Compare commits

...

34 Commits

Author SHA1 Message Date
Florian Preinstorfer
30cec3aa2b Document ports in use
Ref: #1767
2025-08-14 09:24:09 +02:00
Fredrik Ekre
5d8a2c25ea OIDC: Query userinfo endpoint before verifying user
This patch includes some changes to the OIDC integration in particular:
 - Make sure that userinfo claims are queried *before* comparing the
   user with the configured allowed groups, email and email domain.
 - Update user with group claim from the userinfo endpoint which is
   required for allowed groups to work correctly. This is essentially a
   continuation of #2545.
 - Let userinfo claims take precedence over id token claims.

With these changes I have verified that Headscale works as expected
together with Authelia without the documented escape hatch [0], i.e.
everything works even if the id token only contain the iss and sub
claims.

[0]: https://www.authelia.com/integration/openid-connect/headscale/#configuration-escape-hatch
2025-08-11 17:51:16 +02:00
Jeff Emershaw
b4f7782fd8 support force flag for nodes backfillips 2025-08-10 13:31:24 +02:00
eyjhb
d77874373d feat: add robots.txt 2025-08-10 10:57:45 +02:00
Kristoffer Dalby
a058bf3cd3 mapper: produce map before poll (#2628) 2025-07-28 11:15:53 +02:00
Luke Watts
b2a18830ed docs: fix typos 2025-07-28 10:28:49 +02:00
Kristoffer Dalby
9779adc0b7 integration: run headscale with delve and debug symbols (#2689) 2025-07-24 17:44:09 +02:00
nblock
e7fe645be5 Fix invocation of golangci-lint (#2703) 2025-07-24 08:41:20 +02:00
Florian Preinstorfer
bcd80ee773 Add debugging and troubleshooting guide 2025-07-22 14:56:45 +02:00
Florian Preinstorfer
c04e17d82e Document valid log levels
Also change the order as the level seems more important than the format.
2025-07-22 14:56:45 +02:00
Florian Preinstorfer
98fc0563ac Bump version in docs 2025-07-22 14:56:45 +02:00
Kian-Meng Ang
3123d5286b Fix typos
Found via `codespell -L shs,hastable,userr`
2025-07-21 12:06:07 +02:00
Kristoffer Dalby
7fce5065c4 all: remove 32 bit support (#2692) 2025-07-16 13:32:59 +02:00
Florian Preinstorfer
a98d9bd05f The preauthkeys commands expect a user id instead of a username 2025-07-16 09:53:05 +02:00
Florian Preinstorfer
46c59a3fff Fix command in bug report template 2025-07-15 21:12:32 +02:00
Kristoffer Dalby
044193bf34 integration: Use Eventually around external calls (#2685) 2025-07-13 17:37:11 +02:00
Mohammad Javad Naderi
a8f2eebf66 Fix config param name in TLS doc 2025-07-13 12:56:25 +02:00
github-actions[bot]
6220e64978 flake.lock: Update (#2669) 2025-07-13 06:36:04 +00:00
Kristoffer Dalby
c6d7b512bd integration: replace time.Sleep with assert.EventuallyWithT (#2680) 2025-07-10 23:38:55 +02:00
Kristoffer Dalby
b904276f2b poll: use nodeview everywhere
There was a bug in HA subnet router handover where we used stale node data
from the longpoll session that we handed to Connect. This meant that we got
some odd behaviour where routes would not be deactivated correctly.

This commit changes to the nodeview is used through out, and we load the
current node to be updated in the write path and then handle it all there
to be consistent.

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-08 21:05:15 +02:00
Kristoffer Dalby
4a8d2d9ed3 .github/workflows: reduce integration retry to 3
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-08 07:28:35 +01:00
Kristoffer Dalby
22e6094a90 golangci: disable varnamelen
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-07 21:28:59 +01:00
Kristoffer Dalby
73023c2ec3 all: use immutable node view in read path
This commit changes most of our (*)types.Node to
types.NodeView, which is a readonly version of the
underlying node ensuring that there is no mutations
happening in the read path.

Based on the migration, there didnt seem to be any, but the
idea here is to prevent it in the future and simplify other
new implementations.

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-07 21:28:59 +01:00
Kristoffer Dalby
5ba7120418 .github/workflows: prettier
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-07 15:48:38 +01:00
Kristoffer Dalby
d311d2e206 flake: dont override gopls
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-07 15:48:38 +01:00
Kristoffer Dalby
05996a5048 .github/workflow: only run a few selected postgres tests
We are already being punished by github actions, there seem to be
little value in running all the tests for both databases, so only
run a few key tests to check postgres isnt broken.

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-07 15:48:38 +01:00
Kristoffer Dalby
4668e5dd96 changelog: add entry for db
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-07 15:48:38 +01:00
Kristoffer Dalby
c6736dd6d6 db: add sqlite "source of truth" schema
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
2025-07-07 15:48:38 +01:00
Stavros Kois
855c48aec2 remove unneeded check (#2658) 2025-07-04 15:47:01 +00:00
Stavros Kois
ded049b905 don't crash if config file is missing (#2656) 2025-07-04 12:58:17 +00:00
github-actions[bot]
3bad5d5590 flake.lock: Update (#2585)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-07-04 12:00:59 +00:00
Florian Preinstorfer
d461db3abd Refactor OpenID Connect documentation
Restructure and rewrite the OpenID Connect documentation. Start from the
most minimal configuration and describe what needs to be done both in
Headscale and the identity provider. Describe additional features such
as PKCE and authorization filters in a generic manner with examples.

Document how Headscale populates its user profile and how it relates to
OIDC claims. This is a revised version from the table in the changelog.
Document the validation rules for fields and extend known limitations.

Sort the provider specific section alphabetically and add a section for
Authelia, Authentik, Kanidm and Keycloak. Also simplify and rename Azure
to Entra ID.

Update the description for the oidc section in the example
configuration. Give a short explanation of each configuration setting.

All documentend features were tested with Headscale 0.26 (using a fresh
database each time) using the following identity providers:

* Authelia
* Authentik
* Kanidm
* Keycloak

Fixes: #2295
2025-07-04 10:51:37 +02:00
eyJhb
efc6974017 fix typo in parseCapabilityVersion, and removed unused error (#2644) (#2644) 2025-07-04 09:40:29 +02:00
Fredrik Ekre
3f72ee9de8 Clarify SIGHUP log message (#2661) 2025-07-04 09:30:51 +02:00
380 changed files with 14452 additions and 3859 deletions

View File

@@ -17,3 +17,7 @@ LICENSE
.vscode
*.sock
node_modules/
package-lock.json
package.json

View File

@@ -6,14 +6,18 @@ body:
- type: checkboxes
attributes:
label: Is this a support request?
description: This issue tracker is for bugs and feature requests only. If you need help, please use ask in our Discord community
description:
This issue tracker is for bugs and feature requests only. If you need
help, please use ask in our Discord community
options:
- label: This is not a support request
required: true
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
description:
Please search to see if an issue already exists for the bug you
encountered.
options:
- label: I have searched the existing issues
required: true
@@ -73,6 +77,10 @@ body:
attributes:
label: Debug information
description: |
Please have a look at our [Debugging and troubleshooting
guide](https://headscale.net/development/ref/debug/) to learn about
common debugging techniques.
Links? References? Anything that will give us more context about the issue you are encountering.
If **any** of these are omitted we will likely close your issue, do **not** ignore them.
@@ -88,7 +96,7 @@ body:
`tailscale status --json > DESCRIPTIVE_NAME.json`
Get the logs of a Tailscale client that is not working as expected.
`tailscale daemon-logs`
`tailscale debug daemon-logs`
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
**Ensure** you use formatting for files you attach.

View File

@@ -16,13 +16,15 @@ body:
- type: textarea
attributes:
label: Description
description: A clear and precise description of what new or changed feature you want.
description:
A clear and precise description of what new or changed feature you want.
validations:
required: true
- type: checkboxes
attributes:
label: Contribution
description: Are you willing to contribute to the implementation of this feature?
description:
Are you willing to contribute to the implementation of this feature?
options:
- label: I can write the design doc for this feature
required: false
@@ -31,6 +33,7 @@ body:
- type: textarea
attributes:
label: How can it be implemented?
description: Free text for your ideas on how this feature could be implemented.
description:
Free text for your ideas on how this feature could be implemented.
validations:
required: false

View File

@@ -36,7 +36,9 @@ jobs:
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
if: steps.changed-files.outputs.files == 'true'
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Run nix build
@@ -77,11 +79,7 @@ jobs:
strategy:
matrix:
env:
- "GOARCH=arm GOOS=linux GOARM=5"
- "GOARCH=arm GOOS=linux GOARM=6"
- "GOARCH=arm GOOS=linux GOARM=7"
- "GOARCH=arm64 GOOS=linux"
- "GOARCH=386 GOOS=linux"
- "GOARCH=amd64 GOOS=linux"
- "GOARCH=arm64 GOOS=darwin"
- "GOARCH=amd64 GOOS=darwin"
@@ -90,11 +88,15 @@ jobs:
- uses: nixbuild/nix-quick-install-action@889f3180bb5f064ee9e3201428d04ae9e41d54ad # v31
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Run go cross compile
run: env ${{ matrix.env }} nix develop --command -- go build -o "headscale" ./cmd/headscale
run:
env ${{ matrix.env }} nix develop --command -- go build -o "headscale"
./cmd/headscale
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: "headscale-${{ matrix.env }}"

55
.github/workflows/check-generated.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
name: Check Generated Files
on:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
check-generated:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with:
filters: |
files:
- '*.nix'
- 'go.*'
- '**/*.go'
- '**/*.proto'
- 'buf.gen.yaml'
- 'tools/**'
- uses: nixbuild/nix-quick-install-action@889f3180bb5f064ee9e3201428d04ae9e41d54ad # v31
if: steps.changed-files.outputs.files == 'true'
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
if: steps.changed-files.outputs.files == 'true'
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Run make generate
if: steps.changed-files.outputs.files == 'true'
run: nix develop --command -- make generate
- name: Check for uncommitted changes
if: steps.changed-files.outputs.files == 'true'
run: |
if ! git diff --exit-code; then
echo "❌ Generated files are not up to date!"
echo "Please run 'make generate' and commit the changes."
exit 1
else
echo "✅ All generated files are up to date."
fi

View File

@@ -29,7 +29,9 @@ jobs:
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
if: steps.changed-files.outputs.files == 'true'
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Generate and check integration tests

View File

@@ -38,11 +38,12 @@ func findTests() []string {
return tests
}
func updateYAML(tests []string, testPath string) {
func updateYAML(tests []string, jobName string, testPath string) {
testsForYq := fmt.Sprintf("[%s]", strings.Join(tests, ", "))
yqCommand := fmt.Sprintf(
"yq eval '.jobs.integration-test.strategy.matrix.test = %s' %s -i",
"yq eval '.jobs.%s.strategy.matrix.test = %s' %s -i",
jobName,
testsForYq,
testPath,
)
@@ -59,7 +60,7 @@ func updateYAML(tests []string, testPath string) {
log.Fatalf("failed to run yq command: %s", err)
}
fmt.Printf("YAML file (%s) updated successfully\n", testPath)
fmt.Printf("YAML file (%s) job %s updated successfully\n", testPath, jobName)
}
func main() {
@@ -70,5 +71,21 @@ func main() {
quotedTests[i] = fmt.Sprintf("\"%s\"", test)
}
updateYAML(quotedTests, "./test-integration.yaml")
// Define selected tests for PostgreSQL
postgresTestNames := []string{
"TestACLAllowUserDst",
"TestPingAllByIP",
"TestEphemeral2006DeletedTooQuickly",
"TestPingAllByIPManyUpDown",
"TestSubnetRouterMultiNetwork",
}
quotedPostgresTests := make([]string, len(postgresTestNames))
for i, test := range postgresTestNames {
quotedPostgresTests[i] = fmt.Sprintf("\"%s\"", test)
}
// Update both SQLite and PostgreSQL job matrices
updateYAML(quotedTests, "sqlite", "./test-integration.yaml")
updateYAML(quotedPostgresTests, "postgres", "./test-integration.yaml")
}

View File

@@ -0,0 +1,95 @@
name: Integration Test Template
on:
workflow_call:
inputs:
test:
required: true
type: string
postgres_flag:
required: false
type: string
default: ""
database_name:
required: true
type: string
jobs:
test:
runs-on: ubuntu-latest
env:
# Github does not allow us to access secrets in pull requests,
# so this env var is used to check if we have the secret or not.
# If we have the secrets, meaning we are running on push in a fork,
# there might be secrets available for more debugging.
# If TS_OAUTH_CLIENT_ID and TS_OAUTH_SECRET is set, then the job
# will join a debug tailscale network, set up SSH and a tmux session.
# The SSH will be configured to use the SSH key of the Github user
# that triggered the build.
HAS_TAILSCALE_SECRET: ${{ secrets.TS_OAUTH_CLIENT_ID }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with:
filters: |
files:
- '*.nix'
- 'go.*'
- '**/*.go'
- 'integration_test/'
- 'config-example.yaml'
- name: Tailscale
if: ${{ env.HAS_TAILSCALE_SECRET }}
uses: tailscale/github-action@6986d2c82a91fbac2949fe01f5bab95cf21b5102 # v3.2.2
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
tags: tag:gh
- name: Setup SSH server for Actor
if: ${{ env.HAS_TAILSCALE_SECRET }}
uses: alexellis/setup-sshd-actor@master
- uses: nixbuild/nix-quick-install-action@889f3180bb5f064ee9e3201428d04ae9e41d54ad # v31
if: steps.changed-files.outputs.files == 'true'
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
if: steps.changed-files.outputs.files == 'true'
with:
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Run Integration Test
uses: Wandalen/wretry.action@e68c23e6309f2871ca8ae4763e7629b9c258e1ea # v3.8.0
if: steps.changed-files.outputs.files == 'true'
with:
# Our integration tests are started like a thundering herd, often
# hitting limits of the various external repositories we depend on
# like docker hub. This will retry jobs every 5 min, 10 times,
# hopefully letting us avoid manual intervention and restarting jobs.
# One could of course argue that we should invest in trying to avoid
# this, but currently it seems like a larger investment to be cleverer
# about this.
# Some of the jobs might still require manual restart as they are really
# slow and this will cause them to eventually be killed by Github actions.
attempt_delay: 300000 # 5 min
attempt_limit: 2
command: |
nix develop --command -- hi run --stats --ts-memory-limit=300 --hs-memory-limit=500 "^${{ inputs.test }}$" \
--timeout=120m \
${{ inputs.postgres_flag }}
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always() && steps.changed-files.outputs.files == 'true'
with:
name: ${{ inputs.database_name }}-${{ inputs.test }}-logs
path: "control_logs/*/*.log"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always() && steps.changed-files.outputs.files == 'true'
with:
name: ${{ inputs.database_name }}-${{ inputs.test }}-archives
path: "control_logs/*/*.tar"
- name: Setup a blocking tmux session
if: ${{ env.HAS_TAILSCALE_SECRET }}
uses: alexellis/block-with-tmux-action@master

View File

@@ -29,12 +29,19 @@ jobs:
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
if: steps.changed-files.outputs.files == 'true'
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: golangci-lint
if: steps.changed-files.outputs.files == 'true'
run: nix develop --command -- golangci-lint run --new-from-rev=${{github.event.pull_request.base.sha}} --format=colored-line-number
run: nix develop --command -- golangci-lint run
--new-from-rev=${{github.event.pull_request.base.sha}}
--output.text.path=stdout
--output.text.print-linter-name
--output.text.print-issued-lines
--output.text.colors
prettier-lint:
runs-on: ubuntu-latest
@@ -63,12 +70,15 @@ jobs:
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
if: steps.changed-files.outputs.files == 'true'
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Prettify code
if: steps.changed-files.outputs.files == 'true'
run: nix develop --command -- prettier --no-error-on-unmatched-pattern --ignore-unknown --check **/*.{ts,js,md,yaml,yml,sass,css,scss,html}
run: nix develop --command -- prettier --no-error-on-unmatched-pattern
--ignore-unknown --check **/*.{ts,js,md,yaml,yml,sass,css,scss,html}
proto-lint:
runs-on: ubuntu-latest
@@ -77,7 +87,9 @@ jobs:
- uses: nixbuild/nix-quick-install-action@889f3180bb5f064ee9e3201428d04ae9e41d54ad # v31
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Buf lint

View File

@@ -33,7 +33,9 @@ jobs:
- uses: nixbuild/nix-quick-install-action@889f3180bb5f064ee9e3201428d04ae9e41d54ad # v31
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Run goreleaser

View File

@@ -17,8 +17,12 @@ jobs:
days-before-issue-stale: 90
days-before-issue-close: 7
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 90 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
stale-issue-message:
"This issue is stale because it has been open for 90 days with no
activity."
close-issue-message:
"This issue was closed because it has been inactive for 14 days
since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
exempt-issue-labels: "no-stale-bot"

View File

@@ -1,4 +1,4 @@
name: Integration Tests
name: integration
# To debug locally on a branch, and when needing secrets
# change this to include `push` so the build is ran on
# the main repository.
@@ -7,8 +7,7 @@ concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
integration-test:
runs-on: ubuntu-latest
sqlite:
strategy:
fail-fast: false
matrix:
@@ -80,78 +79,23 @@ jobs:
- TestSSHNoSSHConfigured
- TestSSHIsBlockedInACL
- TestSSHUserOnlyIsolation
database: [postgres, sqlite]
env:
# Github does not allow us to access secrets in pull requests,
# so this env var is used to check if we have the secret or not.
# If we have the secrets, meaning we are running on push in a fork,
# there might be secrets available for more debugging.
# If TS_OAUTH_CLIENT_ID and TS_OAUTH_SECRET is set, then the job
# will join a debug tailscale network, set up SSH and a tmux session.
# The SSH will be configured to use the SSH key of the Github user
# that triggered the build.
HAS_TAILSCALE_SECRET: ${{ secrets.TS_OAUTH_CLIENT_ID }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with:
filters: |
files:
- '*.nix'
- 'go.*'
- '**/*.go'
- 'integration_test/'
- 'config-example.yaml'
- name: Tailscale
if: ${{ env.HAS_TAILSCALE_SECRET }}
uses: tailscale/github-action@6986d2c82a91fbac2949fe01f5bab95cf21b5102 # v3.2.2
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
tags: tag:gh
- name: Setup SSH server for Actor
if: ${{ env.HAS_TAILSCALE_SECRET }}
uses: alexellis/setup-sshd-actor@master
- uses: nixbuild/nix-quick-install-action@889f3180bb5f064ee9e3201428d04ae9e41d54ad # v31
if: steps.changed-files.outputs.files == 'true'
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
if: steps.changed-files.outputs.files == 'true'
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Run Integration Test
uses: Wandalen/wretry.action@e68c23e6309f2871ca8ae4763e7629b9c258e1ea # v3.8.0
if: steps.changed-files.outputs.files == 'true'
with:
# Our integration tests are started like a thundering herd, often
# hitting limits of the various external repositories we depend on
# like docker hub. This will retry jobs every 5 min, 10 times,
# hopefully letting us avoid manual intervention and restarting jobs.
# One could of course argue that we should invest in trying to avoid
# this, but currently it seems like a larger investment to be cleverer
# about this.
# Some of the jobs might still require manual restart as they are really
# slow and this will cause them to eventually be killed by Github actions.
attempt_delay: 300000 # 5 min
attempt_limit: 10
command: |
nix develop --command -- hi run "^${{ matrix.test }}$" \
--timeout=120m \
--postgres=${{ matrix.database == 'postgres' && 'true' || 'false' }}
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always() && steps.changed-files.outputs.files == 'true'
with:
name: ${{ matrix.test }}-${{matrix.database}}-logs
path: "control_logs/*/*.log"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always() && steps.changed-files.outputs.files == 'true'
with:
name: ${{ matrix.test }}-${{matrix.database}}-archives
path: "control_logs/*/*.tar"
- name: Setup a blocking tmux session
if: ${{ env.HAS_TAILSCALE_SECRET }}
uses: alexellis/block-with-tmux-action@master
uses: ./.github/workflows/integration-test-template.yml
with:
test: ${{ matrix.test }}
postgres_flag: "--postgres=0"
database_name: "sqlite"
postgres:
strategy:
fail-fast: false
matrix:
test:
- TestACLAllowUserDst
- TestPingAllByIP
- TestEphemeral2006DeletedTooQuickly
- TestPingAllByIPManyUpDown
- TestSubnetRouterMultiNetwork
uses: ./.github/workflows/integration-test-template.yml
with:
test: ${{ matrix.test }}
postgres_flag: "--postgres=1"
database_name: "postgres"

View File

@@ -32,7 +32,9 @@ jobs:
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
if: steps.changed-files.outputs.files == 'true'
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
primary-key:
nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.nix',
'**/flake.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}
- name: Run tests

7
.gitignore vendored
View File

@@ -1,6 +1,9 @@
ignored/
tailscale/
.vscode/
.claude/
*.prof
# Binaries for programs and plugins
*.exe
@@ -46,3 +49,7 @@ integration_test/etc/config.dump.yaml
/site
__debug_bin
node_modules/
package-lock.json
package.json

View File

@@ -24,6 +24,7 @@ linters:
- revive
- tagliatelle
- testpackage
- varnamelen
- wrapcheck
- wsl
settings:

View File

@@ -19,12 +19,8 @@ builds:
- darwin_amd64
- darwin_arm64
- freebsd_amd64
- linux_386
- linux_amd64
- linux_arm64
- linux_arm_5
- linux_arm_6
- linux_arm_7
flags:
- -mod=readonly
ldflags:
@@ -113,9 +109,7 @@ kos:
- CGO_ENABLED=0
platforms:
- linux/amd64
- linux/386
- linux/arm64
- linux/arm/v7
tags:
- "{{ if not .Prerelease }}latest{{ end }}"
- "{{ if not .Prerelease }}{{ .Major }}.{{ .Minor }}.{{ .Patch }}{{ end }}"
@@ -142,9 +136,7 @@ kos:
- CGO_ENABLED=0
platforms:
- linux/amd64
- linux/386
- linux/arm64
- linux/arm/v7
tags:
- "{{ if not .Prerelease }}latest-debug{{ end }}"
- "{{ if not .Prerelease }}{{ .Major }}.{{ .Minor }}.{{ .Patch }}-debug{{ end }}"

View File

@@ -1,4 +1,5 @@
.github/workflows/test-integration-v2*
docs/about/features.md
docs/ref/configuration.md
docs/ref/oidc.md
docs/ref/remote-cli.md

View File

@@ -2,18 +2,77 @@
## Next
**Minimum supported Tailscale client version: v1.64.0**
### Database integrity improvements
This release includes a significant database migration that addresses longstanding
issues with the database schema and data integrity that has accumulated over the
years. The migration introduces a `schema.sql` file as the source of truth for
the expected database schema to ensure new migrations that will cause divergence
does not occur again.
These issues arose from a combination of factors discovered over time: SQLite
foreign keys not being enforced for many early versions, all migrations being
run in one large function until version 0.23.0, and inconsistent use of GORM's
AutoMigrate feature. Moving forward, all new migrations will be explicit SQL
operations rather than relying on GORM AutoMigrate, and foreign keys will be
enforced throughout the migration process.
We are only improving SQLite databases with this change - PostgreSQL databases
are not affected.
Please read the [PR description](https://github.com/juanfont/headscale/pull/2617)
for more technical details about the issues and solutions.
**SQLite Database Backup Example:**
```bash
# Stop headscale
systemctl stop headscale
# Backup sqlite database
cp /var/lib/headscale/db.sqlite /var/lib/headscale/db.sqlite.backup
# Backup sqlite WAL/SHM files (if they exist)
cp /var/lib/headscale/db.sqlite-wal /var/lib/headscale/db.sqlite-wal.backup
cp /var/lib/headscale/db.sqlite-shm /var/lib/headscale/db.sqlite-shm.backup
# Start headscale (migration will run automatically)
systemctl start headscale
```
### BREAKING
- Remove support for 32-bit binaries
[#2692](https://github.com/juanfont/headscale/pull/2692)
- Policy: Zero or empty destination port is no longer allowed
[#2606](https://github.com/juanfont/headscale/pull/2606)
### Changes
- **Database schema migration improvements for SQLite**
[#2617](https://github.com/juanfont/headscale/pull/2617)
- **IMPORTANT: Backup your SQLite database before upgrading**
- Introduces safer table renaming migration strategy
- Addresses longstanding database integrity issues
- Remove policy v1 code [#2600](https://github.com/juanfont/headscale/pull/2600)
- Refactor Debian/Ubuntu packaging and drop support for Ubuntu 20.04.
[#2614](https://github.com/juanfont/headscale/pull/2614)
- Support client verify for DERP
[#2046](https://github.com/juanfont/headscale/pull/2046)
- Remove redundant check regarding `noise` config
[#2658](https://github.com/juanfont/headscale/pull/2658)
- Refactor OpenID Connect documentation
[#2625](https://github.com/juanfont/headscale/pull/2625)
- Don't crash if config file is missing
[#2656](https://github.com/juanfont/headscale/pull/2656)
- Adds `/robots.txt` endpoint to avoid crawlers
[#2643](https://github.com/juanfont/headscale/pull/2643)
- OIDC: Use group claim from UserInfo
[#2663](https://github.com/juanfont/headscale/pull/2663)
- OIDC: Update user with claims from UserInfo *before* comparing with allowed
groups, email and domain [#2663](https://github.com/juanfont/headscale/pull/2663)
## 0.26.1 (2025-06-06)

395
CLAUDE.md Normal file
View File

@@ -0,0 +1,395 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
Headscale is an open-source implementation of the Tailscale control server written in Go. It provides self-hosted coordination for Tailscale networks (tailnets), managing node registration, IP allocation, policy enforcement, and DERP routing.
## Development Commands
### Quick Setup
```bash
# Recommended: Use Nix for dependency management
nix develop
# Full development workflow
make dev # runs fmt + lint + test + build
```
### Essential Commands
```bash
# Build headscale binary
make build
# Run tests
make test
go test ./... # All unit tests
go test -race ./... # With race detection
# Run specific integration test
go run ./cmd/hi run "TestName" --postgres
# Code formatting and linting
make fmt # Format all code (Go, docs, proto)
make lint # Lint all code (Go, proto)
make fmt-go # Format Go code only
make lint-go # Lint Go code only
# Protocol buffer generation (after modifying proto/)
make generate
# Clean build artifacts
make clean
```
### Integration Testing
```bash
# Use the hi (Headscale Integration) test runner
go run ./cmd/hi doctor # Check system requirements
go run ./cmd/hi run "TestPattern" # Run specific test
go run ./cmd/hi run "TestPattern" --postgres # With PostgreSQL backend
# Test artifacts are saved to control_logs/ with logs and debug data
```
## Project Structure & Architecture
### Top-Level Organization
```
headscale/
├── cmd/ # Command-line applications
│ ├── headscale/ # Main headscale server binary
│ └── hi/ # Headscale Integration test runner
├── hscontrol/ # Core control plane logic
├── integration/ # End-to-end Docker-based tests
├── proto/ # Protocol buffer definitions
├── gen/ # Generated code (protobuf)
├── docs/ # Documentation
└── packaging/ # Distribution packaging
```
### Core Packages (`hscontrol/`)
**Main Server (`hscontrol/`)**
- `app.go`: Application setup, dependency injection, server lifecycle
- `handlers.go`: HTTP/gRPC API endpoints for management operations
- `grpcv1.go`: gRPC service implementation for headscale API
- `poll.go`: **Critical** - Handles Tailscale MapRequest/MapResponse protocol
- `noise.go`: Noise protocol implementation for secure client communication
- `auth.go`: Authentication flows (web, OIDC, command-line)
- `oidc.go`: OpenID Connect integration for user authentication
**State Management (`hscontrol/state/`)**
- `state.go`: Central coordinator for all subsystems (database, policy, IP allocation, DERP)
- `node_store.go`: **Performance-critical** - In-memory cache with copy-on-write semantics
- Thread-safe operations with deadlock detection
- Coordinates between database persistence and real-time operations
**Database Layer (`hscontrol/db/`)**
- `db.go`: Database abstraction, GORM setup, migration management
- `node.go`: Node lifecycle, registration, expiration, IP assignment
- `users.go`: User management, namespace isolation
- `api_key.go`: API authentication tokens
- `preauth_keys.go`: Pre-authentication keys for automated node registration
- `ip.go`: IP address allocation and management
- `policy.go`: Policy storage and retrieval
- Schema migrations in `schema.sql` with extensive test data coverage
**Policy Engine (`hscontrol/policy/`)**
- `policy.go`: Core ACL evaluation logic, HuJSON parsing
- `v2/`: Next-generation policy system with improved filtering
- `matcher/`: ACL rule matching and evaluation engine
- Determines peer visibility, route approval, and network access rules
- Supports both file-based and database-stored policies
**Network Management (`hscontrol/`)**
- `derp/`: DERP (Designated Encrypted Relay for Packets) server implementation
- NAT traversal when direct connections fail
- Fallback relay for firewall-restricted environments
- `mapper/`: Converts internal Headscale state to Tailscale's wire protocol format
- `tail.go`: Tailscale-specific data structure generation
- `routes/`: Subnet route management and primary route selection
- `dns/`: DNS record management and MagicDNS implementation
**Utilities & Support (`hscontrol/`)**
- `types/`: Core data structures, configuration, validation
- `util/`: Helper functions for networking, DNS, key management
- `templates/`: Client configuration templates (Apple, Windows, etc.)
- `notifier/`: Event notification system for real-time updates
- `metrics.go`: Prometheus metrics collection
- `capver/`: Tailscale capability version management
### Key Subsystem Interactions
**Node Registration Flow**
1. **Client Connection**: `noise.go` handles secure protocol handshake
2. **Authentication**: `auth.go` validates credentials (web/OIDC/preauth)
3. **State Creation**: `state.go` coordinates IP allocation via `db/ip.go`
4. **Storage**: `db/node.go` persists node, `NodeStore` caches in memory
5. **Network Setup**: `mapper/` generates initial Tailscale network map
**Ongoing Operations**
1. **Poll Requests**: `poll.go` receives periodic client updates
2. **State Updates**: `NodeStore` maintains real-time node information
3. **Policy Application**: `policy/` evaluates ACL rules for peer relationships
4. **Map Distribution**: `mapper/` sends network topology to all affected clients
**Route Management**
1. **Advertisement**: Clients announce routes via `poll.go` Hostinfo updates
2. **Storage**: `db/` persists routes, `NodeStore` caches for performance
3. **Approval**: `policy/` auto-approves routes based on ACL rules
4. **Distribution**: `routes/` selects primary routes, `mapper/` distributes to peers
### Command-Line Tools (`cmd/`)
**Main Server (`cmd/headscale/`)**
- `headscale.go`: CLI parsing, configuration loading, server startup
- Supports daemon mode, CLI operations (user/node management), database operations
**Integration Test Runner (`cmd/hi/`)**
- `main.go`: Test execution framework with Docker orchestration
- `run.go`: Individual test execution with artifact collection
- `doctor.go`: System requirements validation
- `docker.go`: Container lifecycle management
- Essential for validating changes against real Tailscale clients
### Generated & External Code
**Protocol Buffers (`proto/` → `gen/`)**
- Defines gRPC API for headscale management operations
- Client libraries can generate from these definitions
- Run `make generate` after modifying `.proto` files
**Integration Testing (`integration/`)**
- `scenario.go`: Docker test environment setup
- `tailscale.go`: Tailscale client container management
- Individual test files for specific functionality areas
- Real end-to-end validation with network isolation
### Critical Performance Paths
**High-Frequency Operations**
1. **MapRequest Processing** (`poll.go`): Every 15-60 seconds per client
2. **NodeStore Reads** (`node_store.go`): Every operation requiring node data
3. **Policy Evaluation** (`policy/`): On every peer relationship calculation
4. **Route Lookups** (`routes/`): During network map generation
**Database Write Patterns**
- **Frequent**: Node heartbeats, endpoint updates, route changes
- **Moderate**: User operations, policy updates, API key management
- **Rare**: Schema migrations, bulk operations
### Configuration & Deployment
**Configuration** (`hscontrol/types/config.go`)**
- Database connection settings (SQLite/PostgreSQL)
- Network configuration (IP ranges, DNS settings)
- Policy mode (file vs database)
- DERP relay configuration
- OIDC provider settings
**Key Dependencies**
- **GORM**: Database ORM with migration support
- **Tailscale Libraries**: Core networking and protocol code
- **Zerolog**: Structured logging throughout the application
- **Buf**: Protocol buffer toolchain for code generation
### Development Workflow Integration
The architecture supports incremental development:
- **Unit Tests**: Focus on individual packages (`*_test.go` files)
- **Integration Tests**: Validate cross-component interactions
- **Database Tests**: Extensive migration and data integrity validation
- **Policy Tests**: ACL rule evaluation and edge cases
- **Performance Tests**: NodeStore and high-frequency operation validation
## Integration Test System
### Overview
Integration tests use Docker containers running real Tailscale clients against a Headscale server. Tests validate end-to-end functionality including routing, ACLs, node lifecycle, and network coordination.
### Running Integration Tests
**System Requirements**
```bash
# Check if your system is ready
go run ./cmd/hi doctor
```
This verifies Docker, Go, required images, and disk space.
**Test Execution Patterns**
```bash
# Run a single test (recommended for development)
go run ./cmd/hi run "TestSubnetRouterMultiNetwork"
# Run with PostgreSQL backend (for database-heavy tests)
go run ./cmd/hi run "TestExpireNode" --postgres
# Run multiple tests with pattern matching
go run ./cmd/hi run "TestSubnet*"
# Run all integration tests (CI/full validation)
go test ./integration -timeout 30m
```
**Test Categories & Timing**
- **Fast tests** (< 2 min): Basic functionality, CLI operations
- **Medium tests** (2-5 min): Route management, ACL validation
- **Slow tests** (5+ min): Node expiration, HA failover
- **Long-running tests** (10+ min): `TestNodeOnlineStatus` (12 min duration)
### Test Infrastructure
**Docker Setup**
- Headscale server container with configurable database backend
- Multiple Tailscale client containers with different versions
- Isolated networks per test scenario
- Automatic cleanup after test completion
**Test Artifacts**
All test runs save artifacts to `control_logs/TIMESTAMP-ID/`:
```
control_logs/20250713-213106-iajsux/
├── hs-testname-abc123.stderr.log # Headscale server logs
├── hs-testname-abc123.stdout.log
├── hs-testname-abc123.db # Database snapshot
├── hs-testname-abc123_metrics.txt # Prometheus metrics
├── hs-testname-abc123-mapresponses/ # Protocol debug data
├── ts-client-xyz789.stderr.log # Tailscale client logs
├── ts-client-xyz789.stdout.log
└── ts-client-xyz789_status.json # Client status dump
```
### Test Development Guidelines
**Timing Considerations**
Integration tests involve real network operations and Docker container lifecycle:
```go
// ❌ Wrong: Immediate assertions after async operations
client.Execute([]string{"tailscale", "set", "--advertise-routes=10.0.0.0/24"})
nodes, _ := headscale.ListNodes()
require.Len(t, nodes[0].GetAvailableRoutes(), 1) // May fail due to timing
// ✅ Correct: Wait for async operations to complete
client.Execute([]string{"tailscale", "set", "--advertise-routes=10.0.0.0/24"})
require.EventuallyWithT(t, func(c *assert.CollectT) {
nodes, err := headscale.ListNodes()
assert.NoError(c, err)
assert.Len(c, nodes[0].GetAvailableRoutes(), 1)
}, 10*time.Second, 100*time.Millisecond, "route should be advertised")
```
**Common Test Patterns**
- **Route Advertisement**: Use `EventuallyWithT` for route propagation
- **Node State Changes**: Wait for NodeStore synchronization
- **ACL Policy Changes**: Allow time for policy recalculation
- **Network Connectivity**: Use ping tests with retries
**Test Data Management**
```go
// Node identification: Don't assume array ordering
expectedRoutes := map[string]string{"1": "10.33.0.0/16"}
for _, node := range nodes {
nodeIDStr := fmt.Sprintf("%d", node.GetId())
if route, shouldHaveRoute := expectedRoutes[nodeIDStr]; shouldHaveRoute {
// Test the node that should have the route
}
}
```
### Troubleshooting Integration Tests
**Common Failure Patterns**
1. **Timing Issues**: Test assertions run before async operations complete
- **Solution**: Use `EventuallyWithT` with appropriate timeouts
- **Timeout Guidelines**: 3-5s for route operations, 10s for complex scenarios
2. **Infrastructure Problems**: Disk space, Docker issues, network conflicts
- **Check**: `go run ./cmd/hi doctor` for system health
- **Clean**: Remove old test containers and networks
3. **NodeStore Synchronization**: Tests expecting immediate data availability
- **Key Points**: Route advertisements must propagate through poll requests
- **Fix**: Wait for NodeStore updates after Hostinfo changes
4. **Database Backend Differences**: SQLite vs PostgreSQL behavior differences
- **Use**: `--postgres` flag for database-intensive tests
- **Note**: Some timing characteristics differ between backends
**Debugging Failed Tests**
1. **Check test artifacts** in `control_logs/` for detailed logs
2. **Examine MapResponse JSON** files for protocol-level debugging
3. **Review Headscale stderr logs** for server-side error messages
4. **Check Tailscale client status** for network-level issues
**Resource Management**
- Tests require significant disk space (each run ~100MB of logs)
- Docker containers are cleaned up automatically on success
- Failed tests may leave containers running - clean manually if needed
- Use `docker system prune` periodically to reclaim space
### Best Practices for Test Modifications
1. **Always test locally** before committing integration test changes
2. **Use appropriate timeouts** - too short causes flaky tests, too long slows CI
3. **Clean up properly** - ensure tests don't leave persistent state
4. **Handle both success and failure paths** in test scenarios
5. **Document timing requirements** for complex test scenarios
## NodeStore Implementation Details
**Key Insight from Recent Work**: The NodeStore is a critical performance optimization that caches node data in memory while ensuring consistency with the database. When working with route advertisements or node state changes:
1. **Timing Considerations**: Route advertisements need time to propagate from clients to server. Use `require.EventuallyWithT()` patterns in tests instead of immediate assertions.
2. **Synchronization Points**: NodeStore updates happen at specific points like `poll.go:420` after Hostinfo changes. Ensure these are maintained when modifying the polling logic.
3. **Peer Visibility**: The NodeStore's `peersFunc` determines which nodes are visible to each other. Policy-based filtering is separate from monitoring visibility - expired nodes should remain visible for debugging but marked as expired.
## Testing Guidelines
### Integration Test Patterns
```go
// Use EventuallyWithT for async operations
require.EventuallyWithT(t, func(c *assert.CollectT) {
nodes, err := headscale.ListNodes()
assert.NoError(c, err)
// Check expected state
}, 10*time.Second, 100*time.Millisecond, "description")
// Node route checking by actual node properties, not array position
var routeNode *v1.Node
for _, node := range nodes {
if nodeIDStr := fmt.Sprintf("%d", node.GetId()); expectedRoutes[nodeIDStr] != "" {
routeNode = node
break
}
}
```
### Running Problematic Tests
- Some tests require significant time (e.g., `TestNodeOnlineStatus` runs for 12 minutes)
- Infrastructure issues like disk space can cause test failures unrelated to code changes
- Use `--postgres` flag when testing database-heavy scenarios
## Important Notes
- **Dependencies**: Use `nix develop` for consistent toolchain (Go, buf, protobuf tools, linting)
- **Protocol Buffers**: Changes to `proto/` require `make generate` and should be committed separately
- **Code Style**: Enforced via golangci-lint with golines (width 88) and gofumpt formatting
- **Database**: Supports both SQLite (development) and PostgreSQL (production/testing)
- **Integration Tests**: Require Docker and can consume significant disk space
- **Performance**: NodeStore optimizations are critical for scale - be careful with changes to state management
## Debugging Integration Tests
Test artifacts are preserved in `control_logs/TIMESTAMP-ID/` including:
- Headscale server logs (stderr/stdout)
- Tailscale client logs and status
- Database dumps and network captures
- MapResponse JSON files for protocol debugging
When tests fail, check these artifacts first before assuming code issues.

View File

@@ -13,14 +13,18 @@ RUN apt-get update \
&& apt-get clean
RUN mkdir -p /var/run/headscale
# Install delve debugger
RUN go install github.com/go-delve/delve/cmd/dlv@latest
COPY go.mod go.sum /go/src/headscale/
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go install -a ./cmd/headscale && test -e /go/bin/headscale
# Build debug binary with debug symbols for delve
RUN CGO_ENABLED=0 GOOS=linux go build -gcflags="all=-N -l" -o /go/bin/headscale ./cmd/headscale
# Need to reset the entrypoint or everything will run as a busybox script
ENTRYPOINT []
EXPOSE 8080/tcp
CMD ["headscale"]
EXPOSE 8080/tcp 40000/tcp
CMD ["/go/bin/dlv", "--listen=0.0.0.0:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/go/bin/headscale", "--"]

View File

@@ -87,10 +87,9 @@ lint-proto: check-deps $(PROTO_SOURCES)
# Code generation
.PHONY: generate
generate: check-deps $(PROTO_SOURCES)
@echo "Generating code from Protocol Buffers..."
rm -rf gen
buf generate proto
generate: check-deps
@echo "Generating code..."
go generate ./...
# Clean targets
.PHONY: clean

View File

@@ -117,7 +117,7 @@ var createNodeCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf("Cannot create node: %s", status.Convert(err).Message()),
"Cannot create node: "+status.Convert(err).Message(),
output,
)
}

View File

@@ -2,6 +2,7 @@ package cli
import (
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
@@ -68,7 +69,7 @@ func mockOIDC() error {
userStr := os.Getenv("MOCKOIDC_USERS")
if userStr == "" {
return fmt.Errorf("MOCKOIDC_USERS not defined")
return errors.New("MOCKOIDC_USERS not defined")
}
var users []mockoidc.MockUser

View File

@@ -184,7 +184,7 @@ var listNodesCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()),
"Cannot get nodes: "+status.Convert(err).Message(),
output,
)
}
@@ -398,10 +398,7 @@ var deleteNodeCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf(
"Error getting node node: %s",
status.Convert(err).Message(),
),
"Error getting node node: "+status.Convert(err).Message(),
output,
)
@@ -437,10 +434,7 @@ var deleteNodeCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf(
"Error deleting node: %s",
status.Convert(err).Message(),
),
"Error deleting node: "+status.Convert(err).Message(),
output,
)
@@ -498,10 +492,7 @@ var moveNodeCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf(
"Error getting node: %s",
status.Convert(err).Message(),
),
"Error getting node: "+status.Convert(err).Message(),
output,
)
@@ -517,10 +508,7 @@ var moveNodeCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf(
"Error moving node: %s",
status.Convert(err).Message(),
),
"Error moving node: "+status.Convert(err).Message(),
output,
)
@@ -551,26 +539,29 @@ be assigned to nodes.`,
output, _ := cmd.Flags().GetString("output")
confirm := false
prompt := &survey.Confirm{
Message: "Are you sure that you want to assign/remove IPs to/from nodes?",
force, _ := cmd.Flags().GetBool("force")
if !force {
prompt := &survey.Confirm{
Message: "Are you sure that you want to assign/remove IPs to/from nodes?",
}
err = survey.AskOne(prompt, &confirm)
if err != nil {
return
}
}
err = survey.AskOne(prompt, &confirm)
if err != nil {
return
}
if confirm {
if confirm || force {
ctx, client, conn, cancel := newHeadscaleCLIWithConfig()
defer cancel()
defer conn.Close()
changes, err := client.BackfillNodeIPs(ctx, &v1.BackfillNodeIPsRequest{Confirmed: confirm})
changes, err := client.BackfillNodeIPs(ctx, &v1.BackfillNodeIPsRequest{Confirmed: confirm || force })
if err != nil {
ErrorOutput(
err,
fmt.Sprintf(
"Error backfilling IPs: %s",
status.Convert(err).Message(),
),
"Error backfilling IPs: "+status.Convert(err).Message(),
output,
)

View File

@@ -7,8 +7,10 @@ import (
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/juanfont/headscale/hscontrol/policy"
"github.com/juanfont/headscale/hscontrol/types"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"tailscale.com/types/views"
)
func init() {
@@ -111,7 +113,7 @@ var checkPolicy = &cobra.Command{
ErrorOutput(err, fmt.Sprintf("Error reading the policy file: %s", err), output)
}
_, err = policy.NewPolicyManager(policyBytes, nil, nil)
_, err = policy.NewPolicyManager(policyBytes, nil, views.Slice[types.NodeView]{})
if err != nil {
ErrorOutput(err, fmt.Sprintf("Error parsing the policy file: %s", err), output)
}

View File

@@ -2,10 +2,12 @@ package cli
import (
"errors"
"fmt"
"net/http"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/tailscale/squibble"
)
func init() {
@@ -21,6 +23,12 @@ var serveCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
app, err := newHeadscaleServerWithConfig()
if err != nil {
var squibbleErr squibble.ValidationError
if errors.As(err, &squibbleErr) {
fmt.Printf("SQLite schema failed to validate:\n")
fmt.Println(squibbleErr.Diff)
}
log.Fatal().Caller().Err(err).Msg("Error initializing")
}

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net/url"
"strconv"
survey "github.com/AlecAivazis/survey/v2"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
@@ -27,10 +28,7 @@ func usernameAndIDFromFlag(cmd *cobra.Command) (uint64, string) {
err := errors.New("--name or --identifier flag is required")
ErrorOutput(
err,
fmt.Sprintf(
"Cannot rename user: %s",
status.Convert(err).Message(),
),
"Cannot rename user: "+status.Convert(err).Message(),
"",
)
}
@@ -114,10 +112,7 @@ var createUserCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf(
"Cannot create user: %s",
status.Convert(err).Message(),
),
"Cannot create user: "+status.Convert(err).Message(),
output,
)
}
@@ -147,16 +142,16 @@ var destroyUserCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf("Error: %s", status.Convert(err).Message()),
"Error: "+status.Convert(err).Message(),
output,
)
}
if len(users.GetUsers()) != 1 {
err := fmt.Errorf("Unable to determine user to delete, query returned multiple users, use ID")
err := errors.New("Unable to determine user to delete, query returned multiple users, use ID")
ErrorOutput(
err,
fmt.Sprintf("Error: %s", status.Convert(err).Message()),
"Error: "+status.Convert(err).Message(),
output,
)
}
@@ -185,10 +180,7 @@ var destroyUserCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf(
"Cannot destroy user: %s",
status.Convert(err).Message(),
),
"Cannot destroy user: "+status.Convert(err).Message(),
output,
)
}
@@ -220,20 +212,17 @@ var listUsersCmd = &cobra.Command{
switch {
case id > 0:
request.Id = uint64(id)
break
case username != "":
request.Name = username
break
case email != "":
request.Email = email
break
}
response, err := client.ListUsers(ctx, request)
if err != nil {
ErrorOutput(
err,
fmt.Sprintf("Cannot get users: %s", status.Convert(err).Message()),
"Cannot get users: "+status.Convert(err).Message(),
output,
)
}
@@ -247,7 +236,7 @@ var listUsersCmd = &cobra.Command{
tableData = append(
tableData,
[]string{
fmt.Sprintf("%d", user.GetId()),
strconv.FormatUint(user.GetId(), 10),
user.GetDisplayName(),
user.GetName(),
user.GetEmail(),
@@ -287,16 +276,16 @@ var renameUserCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf("Error: %s", status.Convert(err).Message()),
"Error: "+status.Convert(err).Message(),
output,
)
}
if len(users.GetUsers()) != 1 {
err := fmt.Errorf("Unable to determine user to delete, query returned multiple users, use ID")
err := errors.New("Unable to determine user to delete, query returned multiple users, use ID")
ErrorOutput(
err,
fmt.Sprintf("Error: %s", status.Convert(err).Message()),
"Error: "+status.Convert(err).Message(),
output,
)
}
@@ -312,10 +301,7 @@ var renameUserCmd = &cobra.Command{
if err != nil {
ErrorOutput(
err,
fmt.Sprintf(
"Cannot rename user: %s",
status.Convert(err).Message(),
),
"Cannot rename user: "+status.Convert(err).Message(),
output,
)
}

View File

@@ -66,7 +66,7 @@ func killTestContainers(ctx context.Context) error {
if cont.State == "running" {
_ = cli.ContainerKill(ctx, cont.ID, "KILL")
}
// Then remove the container with retry logic
if removeContainerWithRetry(ctx, cli, cont.ID) {
removed++
@@ -87,25 +87,25 @@ func killTestContainers(ctx context.Context) error {
func removeContainerWithRetry(ctx context.Context, cli *client.Client, containerID string) bool {
maxRetries := 3
baseDelay := 100 * time.Millisecond
for attempt := 0; attempt < maxRetries; attempt++ {
for attempt := range maxRetries {
err := cli.ContainerRemove(ctx, containerID, container.RemoveOptions{
Force: true,
})
if err == nil {
return true
}
// If this is the last attempt, don't wait
if attempt == maxRetries-1 {
break
}
// Wait with exponential backoff
delay := baseDelay * time.Duration(1<<attempt)
time.Sleep(delay)
}
return false
}

View File

@@ -90,6 +90,32 @@ func runTestContainer(ctx context.Context, config *RunConfig) error {
log.Printf("Starting test: %s", config.TestPattern)
// Start stats collection for container resource monitoring (if enabled)
var statsCollector *StatsCollector
if config.Stats {
var err error
statsCollector, err = NewStatsCollector()
if err != nil {
if config.Verbose {
log.Printf("Warning: failed to create stats collector: %v", err)
}
statsCollector = nil
}
if statsCollector != nil {
defer statsCollector.Close()
// Start stats collection immediately - no need for complex retry logic
// The new implementation monitors Docker events and will catch containers as they start
if err := statsCollector.StartCollection(ctx, runID, config.Verbose); err != nil {
if config.Verbose {
log.Printf("Warning: failed to start stats collection: %v", err)
}
}
defer statsCollector.StopCollection()
}
}
exitCode, err := streamAndWait(ctx, cli, resp.ID)
// Ensure all containers have finished and logs are flushed before extracting artifacts
@@ -105,6 +131,20 @@ func runTestContainer(ctx context.Context, config *RunConfig) error {
// Always list control files regardless of test outcome
listControlFiles(logsDir)
// Print stats summary and check memory limits if enabled
if config.Stats && statsCollector != nil {
violations := statsCollector.PrintSummaryAndCheckLimits(config.HSMemoryLimit, config.TSMemoryLimit)
if len(violations) > 0 {
log.Printf("MEMORY LIMIT VIOLATIONS DETECTED:")
log.Printf("=================================")
for _, violation := range violations {
log.Printf("Container %s exceeded memory limit: %.1f MB > %.1f MB",
violation.ContainerName, violation.MaxMemoryMB, violation.LimitMB)
}
return fmt.Errorf("test failed: %d container(s) exceeded memory limits", len(violations))
}
}
shouldCleanup := config.CleanAfter && (!config.KeepOnFailure || exitCode == 0)
if shouldCleanup {
if config.Verbose {
@@ -156,10 +196,10 @@ func createGoTestContainer(ctx context.Context, cli *client.Client, config *RunC
projectRoot := findProjectRoot(pwd)
runID := dockertestutil.ExtractRunIDFromContainerName(containerName)
env := []string{
fmt.Sprintf("HEADSCALE_INTEGRATION_POSTGRES=%d", boolToInt(config.UsePostgres)),
fmt.Sprintf("HEADSCALE_INTEGRATION_RUN_ID=%s", runID),
"HEADSCALE_INTEGRATION_RUN_ID=" + runID,
}
containerConfig := &container.Config{
Image: "golang:" + config.GoVersion,
@@ -175,7 +215,7 @@ func createGoTestContainer(ctx context.Context, cli *client.Client, config *RunC
// Get the correct Docker socket path from the current context
dockerSocketPath := getDockerSocketPath()
if config.Verbose {
log.Printf("Using Docker socket: %s", dockerSocketPath)
}
@@ -184,7 +224,7 @@ func createGoTestContainer(ctx context.Context, cli *client.Client, config *RunC
AutoRemove: false, // We'll remove manually for better control
Binds: []string{
fmt.Sprintf("%s:%s", projectRoot, projectRoot),
fmt.Sprintf("%s:/var/run/docker.sock", dockerSocketPath),
dockerSocketPath + ":/var/run/docker.sock",
logsDir + ":/tmp/control",
},
Mounts: []mount.Mount{
@@ -237,7 +277,7 @@ func waitForContainerFinalization(ctx context.Context, cli *client.Client, testC
}
testContainers := getCurrentTestContainers(containers, testContainerID, verbose)
// Wait for all test containers to reach a final state
maxWaitTime := 10 * time.Second
checkInterval := 500 * time.Millisecond
@@ -254,7 +294,7 @@ func waitForContainerFinalization(ctx context.Context, cli *client.Client, testC
return nil
case <-ticker.C:
allFinalized := true
for _, testCont := range testContainers {
inspect, err := cli.ContainerInspect(ctx, testCont.ID)
if err != nil {
@@ -263,17 +303,18 @@ func waitForContainerFinalization(ctx context.Context, cli *client.Client, testC
}
continue
}
// Check if container is in a final state
if !isContainerFinalized(inspect.State) {
allFinalized = false
if verbose {
log.Printf("Container %s still finalizing (state: %s)", testCont.name, inspect.State.Status)
}
break
}
}
if allFinalized {
if verbose {
log.Printf("All test containers finalized, ready for artifact extraction")
@@ -290,7 +331,6 @@ func isContainerFinalized(state *container.State) bool {
return !state.Running && state.FinishedAt != ""
}
// findProjectRoot locates the project root by finding the directory containing go.mod.
func findProjectRoot(startPath string) string {
current := startPath
@@ -379,10 +419,37 @@ func getDockerSocketPath() string {
return "/var/run/docker.sock"
}
// ensureImageAvailable pulls the specified Docker image to ensure it's available.
// checkImageAvailableLocally checks if the specified Docker image is available locally.
func checkImageAvailableLocally(ctx context.Context, cli *client.Client, imageName string) (bool, error) {
_, _, err := cli.ImageInspectWithRaw(ctx, imageName)
if err != nil {
if client.IsErrNotFound(err) {
return false, nil
}
return false, fmt.Errorf("failed to inspect image %s: %w", imageName, err)
}
return true, nil
}
// ensureImageAvailable checks if the image is available locally first, then pulls if needed.
func ensureImageAvailable(ctx context.Context, cli *client.Client, imageName string, verbose bool) error {
// First check if image is available locally
available, err := checkImageAvailableLocally(ctx, cli, imageName)
if err != nil {
return fmt.Errorf("failed to check local image availability: %w", err)
}
if available {
if verbose {
log.Printf("Image %s is available locally", imageName)
}
return nil
}
// Image not available locally, try to pull it
if verbose {
log.Printf("Pulling image %s...", imageName)
log.Printf("Image %s not found locally, pulling...", imageName)
}
reader, err := cli.ImagePull(ctx, imageName, image.PullOptions{})
@@ -427,7 +494,7 @@ func listControlFiles(logsDir string) {
}
if entry.IsDir() {
// Include directories (pprof, mapresponses)
// Include directories (pprof, mapresponses)
if strings.Contains(name, "-pprof") || strings.Contains(name, "-mapresponses") {
dataDirs = append(dataDirs, name)
}
@@ -510,7 +577,7 @@ type testContainer struct {
// getCurrentTestContainers filters containers to only include those from the current test run.
func getCurrentTestContainers(containers []container.Summary, testContainerID string, verbose bool) []testContainer {
var testRunContainers []testContainer
// Find the test container to get its run ID label
var runID string
for _, cont := range containers {
@@ -521,16 +588,16 @@ func getCurrentTestContainers(containers []container.Summary, testContainerID st
break
}
}
if runID == "" {
log.Printf("Error: test container %s missing required hi.run-id label", testContainerID[:12])
return testRunContainers
}
if verbose {
log.Printf("Looking for containers with run ID: %s", runID)
}
// Find all containers with the same run ID
for _, cont := range containers {
for _, name := range cont.Names {
@@ -546,18 +613,19 @@ func getCurrentTestContainers(containers []container.Summary, testContainerID st
log.Printf("Including container %s (run ID: %s)", containerName, runID)
}
}
break
}
}
}
return testRunContainers
}
// extractContainerArtifacts saves logs and tar files from a container.
func extractContainerArtifacts(ctx context.Context, cli *client.Client, containerID, containerName, logsDir string, verbose bool) error {
// Ensure the logs directory exists
if err := os.MkdirAll(logsDir, 0755); err != nil {
if err := os.MkdirAll(logsDir, 0o755); err != nil {
return fmt.Errorf("failed to create logs directory: %w", err)
}
@@ -608,12 +676,12 @@ func extractContainerLogs(ctx context.Context, cli *client.Client, containerID,
}
// Write stdout logs
if err := os.WriteFile(stdoutPath, stdoutBuf.Bytes(), 0644); err != nil {
if err := os.WriteFile(stdoutPath, stdoutBuf.Bytes(), 0o644); err != nil {
return fmt.Errorf("failed to write stdout log: %w", err)
}
// Write stderr logs
if err := os.WriteFile(stderrPath, stderrBuf.Bytes(), 0644); err != nil {
if err := os.WriteFile(stderrPath, stderrBuf.Bytes(), 0o644); err != nil {
return fmt.Errorf("failed to write stderr log: %w", err)
}
@@ -626,7 +694,7 @@ func extractContainerLogs(ctx context.Context, cli *client.Client, containerID,
// extractContainerFiles extracts database file and directories from headscale containers.
// Note: The actual file extraction is now handled by the integration tests themselves
// via SaveProfile, SaveMapResponses, and SaveDatabase functions in hsic.go
// via SaveProfile, SaveMapResponses, and SaveDatabase functions in hsic.go.
func extractContainerFiles(ctx context.Context, cli *client.Client, containerID, containerName, logsDir string, verbose bool) error {
// Files are now extracted directly by the integration tests
// This function is kept for potential future use or other file types
@@ -677,7 +745,7 @@ func extractDirectory(ctx context.Context, cli *client.Client, containerID, sour
// Create target directory
targetDir := filepath.Join(logsDir, dirName)
if err := os.MkdirAll(targetDir, 0755); err != nil {
if err := os.MkdirAll(targetDir, 0o755); err != nil {
return fmt.Errorf("failed to create directory %s: %w", targetDir, err)
}

View File

@@ -190,7 +190,7 @@ func checkDockerSocket(ctx context.Context) DoctorResult {
}
}
// checkGolangImage verifies we can access the golang Docker image.
// checkGolangImage verifies the golang Docker image is available locally or can be pulled.
func checkGolangImage(ctx context.Context) DoctorResult {
cli, err := createDockerClient()
if err != nil {
@@ -205,17 +205,40 @@ func checkGolangImage(ctx context.Context) DoctorResult {
goVersion := detectGoVersion()
imageName := "golang:" + goVersion
// Check if we can pull the image
// First check if image is available locally
available, err := checkImageAvailableLocally(ctx, cli, imageName)
if err != nil {
return DoctorResult{
Name: "Golang Image",
Status: "FAIL",
Message: fmt.Sprintf("Cannot check golang image %s: %v", imageName, err),
Suggestions: []string{
"Check Docker daemon status",
"Try: docker images | grep golang",
},
}
}
if available {
return DoctorResult{
Name: "Golang Image",
Status: "PASS",
Message: fmt.Sprintf("Golang image %s is available locally", imageName),
}
}
// Image not available locally, try to pull it
err = ensureImageAvailable(ctx, cli, imageName, false)
if err != nil {
return DoctorResult{
Name: "Golang Image",
Status: "FAIL",
Message: fmt.Sprintf("Cannot pull golang image %s: %v", imageName, err),
Message: fmt.Sprintf("Golang image %s not available locally and cannot pull: %v", imageName, err),
Suggestions: []string{
"Check internet connectivity",
"Verify Docker Hub access",
"Try: docker pull " + imageName,
"Or run tests offline if image was pulled previously",
},
}
}
@@ -223,7 +246,7 @@ func checkGolangImage(ctx context.Context) DoctorResult {
return DoctorResult{
Name: "Golang Image",
Status: "PASS",
Message: fmt.Sprintf("Golang image %s is available", imageName),
Message: fmt.Sprintf("Golang image %s is now available", imageName),
}
}

View File

@@ -24,6 +24,9 @@ type RunConfig struct {
KeepOnFailure bool `flag:"keep-on-failure,default=false,Keep containers on test failure"`
LogsDir string `flag:"logs-dir,default=control_logs,Control logs directory"`
Verbose bool `flag:"verbose,default=false,Verbose output"`
Stats bool `flag:"stats,default=false,Collect and display container resource usage statistics"`
HSMemoryLimit float64 `flag:"hs-memory-limit,default=0,Fail test if any Headscale container exceeds this memory limit in MB (0 = disabled)"`
TSMemoryLimit float64 `flag:"ts-memory-limit,default=0,Fail test if any Tailscale container exceeds this memory limit in MB (0 = disabled)"`
}
// runIntegrationTest executes the integration test workflow.

468
cmd/hi/stats.go Normal file
View File

@@ -0,0 +1,468 @@
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"sort"
"strings"
"sync"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
)
// ContainerStats represents statistics for a single container
type ContainerStats struct {
ContainerID string
ContainerName string
Stats []StatsSample
mutex sync.RWMutex
}
// StatsSample represents a single stats measurement
type StatsSample struct {
Timestamp time.Time
CPUUsage float64 // CPU usage percentage
MemoryMB float64 // Memory usage in MB
}
// StatsCollector manages collection of container statistics
type StatsCollector struct {
client *client.Client
containers map[string]*ContainerStats
stopChan chan struct{}
wg sync.WaitGroup
mutex sync.RWMutex
collectionStarted bool
}
// NewStatsCollector creates a new stats collector instance
func NewStatsCollector() (*StatsCollector, error) {
cli, err := createDockerClient()
if err != nil {
return nil, fmt.Errorf("failed to create Docker client: %w", err)
}
return &StatsCollector{
client: cli,
containers: make(map[string]*ContainerStats),
stopChan: make(chan struct{}),
}, nil
}
// StartCollection begins monitoring all containers and collecting stats for hs- and ts- containers with matching run ID
func (sc *StatsCollector) StartCollection(ctx context.Context, runID string, verbose bool) error {
sc.mutex.Lock()
defer sc.mutex.Unlock()
if sc.collectionStarted {
return fmt.Errorf("stats collection already started")
}
sc.collectionStarted = true
// Start monitoring existing containers
sc.wg.Add(1)
go sc.monitorExistingContainers(ctx, runID, verbose)
// Start Docker events monitoring for new containers
sc.wg.Add(1)
go sc.monitorDockerEvents(ctx, runID, verbose)
if verbose {
log.Printf("Started container monitoring for run ID %s", runID)
}
return nil
}
// StopCollection stops all stats collection
func (sc *StatsCollector) StopCollection() {
// Check if already stopped without holding lock
sc.mutex.RLock()
if !sc.collectionStarted {
sc.mutex.RUnlock()
return
}
sc.mutex.RUnlock()
// Signal stop to all goroutines
close(sc.stopChan)
// Wait for all goroutines to finish
sc.wg.Wait()
// Mark as stopped
sc.mutex.Lock()
sc.collectionStarted = false
sc.mutex.Unlock()
}
// monitorExistingContainers checks for existing containers that match our criteria
func (sc *StatsCollector) monitorExistingContainers(ctx context.Context, runID string, verbose bool) {
defer sc.wg.Done()
containers, err := sc.client.ContainerList(ctx, container.ListOptions{})
if err != nil {
if verbose {
log.Printf("Failed to list existing containers: %v", err)
}
return
}
for _, cont := range containers {
if sc.shouldMonitorContainer(cont, runID) {
sc.startStatsForContainer(ctx, cont.ID, cont.Names[0], verbose)
}
}
}
// monitorDockerEvents listens for container start events and begins monitoring relevant containers
func (sc *StatsCollector) monitorDockerEvents(ctx context.Context, runID string, verbose bool) {
defer sc.wg.Done()
filter := filters.NewArgs()
filter.Add("type", "container")
filter.Add("event", "start")
eventOptions := events.ListOptions{
Filters: filter,
}
events, errs := sc.client.Events(ctx, eventOptions)
for {
select {
case <-sc.stopChan:
return
case <-ctx.Done():
return
case event := <-events:
if event.Type == "container" && event.Action == "start" {
// Get container details
containerInfo, err := sc.client.ContainerInspect(ctx, event.ID)
if err != nil {
continue
}
// Convert to types.Container format for consistency
cont := types.Container{
ID: containerInfo.ID,
Names: []string{containerInfo.Name},
Labels: containerInfo.Config.Labels,
}
if sc.shouldMonitorContainer(cont, runID) {
sc.startStatsForContainer(ctx, cont.ID, cont.Names[0], verbose)
}
}
case err := <-errs:
if verbose {
log.Printf("Error in Docker events stream: %v", err)
}
return
}
}
}
// shouldMonitorContainer determines if a container should be monitored
func (sc *StatsCollector) shouldMonitorContainer(cont types.Container, runID string) bool {
// Check if it has the correct run ID label
if cont.Labels == nil || cont.Labels["hi.run-id"] != runID {
return false
}
// Check if it's an hs- or ts- container
for _, name := range cont.Names {
containerName := strings.TrimPrefix(name, "/")
if strings.HasPrefix(containerName, "hs-") || strings.HasPrefix(containerName, "ts-") {
return true
}
}
return false
}
// startStatsForContainer begins stats collection for a specific container
func (sc *StatsCollector) startStatsForContainer(ctx context.Context, containerID, containerName string, verbose bool) {
containerName = strings.TrimPrefix(containerName, "/")
sc.mutex.Lock()
// Check if we're already monitoring this container
if _, exists := sc.containers[containerID]; exists {
sc.mutex.Unlock()
return
}
sc.containers[containerID] = &ContainerStats{
ContainerID: containerID,
ContainerName: containerName,
Stats: make([]StatsSample, 0),
}
sc.mutex.Unlock()
if verbose {
log.Printf("Starting stats collection for container %s (%s)", containerName, containerID[:12])
}
sc.wg.Add(1)
go sc.collectStatsForContainer(ctx, containerID, verbose)
}
// collectStatsForContainer collects stats for a specific container using Docker API streaming
func (sc *StatsCollector) collectStatsForContainer(ctx context.Context, containerID string, verbose bool) {
defer sc.wg.Done()
// Use Docker API streaming stats - much more efficient than CLI
statsResponse, err := sc.client.ContainerStats(ctx, containerID, true)
if err != nil {
if verbose {
log.Printf("Failed to get stats stream for container %s: %v", containerID[:12], err)
}
return
}
defer statsResponse.Body.Close()
decoder := json.NewDecoder(statsResponse.Body)
var prevStats *container.Stats
for {
select {
case <-sc.stopChan:
return
case <-ctx.Done():
return
default:
var stats container.Stats
if err := decoder.Decode(&stats); err != nil {
// EOF is expected when container stops or stream ends
if err.Error() != "EOF" && verbose {
log.Printf("Failed to decode stats for container %s: %v", containerID[:12], err)
}
return
}
// Calculate CPU percentage (only if we have previous stats)
var cpuPercent float64
if prevStats != nil {
cpuPercent = calculateCPUPercent(prevStats, &stats)
}
// Calculate memory usage in MB
memoryMB := float64(stats.MemoryStats.Usage) / (1024 * 1024)
// Store the sample (skip first sample since CPU calculation needs previous stats)
if prevStats != nil {
// Get container stats reference without holding the main mutex
var containerStats *ContainerStats
var exists bool
sc.mutex.RLock()
containerStats, exists = sc.containers[containerID]
sc.mutex.RUnlock()
if exists && containerStats != nil {
containerStats.mutex.Lock()
containerStats.Stats = append(containerStats.Stats, StatsSample{
Timestamp: time.Now(),
CPUUsage: cpuPercent,
MemoryMB: memoryMB,
})
containerStats.mutex.Unlock()
}
}
// Save current stats for next iteration
prevStats = &stats
}
}
}
// calculateCPUPercent calculates CPU usage percentage from Docker stats
func calculateCPUPercent(prevStats, stats *container.Stats) float64 {
// CPU calculation based on Docker's implementation
cpuDelta := float64(stats.CPUStats.CPUUsage.TotalUsage) - float64(prevStats.CPUStats.CPUUsage.TotalUsage)
systemDelta := float64(stats.CPUStats.SystemUsage) - float64(prevStats.CPUStats.SystemUsage)
if systemDelta > 0 && cpuDelta >= 0 {
// Calculate CPU percentage: (container CPU delta / system CPU delta) * number of CPUs * 100
numCPUs := float64(len(stats.CPUStats.CPUUsage.PercpuUsage))
if numCPUs == 0 {
// Fallback: if PercpuUsage is not available, assume 1 CPU
numCPUs = 1.0
}
return (cpuDelta / systemDelta) * numCPUs * 100.0
}
return 0.0
}
// ContainerStatsSummary represents summary statistics for a container
type ContainerStatsSummary struct {
ContainerName string
SampleCount int
CPU StatsSummary
Memory StatsSummary
}
// MemoryViolation represents a container that exceeded the memory limit
type MemoryViolation struct {
ContainerName string
MaxMemoryMB float64
LimitMB float64
}
// StatsSummary represents min, max, and average for a metric
type StatsSummary struct {
Min float64
Max float64
Average float64
}
// GetSummary returns a summary of collected statistics
func (sc *StatsCollector) GetSummary() []ContainerStatsSummary {
// Take snapshot of container references without holding main lock long
sc.mutex.RLock()
containerRefs := make([]*ContainerStats, 0, len(sc.containers))
for _, containerStats := range sc.containers {
containerRefs = append(containerRefs, containerStats)
}
sc.mutex.RUnlock()
summaries := make([]ContainerStatsSummary, 0, len(containerRefs))
for _, containerStats := range containerRefs {
containerStats.mutex.RLock()
stats := make([]StatsSample, len(containerStats.Stats))
copy(stats, containerStats.Stats)
containerName := containerStats.ContainerName
containerStats.mutex.RUnlock()
if len(stats) == 0 {
continue
}
summary := ContainerStatsSummary{
ContainerName: containerName,
SampleCount: len(stats),
}
// Calculate CPU stats
cpuValues := make([]float64, len(stats))
memoryValues := make([]float64, len(stats))
for i, sample := range stats {
cpuValues[i] = sample.CPUUsage
memoryValues[i] = sample.MemoryMB
}
summary.CPU = calculateStatsSummary(cpuValues)
summary.Memory = calculateStatsSummary(memoryValues)
summaries = append(summaries, summary)
}
// Sort by container name for consistent output
sort.Slice(summaries, func(i, j int) bool {
return summaries[i].ContainerName < summaries[j].ContainerName
})
return summaries
}
// calculateStatsSummary calculates min, max, and average for a slice of values
func calculateStatsSummary(values []float64) StatsSummary {
if len(values) == 0 {
return StatsSummary{}
}
min := values[0]
max := values[0]
sum := 0.0
for _, value := range values {
if value < min {
min = value
}
if value > max {
max = value
}
sum += value
}
return StatsSummary{
Min: min,
Max: max,
Average: sum / float64(len(values)),
}
}
// PrintSummary prints the statistics summary to the console
func (sc *StatsCollector) PrintSummary() {
summaries := sc.GetSummary()
if len(summaries) == 0 {
log.Printf("No container statistics collected")
return
}
log.Printf("Container Resource Usage Summary:")
log.Printf("================================")
for _, summary := range summaries {
log.Printf("Container: %s (%d samples)", summary.ContainerName, summary.SampleCount)
log.Printf(" CPU Usage: Min: %6.2f%% Max: %6.2f%% Avg: %6.2f%%",
summary.CPU.Min, summary.CPU.Max, summary.CPU.Average)
log.Printf(" Memory Usage: Min: %6.1f MB Max: %6.1f MB Avg: %6.1f MB",
summary.Memory.Min, summary.Memory.Max, summary.Memory.Average)
log.Printf("")
}
}
// CheckMemoryLimits checks if any containers exceeded their memory limits
func (sc *StatsCollector) CheckMemoryLimits(hsLimitMB, tsLimitMB float64) []MemoryViolation {
if hsLimitMB <= 0 && tsLimitMB <= 0 {
return nil
}
summaries := sc.GetSummary()
var violations []MemoryViolation
for _, summary := range summaries {
var limitMB float64
if strings.HasPrefix(summary.ContainerName, "hs-") {
limitMB = hsLimitMB
} else if strings.HasPrefix(summary.ContainerName, "ts-") {
limitMB = tsLimitMB
} else {
continue // Skip containers that don't match our patterns
}
if limitMB > 0 && summary.Memory.Max > limitMB {
violations = append(violations, MemoryViolation{
ContainerName: summary.ContainerName,
MaxMemoryMB: summary.Memory.Max,
LimitMB: limitMB,
})
}
}
return violations
}
// PrintSummaryAndCheckLimits prints the statistics summary and returns memory violations if any
func (sc *StatsCollector) PrintSummaryAndCheckLimits(hsLimitMB, tsLimitMB float64) []MemoryViolation {
sc.PrintSummary()
return sc.CheckMemoryLimits(hsLimitMB, tsLimitMB)
}
// Close closes the stats collector and cleans up resources
func (sc *StatsCollector) Close() error {
sc.StopCollection()
return sc.client.Close()
}

View File

@@ -10,10 +10,8 @@ import (
"strings"
)
var (
// ErrFileNotFoundInTar indicates a file was not found in the tar archive.
ErrFileNotFoundInTar = errors.New("file not found in tar")
)
// ErrFileNotFoundInTar indicates a file was not found in the tar archive.
var ErrFileNotFoundInTar = errors.New("file not found in tar")
// extractFileFromTar extracts a single file from a tar reader.
func extractFileFromTar(tarReader io.Reader, fileName, outputPath string) error {
@@ -42,6 +40,7 @@ func extractFileFromTar(tarReader io.Reader, fileName, outputPath string) error
if _, err := io.Copy(outFile, tr); err != nil {
return fmt.Errorf("failed to copy file contents: %w", err)
}
return nil
}
}
@@ -98,4 +97,4 @@ func extractDirectoryFromTar(tarReader io.Reader, targetDir string) error {
}
return nil
}
}

View File

@@ -225,9 +225,11 @@ tls_cert_path: ""
tls_key_path: ""
log:
# Valid log levels: panic, fatal, error, warn, info, debug, trace
level: info
# Output formatting for logs: text or json
format: text
level: info
## Policy
# headscale supports Tailscale's ACL policies.
@@ -322,51 +324,60 @@ dns:
# Note: for production you will want to set this to something like:
unix_socket: /var/run/headscale/headscale.sock
unix_socket_permission: "0770"
#
# headscale supports experimental OpenID connect support,
# it is still being tested and might have some bugs, please
# help us test it.
# OpenID Connect
# oidc:
# # Block startup until the identity provider is available and healthy.
# only_start_if_oidc_is_available: true
#
# # OpenID Connect Issuer URL from the identity provider
# issuer: "https://your-oidc.issuer.com/path"
#
# # Client ID from the identity provider
# client_id: "your-oidc-client-id"
#
# # Client secret generated by the identity provider
# # Note: client_secret and client_secret_path are mutually exclusive.
# client_secret: "your-oidc-client-secret"
# # Alternatively, set `client_secret_path` to read the secret from the file.
# # It resolves environment variables, making integration to systemd's
# # `LoadCredential` straightforward:
# client_secret_path: "${CREDENTIALS_DIRECTORY}/oidc_client_secret"
# # client_secret and client_secret_path are mutually exclusive.
#
# # The amount of time from a node is authenticated with OpenID until it
# # expires and needs to reauthenticate.
# # The amount of time a node is authenticated with OpenID until it expires
# # and needs to reauthenticate.
# # Setting the value to "0" will mean no expiry.
# expiry: 180d
#
# # Use the expiry from the token received from OpenID when the user logged
# # in, this will typically lead to frequent need to reauthenticate and should
# # only been enabled if you know what you are doing.
# # in. This will typically lead to frequent need to reauthenticate and should
# # only be enabled if you know what you are doing.
# # Note: enabling this will cause `oidc.expiry` to be ignored.
# use_expiry_from_token: false
#
# # Customize the scopes used in the OIDC flow, defaults to "openid", "profile" and "email" and add custom query
# # parameters to the Authorize Endpoint request. Scopes default to "openid", "profile" and "email".
# # The OIDC scopes to use, defaults to "openid", "profile" and "email".
# # Custom scopes can be configured as needed, be sure to always include the
# # required "openid" scope.
# scope: ["openid", "profile", "email"]
#
# scope: ["openid", "profile", "email", "custom"]
# # Provide custom key/value pairs which get sent to the identity provider's
# # authorization endpoint.
# extra_params:
# domain_hint: example.com
#
# # List allowed principal domains and/or users. If an authenticated user's domain is not in this list, the
# # authentication request will be rejected.
#
# # Only accept users whose email domain is part of the allowed_domains list.
# allowed_domains:
# - example.com
# # Note: Groups from keycloak have a leading '/'
# allowed_groups:
# - /headscale
#
# # Only accept users whose email address is part of the allowed_users list.
# allowed_users:
# - alice@example.com
#
# # Only accept users which are members of at least one group in the
# # allowed_groups list.
# allowed_groups:
# - /headscale
#
# # Optional: PKCE (Proof Key for Code Exchange) configuration
# # PKCE adds an additional layer of security to the OAuth 2.0 authorization code flow
# # by preventing authorization code interception attacks
@@ -374,6 +385,7 @@ unix_socket_permission: "0770"
# pkce:
# # Enable or disable PKCE support (default: false)
# enabled: false
#
# # PKCE method to use:
# # - plain: Use plain code verifier
# # - S256: Use SHA256 hashed code verifier (default, recommended)

View File

@@ -51,11 +51,11 @@ is homelabbers and self-hosters. Of course, we do not prevent people from using
it in a commercial/professional setting and often get questions about scaling.
Please note that when Headscale is developed, performance is not part of the
consideration as the main audience is considered to be users with a moddest
consideration as the main audience is considered to be users with a modest
amount of devices. We focus on correctness and feature parity with Tailscale
SaaS over time.
To understand if you might be able to use Headscale for your usecase, I will
To understand if you might be able to use Headscale for your use case, I will
describe two scenarios in an effort to explain what is the central bottleneck
of Headscale:
@@ -76,7 +76,7 @@ new "world map" is created for every node in the network.
This means that under certain conditions, Headscale can likely handle 100s
of devices (maybe more), if there is _little to no change_ happening in the
network. For example, in Scenario 1, the process of computing the world map is
extremly demanding due to the size of the network, but when the map has been
extremely demanding due to the size of the network, but when the map has been
created and the nodes are not changing, the Headscale instance will likely
return to a very low resource usage until the next time there is an event
requiring the new map.
@@ -94,14 +94,14 @@ learn about the current state of the world.
We expect that the performance will improve over time as we improve the code
base, but it is not a focus. In general, we will never make the tradeoff to make
things faster on the cost of less maintainable or readable code. We are a small
team and have to optimise for maintainabillity.
team and have to optimise for maintainability.
## Which database should I use?
We recommend the use of SQLite as database for headscale:
- SQLite is simple to setup and easy to use
- It scales well for all of headscale's usecases
- It scales well for all of headscale's use cases
- Development and testing happens primarily on SQLite
- PostgreSQL is still supported, but is considered to be in "maintenance mode"

View File

@@ -28,10 +28,9 @@ provides on overview of Headscale's feature and compatibility with the Tailscale
routers](../ref/routes.md#automatically-approve-routes-of-a-subnet-router) and [exit
nodes](../ref/routes.md#automatically-approve-an-exit-node-with-auto-approvers)
- [x] [Tailscale SSH](https://tailscale.com/kb/1193/tailscale-ssh)
* [ ] Node registration using Single-Sign-On (OpenID Connect) ([GitHub label "OIDC"](https://github.com/juanfont/headscale/labels/OIDC))
* [x] [Node registration using Single-Sign-On (OpenID Connect)](../ref/oidc.md) ([GitHub label "OIDC"](https://github.com/juanfont/headscale/labels/OIDC))
- [x] Basic registration
- [x] Update user profile from identity provider
- [ ] Dynamic ACL support
- [ ] OIDC groups cannot be used in ACLs
- [ ] [Funnel](https://tailscale.com/kb/1223/funnel) ([#1040](https://github.com/juanfont/headscale/issues/1040))
- [ ] [Serve](https://tailscale.com/kb/1312/serve) ([#1234](https://github.com/juanfont/headscale/issues/1921))

115
docs/ref/debug.md Normal file
View File

@@ -0,0 +1,115 @@
# Debugging and troubleshooting
Headscale and Tailscale provide debug and introspection capabilities that can be helpful when things don't work as
expected. This page explains some debugging techniques to help pinpoint problems.
Please also have a look at [Tailscale's Troubleshooting guide](https://tailscale.com/kb/1023/troubleshooting). It offers
a many tips and suggestions to troubleshoot common issues.
## Tailscale
The Tailscale client itself offers many commands to introspect its state as well as the state of the network:
- [Check local network conditions](https://tailscale.com/kb/1080/cli#netcheck): `tailscale netcheck`
- [Get the client status](https://tailscale.com/kb/1080/cli#status): `tailscale status --json`
- [Get DNS status](https://tailscale.com/kb/1080/cli#dns): `tailscale dns status --all`
- Client logs: `tailscale debug daemon-logs`
- Client netmap: `tailscale debug netmap`
- Test DERP connection: `tailscale debug derp headscale`
- And many more, see: `tailscale debug --help`
Many of the commands are helpful when trying to understand differences between Headscale and Tailscale SaaS.
## Headscale
### Application logging
The log levels `debug` and `trace` can be useful to get more information from Headscale.
```yaml hl_lines="3"
log:
# Valid log levels: panic, fatal, error, warn, info, debug, trace
level: debug
```
### Database logging
The database debug mode logs all database queries. Enable it to see how Headscale interacts with its database. This also
requires the application log level to be set to either `debug` or `trace`.
```yaml hl_lines="3 7"
database:
# Enable debug mode. This setting requires the log.level to be set to "debug" or "trace".
debug: false
log:
# Valid log levels: panic, fatal, error, warn, info, debug, trace
level: debug
```
### Metrics and debug endpoint
Headscale provides a metrics and debug endpoint. It allows to introspect different aspects such as:
- Information about the Go runtime, memory usage and statistics
- Connected nodes and pending registrations
- Active ACLs, filters and SSH policy
- Current DERPMap
- Prometheus metrics
!!! warning "Keep the metrics and debug endpoint private"
The listen address and port can be configured with the `metrics_listen_addr` variable in the [configuration
file](./configuration.md). By default it listens on localhost, port 9090.
Keep the metrics and debug endpoint private to your internal network and don't expose it to the Internet.
Query metrics via <http://localhost:9090/metrics> and get an overview of available debug information via
<http://localhost:9090/debug/>. Metrics may be queried from outside localhost but the debug interface is subject to
additional protection despite listening on all interfaces.
=== "Direct access"
Access the debug interface directly on the server where Headscale is installed.
```console
curl http://localhost:9090/debug/
```
=== "SSH port forwarding"
Use SSH port forwarding to forward Headscale's metrics and debug port to your device.
```console
ssh <HEADSCALE_SERVER> -L 9090:localhost:9090
```
Access the debug interface on your device by opening <http://localhost:9090/debug/> in your web browser.
=== "Via debug key"
The access control of the debug interface supports the use of a debug key. Traffic is accepted if the path to a
debug key is set via the environment variable `TS_DEBUG_KEY_PATH` and the debug key sent as value for `debugkey`
parameter with each request.
```console
openssl rand -hex 32 | tee debugkey.txt
export TS_DEBUG_KEY_PATH=debugkey.txt
headscale serve
```
Access the debug interface on your device by opening `http://<IP_OF_HEADSCALE>:9090/debug/?debugkey=<DEBUG_KEY>` in
your web browser. The `debugkey` parameter must be sent with every request.
=== "Via debug IP address"
The debug endpoint expects traffic from localhost. A different debug IP address may be configured by setting the
`TS_ALLOW_DEBUG_IP` environment variable before starting Headscale. The debug IP address is ignored when the HTTP
header `X-Forwarded-For` is present.
```console
export TS_ALLOW_DEBUG_IP=192.168.0.10 # IP address of your device
headscale serve
```
Access the debug interface on your device by opening `http://<IP_OF_HEADSCALE>:9090/debug/` in your web browser.

View File

@@ -1,162 +1,272 @@
# Configuring headscale to use OIDC authentication
# OpenID Connect
In order to authenticate users through a centralized solution one must enable the OIDC integration.
Headscale supports authentication via external identity providers using OpenID Connect (OIDC). It features:
Known limitations:
- Auto configuration via OpenID Connect Discovery Protocol
- [Proof Key for Code Exchange (PKCE) code verification](#enable-pkce-recommended)
- [Authorization based on a user's domain, email address or group membership](#authorize-users-with-filters)
- Synchronization of [standard OIDC claims](#supported-oidc-claims)
- No dynamic ACL support
- OIDC groups cannot be used in ACLs
Please see [limitations](#limitations) for known issues and limitations.
## Basic configuration
## Configuration
In your `config.yaml`, customize this to your liking:
OpenID requires configuration in Headscale and your identity provider:
```yaml title="config.yaml"
oidc:
# Block further startup until the OIDC provider is healthy and available
only_start_if_oidc_is_available: true
# Specified by your OIDC provider
issuer: "https://your-oidc.issuer.com/path"
# Specified/generated by your OIDC provider
client_id: "your-oidc-client-id"
client_secret: "your-oidc-client-secret"
# alternatively, set `client_secret_path` to read the secret from the file.
# It resolves environment variables, making integration to systemd's
# `LoadCredential` straightforward:
#client_secret_path: "${CREDENTIALS_DIRECTORY}/oidc_client_secret"
# as third option, it's also possible to load the oidc secret from environment variables
# set HEADSCALE_OIDC_CLIENT_SECRET to the required value
- Headscale: The `oidc` section of the Headscale [configuration](configuration.md) contains all available configuration
options along with a description and their default values.
- Identity provider: Please refer to the official documentation of your identity provider for specific instructions.
Additionally, there might be some useful hints in the [Identity provider specific
configuration](#identity-provider-specific-configuration) section below.
# Customize the scopes used in the OIDC flow, defaults to "openid", "profile" and "email" and add custom query
# parameters to the Authorize Endpoint request. Scopes default to "openid", "profile" and "email".
scope: ["openid", "profile", "email", "custom"]
# Optional: Passed on to the browser login request used to tweak behaviour for the OIDC provider
extra_params:
domain_hint: example.com
### Basic configuration
# Optional: List allowed principal domains and/or users. If an authenticated user's domain is not in this list,
# the authentication request will be rejected.
allowed_domains:
- example.com
# Optional. Note that groups from Keycloak have a leading '/'.
allowed_groups:
- /headscale
# Optional.
allowed_users:
- alice@example.com
A basic configuration connects Headscale to an identity provider and typically requires:
# Optional: PKCE (Proof Key for Code Exchange) configuration
# PKCE adds an additional layer of security to the OAuth 2.0 authorization code flow
# by preventing authorization code interception attacks
# See https://datatracker.ietf.org/doc/html/rfc7636
pkce:
# Enable or disable PKCE support (default: false)
enabled: false
# PKCE method to use:
# - plain: Use plain code verifier
# - S256: Use SHA256 hashed code verifier (default, recommended)
method: S256
```
- OpenID Connect Issuer URL from the identity provider. Headscale uses the OpenID Connect Discovery Protocol 1.0 to
automatically obtain OpenID configuration parameters (example: `https://sso.example.com`).
- Client ID from the identity provider (example: `headscale`).
- Client secret generated by the identity provider (example: `generated-secret`).
- Redirect URI for your identity provider (example: `https://headscale.example.com/oidc/callback`).
## Azure AD example
=== "Headscale"
In order to integrate headscale with Azure Active Directory, we'll need to provision an App Registration with the correct scopes and redirect URI. Here with Terraform:
```yaml
oidc:
issuer: "https://sso.example.com"
client_id: "headscale"
client_secret: "generated-secret"
```
```hcl title="terraform.hcl"
resource "azuread_application" "headscale" {
display_name = "Headscale"
=== "Identity provider"
sign_in_audience = "AzureADMyOrg"
fallback_public_client_enabled = false
* Create a new confidential client (`Client ID`, `Client secret`)
* Add Headscale's OIDC callback URL as valid redirect URL: `https://headscale.example.com/oidc/callback`
* Configure additional parameters to improve user experience such as: name, description, logo, …
required_resource_access {
// Microsoft Graph
resource_app_id = "00000003-0000-0000-c000-000000000000"
### Enable PKCE (recommended)
resource_access {
// scope: profile
id = "14dad69e-099b-42c9-810b-d002981feec1"
type = "Scope"
}
resource_access {
// scope: openid
id = "37f7f235-527c-4136-accd-4a02d197296e"
type = "Scope"
}
resource_access {
// scope: email
id = "64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0"
type = "Scope"
}
}
web {
# Points at your running headscale instance
redirect_uris = ["https://headscale.example.com/oidc/callback"]
Proof Key for Code Exchange (PKCE) adds an additional layer of security to the OAuth 2.0 authorization code flow by
preventing authorization code interception attacks, see: <https://datatracker.ietf.org/doc/html/rfc7636>. PKCE is
recommended and needs to be configured for Headscale and the identity provider alike:
implicit_grant {
access_token_issuance_enabled = false
id_token_issuance_enabled = true
}
}
=== "Headscale"
group_membership_claims = ["SecurityGroup"]
optional_claims {
# Expose group memberships
id_token {
name = "groups"
}
}
}
```yaml hl_lines="5-6"
oidc:
issuer: "https://sso.example.com"
client_id: "headscale"
client_secret: "generated-secret"
pkce:
enabled: true
```
resource "azuread_application_password" "headscale-application-secret" {
display_name = "Headscale Server"
application_object_id = azuread_application.headscale.object_id
}
=== "Identity provider"
resource "azuread_service_principal" "headscale" {
application_id = azuread_application.headscale.application_id
}
* Enable PKCE for the headscale client
* Set the PKCE challenge method to "S256"
resource "azuread_service_principal_password" "headscale" {
service_principal_id = azuread_service_principal.headscale.id
end_date_relative = "44640h"
}
### Authorize users with filters
output "headscale_client_id" {
value = azuread_application.headscale.application_id
}
Headscale allows to filter for allowed users based on their domain, email address or group membership. These filters can
be helpful to apply additional restrictions and control which users are allowed to join. Filters are disabled by
default, users are allowed to join once the authentication with the identity provider succeeds. In case multiple filters
are configured, a user needs to pass all of them.
output "headscale_client_secret" {
value = azuread_application_password.headscale-application-secret.value
}
```
=== "Allowed domains"
And in your headscale `config.yaml`:
* Check the email domain of each authenticating user against the list of allowed domains and only authorize users
whose email domain matches `example.com`.
* Access allowed: `alice@example.com`
* Access denied: `bob@example.net`
```yaml title="config.yaml"
oidc:
issuer: "https://login.microsoftonline.com/<tenant-UUID>/v2.0"
client_id: "<client-id-from-terraform>"
client_secret: "<client-secret-from-terraform>"
```yaml hl_lines="5-6"
oidc:
issuer: "https://sso.example.com"
client_id: "headscale"
client_secret: "generated-secret"
allowed_domains:
- "example.com"
```
# Optional: add "groups"
scope: ["openid", "profile", "email"]
extra_params:
# Use your own domain, associated with Azure AD
domain_hint: example.com
# Optional: Force the Azure AD account picker
prompt: select_account
```
=== "Allowed users/emails"
## Google OAuth Example
* Check the email address of each authenticating user against the list of allowed email addresses and only authorize
users whose email is part of the `allowed_users` list.
* Access allowed: `alice@example.com`, `bob@example.net`
* Access denied: `mallory@example.net`
In order to integrate headscale with Google, you'll need to have a [Google Cloud Console](https://console.cloud.google.com) account.
```yaml hl_lines="5-7"
oidc:
issuer: "https://sso.example.com"
client_id: "headscale"
client_secret: "generated-secret"
allowed_users:
- "alice@example.com"
- "bob@example.net"
```
Google OAuth has a [verification process](https://support.google.com/cloud/answer/9110914?hl=en) if you need to have users authenticate who are outside of your domain. If you only need to authenticate users from your domain name (ie `@example.com`), you don't need to go through the verification process.
=== "Allowed groups"
However if you don't have a domain, or need to add users outside of your domain, you can manually add emails via Google Console.
* Use the OIDC `groups` claim of each authenticating user to get their group membership and only authorize users
which are members in at least one of the referenced groups.
* Access allowed: users in the `headscale_users` group
* Access denied: users without groups, users with other groups
### Steps
```yaml hl_lines="5-7"
oidc:
issuer: "https://sso.example.com"
client_id: "headscale"
client_secret: "generated-secret"
scope: ["openid", "profile", "email", "groups"]
allowed_groups:
- "headscale_users"
```
### Customize node expiration
The node expiration is the amount of time a node is authenticated with OpenID Connect until it expires and needs to
reauthenticate. The default node expiration is 180 days. This can either be customized or set to the expiration from the
Access Token.
=== "Customize node expiration"
```yaml hl_lines="5"
oidc:
issuer: "https://sso.example.com"
client_id: "headscale"
client_secret: "generated-secret"
expiry: 30d # Use 0 to disable node expiration
```
=== "Use expiration from Access Token"
Please keep in mind that the Access Token is typically a short-lived token that expires within a few minutes. You
will have to configure token expiration in your identity provider to avoid frequent re-authentication.
```yaml hl_lines="5"
oidc:
issuer: "https://sso.example.com"
client_id: "headscale"
client_secret: "generated-secret"
use_expiry_from_token: true
```
!!! tip "Expire a node and force re-authentication"
A node can be expired immediately via:
```console
headscale node expire -i <NODE_ID>
```
### Reference a user in the policy
You may refer to users in the Headscale policy via:
- Email address
- Username
- Provider identifier (only available in the database or from your identity provider)
!!! note "A user identifier in the policy must contain a single `@`"
The Headscale policy requires a single `@` to reference a user. If the username or provider identifier doesn't
already contain a single `@`, it needs to be appended at the end. For example: the username `ssmith` has to be
written as `ssmith@` to be correctly identified as user within the policy.
!!! warning "Email address or username might be updated by users"
Many identity providers allow users to update their own profile. Depending on the identity provider and its
configuration, the values for username or email address might change over time. This might have unexpected
consequences for Headscale where a policy might no longer work or a user might obtain more access by hijacking an
existing username or email address.
## Supported OIDC claims
Headscale uses [the standard OIDC claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) to
populate and update its local user profile on each login. OIDC claims are read from the ID Token or from the UserInfo
endpoint.
| Headscale profile | OIDC claim | Notes / examples |
| ------------------- | -------------------- | ------------------------------------------------------------------------------------------------- |
| email address | `email` | Only used when `email_verified: true` |
| display name | `name` | eg: `Sam Smith` |
| username | `preferred_username` | Depends on identity provider, eg: `ssmith`, `ssmith@idp.example.com`, `\\example.com\ssmith` |
| profile picture | `picture` | URL to a profile picture or avatar |
| provider identifier | `iss`, `sub` | A stable and unique identifier for a user, typically a combination of `iss` and `sub` OIDC claims |
| | `groups` | [Only used to filter for allowed groups](#authorize-users-with-filters) |
## Limitations
- Support for OpenID Connect aims to be generic and vendor independent. It offers only limited support for quirks of
specific identity providers.
- OIDC groups cannot be used in ACLs.
- The username provided by the identity provider needs to adhere to this pattern:
- The username must be at least two characters long.
- It must only contain letters, digits, hyphens, dots, underscores, and up to a single `@`.
- The username must start with a letter.
- A user's email address is only synchronized to the local user profile when the identity provider marks the email
address as verified (`email_verified: true`).
Please see the [GitHub label "OIDC"](https://github.com/juanfont/headscale/labels/OIDC) for OIDC related issues.
## Identity provider specific configuration
!!! warning "Third-party software and services"
This section of the documentation is specific for third-party software and services. We recommend users read the
third-party documentation on how to configure and integrate an OIDC client. Please see the [Configuration
section](#configuration) for a description of Headscale's OIDC related configuration settings.
Any identity provider with OpenID Connect support should "just work" with Headscale. The following identity providers
are known to work:
- [Authelia](#authelia)
- [Authentik](#authentik)
- [Kanidm](#kanidm)
- [Keycloak](#keycloak)
### Authelia
Authelia is fully supported by Headscale.
#### Additional configuration to authorize users based on filters
Authelia (4.39.0 or newer) no longer provides standard OIDC claims such as `email` or `groups` via the ID Token. The
OIDC `email` and `groups` claims are used to [authorize users with filters](#authorize-users-with-filters). This extra
configuration step is **only** needed if you need to authorize access based on one of the following user properties:
- domain
- email address
- group membership
Please follow the instructions from Authelia's documentation on how to [Restore Functionality Prior to Claims
Parameter](https://www.authelia.com/integration/openid-connect/openid-connect-1.0-claims/#restore-functionality-prior-to-claims-parameter).
### Authentik
- Authentik is fully supported by Headscale.
- [Headscale does not JSON Web Encryption](https://github.com/juanfont/headscale/issues/2446). Leave the field
`Encryption Key` in the providers section unset.
### Google OAuth
!!! warning "No username due to missing preferred_username"
Google OAuth does not send the `preferred_username` claim when the scope `profile` is requested. The username in
Headscale will be blank/not set.
In order to integrate Headscale with Google, you'll need to have a [Google Cloud
Console](https://console.cloud.google.com) account.
Google OAuth has a [verification process](https://support.google.com/cloud/answer/9110914?hl=en) if you need to have
users authenticate who are outside of your domain. If you only need to authenticate users from your domain name (ie
`@example.com`), you don't need to go through the verification process.
However if you don't have a domain, or need to add users outside of your domain, you can manually add emails via Google
Console.
#### Steps
1. Go to [Google Console](https://console.cloud.google.com) and login or create an account if you don't have one.
2. Create a project (if you don't already have one).
@@ -164,58 +274,44 @@ However if you don't have a domain, or need to add users outside of your domain,
4. Click `Create Credentials` -> `OAuth client ID`
5. Under `Application Type`, choose `Web Application`
6. For `Name`, enter whatever you like
7. Under `Authorised redirect URIs`, use `https://example.com/oidc/callback`, replacing example.com with your headscale URL.
7. Under `Authorised redirect URIs`, add Headscale's OIDC callback URL: `https://headscale.example.com/oidc/callback`
8. Click `Save` at the bottom of the form
9. Take note of the `Client ID` and `Client secret`, you can also download it for reference if you need it.
10. Edit your headscale config, under `oidc`, filling in your `client_id` and `client_secret`:
```yaml title="config.yaml"
oidc:
issuer: "https://accounts.google.com"
client_id: ""
client_secret: ""
scope: ["openid", "profile", "email"]
```
10. [Configure Headscale following the "Basic configuration" steps](#basic-configuration). The issuer URL for Google
OAuth is: `https://accounts.google.com`.
You can also use `allowed_domains` and `allowed_users` to restrict the users who can authenticate.
### Kanidm
## Authelia
- Kanidm is fully supported by Headscale.
- Groups for the [allowed groups filter](#authorize-users-with-filters) need to be specified with their full SPN, for
example: `headscale_users@sso.example.com`.
Authelia since v4.39.0, has removed most claims from the `ID Token`, they are still available when application queries [UserInfo Endpoint](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo).
### Keycloak
Following config restores sending 'default' claims in the `ID Token`
Keycloak is fully supported by Headscale.
For more information please read: [Authelia restore functionality prior to claims parameter](https://www.authelia.com/integration/openid-connect/openid-connect-1.0-claims/#restore-functionality-prior-to-claims-parameter)
#### Additional configuration to use the allowed groups filter
```yaml
identity_providers:
oidc:
claims_policies:
default:
id_token:
[
"groups",
"email",
"email_verified",
"alt_emails",
"preferred_username",
"name",
]
clients:
- client_id: "headscale"
client_name: "headscale"
client_secret: ""
public: false
claims_policy: "default"
authorization_policy: "two_factor"
require_pkce: true
pkce_challenge_method: "S256"
redirect_uris:
- "https://headscale.example.com/oidc/callback"
scopes:
- "openid"
- "profile"
- "groups"
- "email"
userinfo_signed_response_alg: "none"
token_endpoint_auth_method: "client_secret_basic"
```
Keycloak has no built-in client scope for the OIDC `groups` claim. This extra configuration step is **only** needed if
you need to [authorize access based on group membership](#authorize-users-with-filters).
- Create a new client scope `groups` for OpenID Connect:
- Configure a `Group Membership` mapper with name `groups` and the token claim name `groups`.
- Enable the mapper for the ID Token, Access Token and UserInfo endpoint.
- Configure the new client scope for your Headscale client:
- Edit the Headscale client.
- Search for the client scope `group`.
- Add it with assigned type `Default`.
- [Configure the allowed groups in Headscale](#authorize-users-with-filters). Keep in mind that groups in Keycloak start
with a leading `/`.
### Microsoft Entra ID
In order to integrate Headscale with Microsoft Entra ID, you'll need to provision an App Registration with the correct
scopes and redirect URI.
[Configure Headscale following the "Basic configuration" steps](#basic-configuration). The issuer URL for Microsoft
Entra ID is: `https://login.microsoftonline.com/<tenant-UUID>/v2.0`. The following `extra_params` might be useful:
- `domain_hint: example.com` to use your own domain
- `prompt: select_account` to force an account picker during login

View File

@@ -2,7 +2,7 @@
## Bring your own certificate
Headscale can be configured to expose its web service via TLS. To configure the certificate and key file manually, set the `tls_cert_path` and `tls_cert_path` configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.
Headscale can be configured to expose its web service via TLS. To configure the certificate and key file manually, set the `tls_cert_path` and `tls_key_path` configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.
```yaml title="config.yaml"
tls_cert_path: ""

View File

@@ -112,11 +112,11 @@ docker exec -it headscale \
### Register a machine using a pre authenticated key
Generate a key using the command line:
Generate a key using the command line for the user with ID 1:
```shell
docker exec -it headscale \
headscale preauthkeys create --user myfirstuser --reusable --expiration 24h
headscale preauthkeys create --user 1 --reusable --expiration 24h
```
This will return a pre-authenticated key that can be used to connect a node to headscale with the `tailscale up` command:

View File

@@ -4,11 +4,35 @@ Headscale should just work as long as the following requirements are met:
- A server with a public IP address for headscale. A dual-stack setup with a public IPv4 and a public IPv6 address is
recommended.
- Headscale is served via HTTPS on port 443[^1].
- Headscale is served via HTTPS on port 443[^1] and [may use additional ports](#ports-in-use).
- A reasonably modern Linux or BSD based operating system.
- A dedicated local user account to run headscale.
- A little bit of command line knowledge to configure and operate headscale.
## Ports in use
The ports in use vary with the intended scenario and enabled features. Some of the listed ports may be changed via the
[configuration file](../ref/configuration.md) but we recommend to stick with the default values.
- tcp/80
- Expose publicly: yes
- HTTP, used by Let's Encrypt to verify ownership via the HTTP-01 challenge.
- Only required if the built-in Let's Enrypt client with the HTTP-01 challenge is used. See [TLS](../ref/tls.md) for
details.
- tcp/443
- Expose publicly: yes
- HTTPS, required to make Headscale available to Tailscale clients[^1]
- Required if the built-in DERP server is enabled
- udp/3478
- Expose publicly: yes
- STUN, required if the built-in DERP server is enabled
- tcp/50443
- Expose publicly: yes
- Only required if the gRPC interface is used to [remote-control Headscale](../ref/remote-cli.md).
- tcp/9090
- Expose publicly: no
- [Metrics and debug endpoint](../ref/debug.md#metrics-and-debug-endpoint)
## Assumptions
The headscale documentation and the provided examples are written with a few assumptions in mind:

View File

@@ -117,14 +117,14 @@ headscale instance. By default, the key is valid for one hour and can only be us
=== "Native"
```shell
headscale preauthkeys create --user <USER>
headscale preauthkeys create --user <USER_ID>
```
=== "Container"
```shell
docker exec -it headscale \
headscale preauthkeys create --user <USER>
headscale preauthkeys create --user <USER_ID>
```
The command returns the preauthkey on success which is used to connect a node to the headscale instance via the

6
flake.lock generated
View File

@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1746300365,
"narHash": "sha256-thYTdWqCRipwPRxWiTiH1vusLuAy0okjOyzRx4hLWh4=",
"lastModified": 1752012998,
"narHash": "sha256-Q82Ms+FQmgOBkdoSVm+FBpuFoeUAffNerR5yVV7SgT8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f21e4546e3ede7ae34d12a84602a22246b31f7e0",
"rev": "2a2130494ad647f953593c4e84ea4df839fbd68c",
"type": "github"
},
"original": {

View File

@@ -19,7 +19,7 @@
overlay = _: prev: let
pkgs = nixpkgs.legacyPackages.${prev.system};
buildGo = pkgs.buildGo124Module;
vendorHash = "sha256-ACab+UvKrh+7G5KXNS+Iu9y8ZExefQDhwEKgIv0iIvE=";
vendorHash = "sha256-83L2NMyOwKCHWqcowStJ7Ze/U9CJYhzleDRLrJNhX2g=";
in {
headscale = buildGo {
pname = "headscale";
@@ -113,9 +113,9 @@
buildGoModule = buildGo;
};
gopls = prev.gopls.override {
buildGoModule = buildGo;
};
# gopls = prev.gopls.override {
# buildGoModule = buildGo;
# };
};
}
// flake-utils.lib.eachDefaultSystem
@@ -159,7 +159,8 @@
# Add hi to make it even easier to use ci runner.
hi
];
]
++ lib.optional pkgs.stdenv.isLinux [traceroute];
# Add entry to build a docker image with headscale
# caveat: only works on Linux

31
go.mod
View File

@@ -23,7 +23,6 @@ require (
github.com/gorilla/mux v1.8.1
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.0
github.com/jagottsicher/termcolor v1.0.2
github.com/klauspost/compress v1.18.0
github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25
github.com/ory/dockertest/v3 v3.12.0
github.com/philip-bui/grpc-zerolog v1.0.1
@@ -39,14 +38,15 @@ require (
github.com/spf13/viper v1.20.1
github.com/stretchr/testify v1.10.0
github.com/tailscale/hujson v0.0.0-20250226034555-ec1d1c113d33
github.com/tailscale/squibble v0.0.0-20250108170732-a4ca58afa694
github.com/tailscale/tailsql v0.0.0-20250421235516-02f85f087b97
github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.39.0
golang.org/x/crypto v0.40.0
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0
golang.org/x/net v0.41.0
golang.org/x/net v0.42.0
golang.org/x/oauth2 v0.30.0
golang.org/x/sync v0.15.0
golang.org/x/sync v0.16.0
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822
google.golang.org/grpc v1.73.0
google.golang.org/protobuf v1.36.6
@@ -54,7 +54,7 @@ require (
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/postgres v1.6.0
gorm.io/gorm v1.30.0
tailscale.com v1.84.2
tailscale.com v1.84.3
zgo.at/zcache/v2 v2.2.0
zombiezen.com/go/postgrestest v1.0.1
)
@@ -80,7 +80,7 @@ require (
modernc.org/libc v1.62.1 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.10.0 // indirect
modernc.org/sqlite v1.37.0 // indirect
modernc.org/sqlite v1.37.0
)
require (
@@ -116,7 +116,7 @@ require (
github.com/containerd/errdefs v0.3.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect
github.com/creachadair/mds v0.24.1 // indirect
github.com/creachadair/mds v0.24.3 // indirect
github.com/dblohm7/wingoes v0.0.0-20240123200102-b75a8a7d7eb0 // indirect
github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect
github.com/distribution/reference v0.6.0 // indirect
@@ -165,6 +165,7 @@ require (
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jsimonetti/rtnetlink v1.4.1 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.9 // indirect
@@ -213,7 +214,6 @@ require (
github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 // indirect
github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect
github.com/tailscale/setec v0.0.0-20250305161714-445cadbbca3d // indirect
github.com/tailscale/squibble v0.0.0-20250108170732-a4ca58afa694 // indirect
github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 // indirect
github.com/tailscale/wireguard-go v0.0.0-20250304000100-91a0587fb251 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
@@ -231,14 +231,19 @@ require (
go.opentelemetry.io/otel/trace v1.36.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/mod v0.26.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/term v0.33.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/time v0.10.0 // indirect
golang.org/x/tools v0.33.0 // indirect
golang.org/x/tools v0.35.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 // indirect
)
tool (
golang.org/x/tools/cmd/stringer
tailscale.com/cmd/viewer
)

38
go.sum
View File

@@ -126,8 +126,8 @@ github.com/creachadair/command v0.1.22 h1:WmdrURwZdmPD1jm13SjKooaMoqo7mW1qI2BPCS
github.com/creachadair/command v0.1.22/go.mod h1:YFc+OMGucqTpxwQg/iJnNg8BMNmRPDK60rYy8ckgKwE=
github.com/creachadair/flax v0.0.5 h1:zt+CRuXQASxwQ68e9GHAOnEgAU29nF0zYMHOCrL5wzE=
github.com/creachadair/flax v0.0.5/go.mod h1:F1PML0JZLXSNDMNiRGK2yjm5f+L9QCHchyHBldFymj8=
github.com/creachadair/mds v0.24.1 h1:bzL4ItCtAUxxO9KkotP0PVzlw4tnJicAcjPu82v2mGs=
github.com/creachadair/mds v0.24.1/go.mod h1:ArfS0vPHoLV/SzuIzoqTEZfoYmac7n9Cj8XPANHocvw=
github.com/creachadair/mds v0.24.3 h1:X7cM2ymZSyl4IVWnfyXLxRXMJ6awhbcWvtLPhfnTaqI=
github.com/creachadair/mds v0.24.3/go.mod h1:0oeHt9QWu8VfnmskOL4zi2CumjEvB29ScmtOmdrhFeU=
github.com/creachadair/taskgroup v0.13.2 h1:3KyqakBuFsm3KkXi/9XIb0QcA8tEzLHLgaoidf0MdVc=
github.com/creachadair/taskgroup v0.13.2/go.mod h1:i3V1Zx7H8RjwljUEeUWYT30Lmb9poewSb2XI1yTwD0g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -555,8 +555,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8=
@@ -567,8 +567,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -577,8 +577,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -587,8 +587,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -615,8 +615,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -624,8 +624,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
@@ -633,8 +633,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -643,8 +643,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -714,6 +714,8 @@ software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=
tailscale.com v1.84.2 h1:v6aM4RWUgYiV52LRAx6ET+dlGnvO/5lnqPXb7/pMnR0=
tailscale.com v1.84.2/go.mod h1:6/S63NMAhmncYT/1zIPDJkvCuZwMw+JnUuOfSPNazpo=
tailscale.com v1.84.3 h1:Ur9LMedSgicwbqpy5xn7t49G8490/s6rqAJOk5Q5AYE=
tailscale.com v1.84.3/go.mod h1:6/S63NMAhmncYT/1zIPDJkvCuZwMw+JnUuOfSPNazpo=
zgo.at/zcache/v2 v2.2.0 h1:K29/IPjMniZfveYE+IRXfrl11tMzHkIPuyGrfVZ2fGo=
zgo.at/zcache/v2 v2.2.0/go.mod h1:gyCeoLVo01QjDZynjime8xUGHHMbsLiPyUTBpDGd4Gk=
zombiezen.com/go/postgrestest v1.0.1 h1:aXoADQAJmZDU3+xilYVut0pHhgc0sF8ZspPW9gFNwP4=

View File

@@ -28,14 +28,15 @@ import (
derpServer "github.com/juanfont/headscale/hscontrol/derp/server"
"github.com/juanfont/headscale/hscontrol/dns"
"github.com/juanfont/headscale/hscontrol/mapper"
"github.com/juanfont/headscale/hscontrol/notifier"
"github.com/juanfont/headscale/hscontrol/state"
"github.com/juanfont/headscale/hscontrol/types"
"github.com/juanfont/headscale/hscontrol/types/change"
"github.com/juanfont/headscale/hscontrol/util"
zerolog "github.com/philip-bui/grpc-zerolog"
"github.com/pkg/profile"
zl "github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/sasha-s/go-deadlock"
"golang.org/x/crypto/acme"
"golang.org/x/crypto/acme/autocert"
"golang.org/x/sync/errgroup"
@@ -64,6 +65,19 @@ var (
)
)
var (
debugDeadlock = envknob.Bool("HEADSCALE_DEBUG_DEADLOCK")
debugDeadlockTimeout = envknob.RegisterDuration("HEADSCALE_DEBUG_DEADLOCK_TIMEOUT")
)
func init() {
deadlock.Opts.Disable = !debugDeadlock
if debugDeadlock {
deadlock.Opts.DeadlockTimeout = debugDeadlockTimeout()
deadlock.Opts.PrintAllCurrentGoroutines = true
}
}
const (
AuthPrefix = "Bearer "
updateInterval = 5 * time.Second
@@ -82,9 +96,8 @@ type Headscale struct {
// Things that generate changes
extraRecordMan *dns.ExtraRecordsMan
mapper *mapper.Mapper
nodeNotifier *notifier.Notifier
authProvider AuthProvider
mapBatcher mapper.Batcher
pollNetMapStreamWG sync.WaitGroup
}
@@ -118,7 +131,6 @@ func NewHeadscale(cfg *types.Config) (*Headscale, error) {
cfg: cfg,
noisePrivateKey: noisePrivateKey,
pollNetMapStreamWG: sync.WaitGroup{},
nodeNotifier: notifier.NewNotifier(cfg),
state: s,
}
@@ -136,12 +148,7 @@ func NewHeadscale(cfg *types.Config) (*Headscale, error) {
return
}
// Send policy update notifications if needed
if policyChanged {
ctx := types.NotifyCtx(context.Background(), "ephemeral-gc-policy", node.Hostname)
app.nodeNotifier.NotifyAll(ctx, types.UpdateFull())
}
app.Change(policyChanged)
log.Debug().Uint64("node.id", ni.Uint64()).Msgf("deleted ephemeral node")
})
app.ephemeralGC = ephemeralGC
@@ -153,10 +160,9 @@ func NewHeadscale(cfg *types.Config) (*Headscale, error) {
defer cancel()
oidcProvider, err := NewAuthProviderOIDC(
ctx,
&app,
cfg.ServerURL,
&cfg.OIDC,
app.state,
app.nodeNotifier,
)
if err != nil {
if cfg.OIDC.OnlyStartIfOIDCIsAvailable {
@@ -262,16 +268,18 @@ func (h *Headscale) scheduledTasks(ctx context.Context) {
return
case <-expireTicker.C:
var update types.StateUpdate
var expiredNodeChanges []change.ChangeSet
var changed bool
lastExpiryCheck, update, changed = h.state.ExpireExpiredNodes(lastExpiryCheck)
lastExpiryCheck, expiredNodeChanges, changed = h.state.ExpireExpiredNodes(lastExpiryCheck)
if changed {
log.Trace().Interface("nodes", update.ChangePatches).Msgf("expiring nodes")
log.Trace().Interface("changes", expiredNodeChanges).Msgf("expiring nodes")
ctx := types.NotifyCtx(context.Background(), "expire-expired", "na")
h.nodeNotifier.NotifyAll(ctx, update)
// Send the changes directly since they're already in the new format
for _, nodeChange := range expiredNodeChanges {
h.Change(nodeChange)
}
}
case <-derpTickerChan:
@@ -282,11 +290,7 @@ func (h *Headscale) scheduledTasks(ctx context.Context) {
derpMap.Regions[region.RegionID] = &region
}
ctx := types.NotifyCtx(context.Background(), "derpmap-update", "na")
h.nodeNotifier.NotifyAll(ctx, types.StateUpdate{
Type: types.StateDERPUpdated,
DERPMap: derpMap,
})
h.Change(change.DERPSet)
case records, ok := <-extraRecordsUpdate:
if !ok {
@@ -294,19 +298,16 @@ func (h *Headscale) scheduledTasks(ctx context.Context) {
}
h.cfg.TailcfgDNSConfig.ExtraRecords = records
ctx := types.NotifyCtx(context.Background(), "dns-extrarecord", "all")
// TODO(kradalby): We can probably do better than sending a full update here,
// but for now this will ensure that all of the nodes get the new records.
h.nodeNotifier.NotifyAll(ctx, types.UpdateFull())
h.Change(change.ExtraRecordsSet)
}
}
}
func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context,
req interface{},
req any,
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error) {
) (any, error) {
// Check if the request is coming from the on-server client.
// This is not secure, but it is to maintain maintainability
// with the "legacy" database-based client
@@ -448,6 +449,7 @@ func (h *Headscale) createRouter(grpcMux *grpcRuntime.ServeMux) *mux.Router {
router.HandleFunc(ts2021UpgradePath, h.NoiseUpgradeHandler).
Methods(http.MethodPost, http.MethodGet)
router.HandleFunc("/robots.txt", h.RobotsHandler).Methods(http.MethodGet)
router.HandleFunc("/health", h.HealthHandler).Methods(http.MethodGet)
router.HandleFunc("/key", h.KeyHandler).Methods(http.MethodGet)
router.HandleFunc("/register/{registration_id}", h.authProvider.RegisterHandler).
@@ -484,58 +486,6 @@ func (h *Headscale) createRouter(grpcMux *grpcRuntime.ServeMux) *mux.Router {
return router
}
// // TODO(kradalby): Do a variant of this, and polman which only updates the node that has changed.
// // Maybe we should attempt a new in memory state and not go via the DB?
// // Maybe this should be implemented as an event bus?
// // A bool is returned indicating if a full update was sent to all nodes
// func usersChangedHook(db *db.HSDatabase, polMan policy.PolicyManager, notif *notifier.Notifier) error {
// users, err := db.ListUsers()
// if err != nil {
// return err
// }
// changed, err := polMan.SetUsers(users)
// if err != nil {
// return err
// }
// if changed {
// ctx := types.NotifyCtx(context.Background(), "acl-users-change", "all")
// notif.NotifyAll(ctx, types.UpdateFull())
// }
// return nil
// }
// // TODO(kradalby): Do a variant of this, and polman which only updates the node that has changed.
// // Maybe we should attempt a new in memory state and not go via the DB?
// // Maybe this should be implemented as an event bus?
// // A bool is returned indicating if a full update was sent to all nodes
// func nodesChangedHook(
// db *db.HSDatabase,
// polMan policy.PolicyManager,
// notif *notifier.Notifier,
// ) (bool, error) {
// nodes, err := db.ListNodes()
// if err != nil {
// return false, err
// }
// filterChanged, err := polMan.SetNodes(nodes)
// if err != nil {
// return false, err
// }
// if filterChanged {
// ctx := types.NotifyCtx(context.Background(), "acl-nodes-change", "all")
// notif.NotifyAll(ctx, types.UpdateFull())
// return true, nil
// }
// return false, nil
// }
// Serve launches the HTTP and gRPC server service Headscale and the API.
func (h *Headscale) Serve() error {
capver.CanOldCodeBeCleanedUp()
@@ -562,8 +512,9 @@ func (h *Headscale) Serve() error {
Str("minimum_version", capver.TailscaleVersion(capver.MinSupportedCapabilityVersion)).
Msg("Clients with a lower minimum version will be rejected")
// Fetch an initial DERP Map before we start serving
h.mapper = mapper.NewMapper(h.state, h.cfg, h.nodeNotifier)
h.mapBatcher = mapper.NewBatcherAndMapper(h.cfg, h.state)
h.mapBatcher.Start()
defer h.mapBatcher.Close()
// TODO(kradalby): fix state part.
if h.cfg.DERP.ServerEnabled {
@@ -822,7 +773,7 @@ func (h *Headscale) Serve() error {
case syscall.SIGHUP:
log.Info().
Str("signal", sig.String()).
Msg("Received SIGHUP, reloading ACL and Config")
Msg("Received SIGHUP, reloading ACL policy")
if h.cfg.Policy.IsEmpty() {
continue
@@ -838,8 +789,12 @@ func (h *Headscale) Serve() error {
log.Info().
Msg("ACL policy successfully reloaded, notifying nodes of change")
ctx := types.NotifyCtx(context.Background(), "acl-sighup", "na")
h.nodeNotifier.NotifyAll(ctx, types.UpdateFull())
err = h.state.AutoApproveNodes()
if err != nil {
log.Error().Err(err).Msg("failed to approve routes after new policy")
}
h.Change(change.PolicySet)
}
default:
info := func(msg string) { log.Info().Msg(msg) }
@@ -865,7 +820,6 @@ func (h *Headscale) Serve() error {
}
info("closing node notifier")
h.nodeNotifier.Close()
info("waiting for netmap stream to close")
h.pollNetMapStreamWG.Wait()
@@ -1047,3 +1001,10 @@ func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) {
return &machineKey, nil
}
// Change is used to send changes to nodes.
// All change should be enqueued here and empty will be automatically
// ignored.
func (h *Headscale) Change(c change.ChangeSet) {
h.mapBatcher.AddWork(c)
}

View File

@@ -10,6 +10,8 @@ import (
"time"
"github.com/juanfont/headscale/hscontrol/types"
"github.com/juanfont/headscale/hscontrol/types/change"
"gorm.io/gorm"
"tailscale.com/tailcfg"
"tailscale.com/types/key"
@@ -32,6 +34,21 @@ func (h *Headscale) handleRegister(
}
if node != nil {
// If an existing node is trying to register with an auth key,
// we need to validate the auth key even for existing nodes
if regReq.Auth != nil && regReq.Auth.AuthKey != "" {
resp, err := h.handleRegisterWithAuthKey(regReq, machineKey)
if err != nil {
// Preserve HTTPError types so they can be handled properly by the HTTP layer
var httpErr HTTPError
if errors.As(err, &httpErr) {
return nil, httpErr
}
return nil, fmt.Errorf("handling register with auth key for existing node: %w", err)
}
return resp, nil
}
resp, err := h.handleExistingNode(node, regReq, machineKey)
if err != nil {
return nil, fmt.Errorf("handling existing node: %w", err)
@@ -47,6 +64,11 @@ func (h *Headscale) handleRegister(
if regReq.Auth != nil && regReq.Auth.AuthKey != "" {
resp, err := h.handleRegisterWithAuthKey(regReq, machineKey)
if err != nil {
// Preserve HTTPError types so they can be handled properly by the HTTP layer
var httpErr HTTPError
if errors.As(err, &httpErr) {
return nil, httpErr
}
return nil, fmt.Errorf("handling register with auth key: %w", err)
}
@@ -66,11 +88,13 @@ func (h *Headscale) handleExistingNode(
regReq tailcfg.RegisterRequest,
machineKey key.MachinePublic,
) (*tailcfg.RegisterResponse, error) {
if node.MachineKey != machineKey {
return nil, NewHTTPError(http.StatusUnauthorized, "node exist with different machine key", nil)
}
expired := node.IsExpired()
if !expired && !regReq.Expiry.IsZero() {
requestExpiry := regReq.Expiry
@@ -82,43 +106,26 @@ func (h *Headscale) handleExistingNode(
// If the request expiry is in the past, we consider it a logout.
if requestExpiry.Before(time.Now()) {
if node.IsEphemeral() {
policyChanged, err := h.state.DeleteNode(node)
c, err := h.state.DeleteNode(node)
if err != nil {
return nil, fmt.Errorf("deleting ephemeral node: %w", err)
}
// Send policy update notifications if needed
if policyChanged {
ctx := types.NotifyCtx(context.Background(), "auth-logout-ephemeral-policy", "na")
h.nodeNotifier.NotifyAll(ctx, types.UpdateFull())
} else {
ctx := types.NotifyCtx(context.Background(), "logout-ephemeral", "na")
h.nodeNotifier.NotifyAll(ctx, types.UpdatePeerRemoved(node.ID))
}
h.Change(c)
return nil, nil
}
}
n, policyChanged, err := h.state.SetNodeExpiry(node.ID, requestExpiry)
_, c, err := h.state.SetNodeExpiry(node.ID, requestExpiry)
if err != nil {
return nil, fmt.Errorf("setting node expiry: %w", err)
}
// Send policy update notifications if needed
if policyChanged {
ctx := types.NotifyCtx(context.Background(), "auth-expiry-policy", "na")
h.nodeNotifier.NotifyAll(ctx, types.UpdateFull())
} else {
ctx := types.NotifyCtx(context.Background(), "logout-expiry", "na")
h.nodeNotifier.NotifyWithIgnore(ctx, types.UpdateExpire(node.ID, requestExpiry), node.ID)
h.Change(c)
}
return nodeToRegisterResponse(n), nil
}
return nodeToRegisterResponse(node), nil
return nodeToRegisterResponse(node), nil
}
func nodeToRegisterResponse(node *types.Node) *tailcfg.RegisterResponse {
@@ -169,8 +176,7 @@ func (h *Headscale) handleRegisterWithAuthKey(
regReq tailcfg.RegisterRequest,
machineKey key.MachinePublic,
) (*tailcfg.RegisterResponse, error) {
node, changed, err := h.state.HandleNodeFromPreAuthKey(
node, changed, policyChanged, err := h.state.HandleNodeFromPreAuthKey(
regReq,
machineKey,
)
@@ -178,12 +184,20 @@ func (h *Headscale) handleRegisterWithAuthKey(
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, NewHTTPError(http.StatusUnauthorized, "invalid pre auth key", nil)
}
if perr, ok := err.(types.PAKError); ok {
var perr types.PAKError
if errors.As(err, &perr) {
return nil, NewHTTPError(http.StatusUnauthorized, perr.Error(), nil)
}
return nil, err
}
// If node is nil, it means an ephemeral node was deleted during logout
if node == nil {
h.Change(changed)
return nil, nil
}
// This is a bit of a back and forth, but we have a bit of a chicken and egg
// dependency here.
// Because the way the policy manager works, we need to have the node
@@ -195,17 +209,22 @@ func (h *Headscale) handleRegisterWithAuthKey(
// ensure we send an update.
// This works, but might be another good candidate for doing some sort of
// eventbus.
routesChanged := h.state.AutoApproveRoutes(node)
// TODO(kradalby): This needs to be ran as part of the batcher maybe?
// now since we dont update the node/pol here anymore
routeChange := h.state.AutoApproveRoutes(node)
if _, _, err := h.state.SaveNode(node); err != nil {
return nil, fmt.Errorf("saving auto approved routes to node: %w", err)
}
if routesChanged {
ctx := types.NotifyCtx(context.Background(), "node updated", node.Hostname)
h.nodeNotifier.NotifyAll(ctx, types.UpdatePeerChanged(node.ID))
} else if changed {
ctx := types.NotifyCtx(context.Background(), "node created", node.Hostname)
h.nodeNotifier.NotifyAll(ctx, types.UpdateFull())
if routeChange && changed.Empty() {
changed = change.NodeAdded(node.ID)
}
h.Change(changed)
// If policy changed due to node registration, send a separate policy change
if policyChanged {
policyChange := change.PolicyChange()
h.Change(policyChange)
}
return &tailcfg.RegisterResponse{

View File

@@ -1,17 +1,18 @@
package capver
//go:generate go run ../../tools/capver/main.go
import (
"slices"
"sort"
"strings"
"slices"
xmaps "golang.org/x/exp/maps"
"tailscale.com/tailcfg"
"tailscale.com/util/set"
)
const MinSupportedCapabilityVersion tailcfg.CapabilityVersion = 88
const MinSupportedCapabilityVersion tailcfg.CapabilityVersion = 90
// CanOldCodeBeCleanedUp is intended to be called on startup to see if
// there are old code that can ble cleaned up, entries should contain

View File

@@ -5,10 +5,6 @@ package capver
import "tailscale.com/tailcfg"
var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{
"v1.60.0": 87,
"v1.60.1": 87,
"v1.62.0": 88,
"v1.62.1": 88,
"v1.64.0": 90,
"v1.64.1": 90,
"v1.64.2": 90,
@@ -36,12 +32,13 @@ var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{
"v1.80.3": 113,
"v1.82.0": 115,
"v1.82.5": 115,
"v1.84.0": 116,
"v1.84.1": 116,
"v1.84.2": 116,
}
var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{
87: "v1.60.0",
88: "v1.62.0",
90: "v1.64.0",
95: "v1.66.0",
97: "v1.68.0",
@@ -51,4 +48,5 @@ var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{
109: "v1.78.0",
113: "v1.80.0",
115: "v1.82.0",
116: "v1.84.0",
}

View File

@@ -13,11 +13,10 @@ func TestTailscaleLatestMajorMinor(t *testing.T) {
stripV bool
expected []string
}{
{3, false, []string{"v1.78", "v1.80", "v1.82"}},
{2, true, []string{"1.80", "1.82"}},
{3, false, []string{"v1.80", "v1.82", "v1.84"}},
{2, true, []string{"1.82", "1.84"}},
// Lazy way to see all supported versions
{10, true, []string{
"1.64",
"1.66",
"1.68",
"1.70",
@@ -27,6 +26,7 @@ func TestTailscaleLatestMajorMinor(t *testing.T) {
"1.78",
"1.80",
"1.82",
"1.84",
}},
{0, false, nil},
}
@@ -46,7 +46,6 @@ func TestCapVerMinimumTailscaleVersion(t *testing.T) {
input tailcfg.CapabilityVersion
expected string
}{
{88, "v1.62.0"},
{90, "v1.64.0"},
{95, "v1.66.0"},
{106, "v1.74.0"},

View File

@@ -3,6 +3,7 @@ package db
import (
"context"
"database/sql"
_ "embed"
"encoding/json"
"errors"
"fmt"
@@ -15,9 +16,11 @@ import (
"github.com/glebarez/sqlite"
"github.com/go-gormigrate/gormigrate/v2"
"github.com/juanfont/headscale/hscontrol/db/sqliteconfig"
"github.com/juanfont/headscale/hscontrol/types"
"github.com/juanfont/headscale/hscontrol/util"
"github.com/rs/zerolog/log"
"github.com/tailscale/squibble"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
@@ -27,12 +30,23 @@ import (
"zgo.at/zcache/v2"
)
//go:embed schema.sql
var dbSchema string
func init() {
schema.RegisterSerializer("text", TextSerialiser{})
}
var errDatabaseNotSupported = errors.New("database type not supported")
var errForeignKeyConstraintsViolated = errors.New("foreign key constraints violated")
const (
maxIdleConns = 100
maxOpenConns = 100
contextTimeoutSecs = 10
)
// KV is a key-value store in a psql table. For future use...
// TODO(kradalby): Is this used for anything?
type KV struct {
@@ -471,6 +485,7 @@ func NewHeadscaleDatabase(
// Drop the old table.
_ = tx.Migrator().DropTable(&preAuthKeyACLTag{})
return nil
},
Rollback: func(db *gorm.DB) error { return nil },
@@ -481,7 +496,7 @@ func NewHeadscaleDatabase(
ID: "202407191627",
Migrate: func(tx *gorm.DB) error {
// Fix an issue where the automigration in GORM expected a constraint to
// exists that didnt, and add the one it wanted.
// exists that didn't, and add the one it wanted.
// Fixes https://github.com/juanfont/headscale/issues/2351
if cfg.Type == types.DatabasePostgres {
err := tx.Exec(`
@@ -602,7 +617,7 @@ COMMIT;
},
Rollback: func(db *gorm.DB) error { return nil },
},
// Ensure there are no nodes refering to a deleted preauthkey.
// Ensure there are no nodes referring to a deleted preauthkey.
{
ID: "202502070949",
Migrate: func(tx *gorm.DB) error {
@@ -718,6 +733,209 @@ AND auth_key_id NOT IN (
},
Rollback: func(db *gorm.DB) error { return nil },
},
// Schema migration to ensure all tables match the expected schema.
// This migration recreates all tables to match the exact structure in schema.sql,
// preserving all data during the process.
// Only SQLite will be migrated for consistency.
{
ID: "202507021200",
Migrate: func(tx *gorm.DB) error {
// Only run on SQLite
if cfg.Type != types.DatabaseSqlite {
log.Info().Msg("Skipping schema migration on non-SQLite database")
return nil
}
log.Info().Msg("Starting schema recreation with table renaming")
// Rename existing tables to _old versions
tablesToRename := []string{"users", "pre_auth_keys", "api_keys", "nodes", "policies"}
// Check if routes table exists and drop it (should have been migrated already)
var routesExists bool
err := tx.Raw("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='routes'").Row().Scan(&routesExists)
if err == nil && routesExists {
log.Info().Msg("Dropping leftover routes table")
if err := tx.Exec("DROP TABLE routes").Error; err != nil {
return fmt.Errorf("dropping routes table: %w", err)
}
}
// Drop all indexes first to avoid conflicts
indexesToDrop := []string{
"idx_users_deleted_at",
"idx_provider_identifier",
"idx_name_provider_identifier",
"idx_name_no_provider_identifier",
"idx_api_keys_prefix",
"idx_policies_deleted_at",
}
for _, index := range indexesToDrop {
_ = tx.Exec("DROP INDEX IF EXISTS " + index).Error
}
for _, table := range tablesToRename {
// Check if table exists before renaming
var exists bool
err := tx.Raw("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=?", table).Row().Scan(&exists)
if err != nil {
return fmt.Errorf("checking if table %s exists: %w", table, err)
}
if exists {
// Drop old table if it exists from previous failed migration
_ = tx.Exec("DROP TABLE IF EXISTS " + table + "_old").Error
// Rename current table to _old
if err := tx.Exec("ALTER TABLE " + table + " RENAME TO " + table + "_old").Error; err != nil {
return fmt.Errorf("renaming table %s to %s_old: %w", table, table, err)
}
}
}
// Create new tables with correct schema
tableCreationSQL := []string{
`CREATE TABLE users(
id integer PRIMARY KEY AUTOINCREMENT,
name text,
display_name text,
email text,
provider_identifier text,
provider text,
profile_pic_url text,
created_at datetime,
updated_at datetime,
deleted_at datetime
)`,
`CREATE TABLE pre_auth_keys(
id integer PRIMARY KEY AUTOINCREMENT,
key text,
user_id integer,
reusable numeric,
ephemeral numeric DEFAULT false,
used numeric DEFAULT false,
tags text,
expiration datetime,
created_at datetime,
CONSTRAINT fk_pre_auth_keys_user FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE SET NULL
)`,
`CREATE TABLE api_keys(
id integer PRIMARY KEY AUTOINCREMENT,
prefix text,
hash blob,
expiration datetime,
last_seen datetime,
created_at datetime
)`,
`CREATE TABLE nodes(
id integer PRIMARY KEY AUTOINCREMENT,
machine_key text,
node_key text,
disco_key text,
endpoints text,
host_info text,
ipv4 text,
ipv6 text,
hostname text,
given_name varchar(63),
user_id integer,
register_method text,
forced_tags text,
auth_key_id integer,
last_seen datetime,
expiry datetime,
approved_routes text,
created_at datetime,
updated_at datetime,
deleted_at datetime,
CONSTRAINT fk_nodes_user FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_nodes_auth_key FOREIGN KEY(auth_key_id) REFERENCES pre_auth_keys(id)
)`,
`CREATE TABLE policies(
id integer PRIMARY KEY AUTOINCREMENT,
data text,
created_at datetime,
updated_at datetime,
deleted_at datetime
)`,
}
for _, createSQL := range tableCreationSQL {
if err := tx.Exec(createSQL).Error; err != nil {
return fmt.Errorf("creating new table: %w", err)
}
}
// Copy data directly using SQL
dataCopySQL := []string{
`INSERT INTO users (id, name, display_name, email, provider_identifier, provider, profile_pic_url, created_at, updated_at, deleted_at)
SELECT id, name, display_name, email, provider_identifier, provider, profile_pic_url, created_at, updated_at, deleted_at
FROM users_old`,
`INSERT INTO pre_auth_keys (id, key, user_id, reusable, ephemeral, used, tags, expiration, created_at)
SELECT id, key, user_id, reusable, ephemeral, used, tags, expiration, created_at
FROM pre_auth_keys_old`,
`INSERT INTO api_keys (id, prefix, hash, expiration, last_seen, created_at)
SELECT id, prefix, hash, expiration, last_seen, created_at
FROM api_keys_old`,
`INSERT INTO nodes (id, machine_key, node_key, disco_key, endpoints, host_info, ipv4, ipv6, hostname, given_name, user_id, register_method, forced_tags, auth_key_id, last_seen, expiry, approved_routes, created_at, updated_at, deleted_at)
SELECT id, machine_key, node_key, disco_key, endpoints, host_info, ipv4, ipv6, hostname, given_name, user_id, register_method, forced_tags, auth_key_id, last_seen, expiry, approved_routes, created_at, updated_at, deleted_at
FROM nodes_old`,
`INSERT INTO policies (id, data, created_at, updated_at, deleted_at)
SELECT id, data, created_at, updated_at, deleted_at
FROM policies_old`,
}
for _, copySQL := range dataCopySQL {
if err := tx.Exec(copySQL).Error; err != nil {
return fmt.Errorf("copying data: %w", err)
}
}
// Create indexes
indexes := []string{
"CREATE INDEX idx_users_deleted_at ON users(deleted_at)",
`CREATE UNIQUE INDEX idx_provider_identifier ON users(
provider_identifier
) WHERE provider_identifier IS NOT NULL`,
`CREATE UNIQUE INDEX idx_name_provider_identifier ON users(
name,
provider_identifier
)`,
`CREATE UNIQUE INDEX idx_name_no_provider_identifier ON users(
name
) WHERE provider_identifier IS NULL`,
"CREATE UNIQUE INDEX idx_api_keys_prefix ON api_keys(prefix)",
"CREATE INDEX idx_policies_deleted_at ON policies(deleted_at)",
}
for _, indexSQL := range indexes {
if err := tx.Exec(indexSQL).Error; err != nil {
return fmt.Errorf("creating index: %w", err)
}
}
// Drop old tables only after everything succeeds
for _, table := range tablesToRename {
if err := tx.Exec("DROP TABLE IF EXISTS " + table + "_old").Error; err != nil {
log.Warn().Str("table", table+"_old").Err(err).Msg("Failed to drop old table, but migration succeeded")
}
}
log.Info().Msg("Schema recreation completed successfully")
return nil
},
Rollback: func(db *gorm.DB) error { return nil },
},
// From this point, the following rules must be followed:
// - NEVER use gorm.AutoMigrate, write the exact migration steps needed
// - AutoMigrate depends on the struct staying exactly the same, which it won't over time.
// - Never write migrations that requires foreign keys to be disabled.
},
)
@@ -725,6 +943,30 @@ AND auth_key_id NOT IN (
log.Fatal().Err(err).Msgf("Migration failed: %v", err)
}
// Validate that the schema ends up in the expected state.
// This is currently only done on sqlite as squibble does not
// support Postgres and we use our sqlite schema as our source of
// truth.
if cfg.Type == types.DatabaseSqlite {
sqlConn, err := dbConn.DB()
if err != nil {
return nil, fmt.Errorf("getting DB from gorm: %w", err)
}
// or else it blocks...
sqlConn.SetMaxIdleConns(maxIdleConns)
sqlConn.SetMaxOpenConns(maxOpenConns)
defer sqlConn.SetMaxIdleConns(1)
defer sqlConn.SetMaxOpenConns(1)
ctx, cancel := context.WithTimeout(context.Background(), contextTimeoutSecs*time.Second)
defer cancel()
if err := squibble.Validate(ctx, sqlConn, dbSchema); err != nil {
return nil, fmt.Errorf("validating schema: %w", err)
}
}
db := HSDatabase{
DB: dbConn,
cfg: &cfg,
@@ -758,32 +1000,26 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {
Str("path", cfg.Sqlite.Path).
Msg("Opening database")
// Build SQLite configuration with pragmas set at connection time
sqliteConfig := sqliteconfig.Default(cfg.Sqlite.Path)
if cfg.Sqlite.WriteAheadLog {
sqliteConfig.JournalMode = sqliteconfig.JournalModeWAL
sqliteConfig.WALAutocheckpoint = cfg.Sqlite.WALAutoCheckPoint
}
connectionURL, err := sqliteConfig.ToURL()
if err != nil {
return nil, fmt.Errorf("building sqlite connection URL: %w", err)
}
db, err := gorm.Open(
sqlite.Open(cfg.Sqlite.Path),
sqlite.Open(connectionURL),
&gorm.Config{
PrepareStmt: cfg.Gorm.PrepareStmt,
Logger: dbLogger,
},
)
if err := db.Exec(`
PRAGMA foreign_keys=ON;
PRAGMA busy_timeout=10000;
PRAGMA auto_vacuum=INCREMENTAL;
PRAGMA synchronous=NORMAL;
`).Error; err != nil {
return nil, fmt.Errorf("enabling foreign keys: %w", err)
}
if cfg.Sqlite.WriteAheadLog {
if err := db.Exec(fmt.Sprintf(`
PRAGMA journal_mode=WAL;
PRAGMA wal_autocheckpoint=%d;
`, cfg.Sqlite.WALAutoCheckPoint)).Error; err != nil {
return nil, fmt.Errorf("setting WAL mode: %w", err)
}
}
// The pure Go SQLite library does not handle locking in
// the same way as the C based one and we can't use the gorm
// connection pool as of 2022/02/23.
@@ -812,7 +1048,7 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {
dbString += " sslmode=disable"
}
} else {
dbString += fmt.Sprintf(" sslmode=%s", cfg.Postgres.Ssl)
dbString += " sslmode=" + cfg.Postgres.Ssl
}
if cfg.Postgres.Port != 0 {
@@ -820,7 +1056,7 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {
}
if cfg.Postgres.Pass != "" {
dbString += fmt.Sprintf(" password=%s", cfg.Postgres.Pass)
dbString += " password=" + cfg.Postgres.Pass
}
db, err := gorm.Open(postgres.Open(dbString), &gorm.Config{
@@ -848,29 +1084,84 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {
}
func runMigrations(cfg types.DatabaseConfig, dbConn *gorm.DB, migrations *gormigrate.Gormigrate) error {
// Turn off foreign keys for the duration of the migration if using sqlite to
// prevent data loss due to the way the GORM migrator handles certain schema
// changes.
if cfg.Type == types.DatabaseSqlite {
var fkEnabled int
if err := dbConn.Raw("PRAGMA foreign_keys").Scan(&fkEnabled).Error; err != nil {
// SQLite: Run migrations step-by-step, only disabling foreign keys when necessary
// List of migration IDs that require foreign keys to be disabled
// These are migrations that perform complex schema changes that GORM cannot handle safely with FK enabled
// NO NEW MIGRATIONS SHOULD BE ADDED HERE. ALL NEW MIGRATIONS MUST RUN WITH FOREIGN KEYS ENABLED.
migrationsRequiringFKDisabled := map[string]bool{
"202312101416": true, // Initial migration with complex table/column renames
"202402151347": true, // Migration that removes last_successful_update column
"2024041121742": true, // Migration that changes IP address storage format
"202407191627": true, // User table automigration with FK constraint issues
"202408181235": true, // User table automigration with FK constraint issues
"202501221827": true, // Route table automigration with FK constraint issues
"202501311657": true, // PreAuthKey table automigration with FK constraint issues
// Add other migration IDs here as they are identified to need FK disabled
}
// Get the current foreign key status
var fkOriginallyEnabled int
if err := dbConn.Raw("PRAGMA foreign_keys").Scan(&fkOriginallyEnabled).Error; err != nil {
return fmt.Errorf("checking foreign key status: %w", err)
}
if fkEnabled == 1 {
if err := dbConn.Exec("PRAGMA foreign_keys = OFF").Error; err != nil {
return fmt.Errorf("disabling foreign keys: %w", err)
}
defer dbConn.Exec("PRAGMA foreign_keys = ON")
// Get all migration IDs in order from the actual migration definitions
// Only IDs that are in the migrationsRequiringFKDisabled map will be processed with FK disabled
// any other new migrations are ran after.
migrationIDs := []string{
"202312101416",
"202312101430",
"202402151347",
"2024041121742",
"202406021630",
"202407191627",
"202408181235",
"202409271400",
"202501221827",
"202501311657",
"202502070949",
"202502131714",
"202502171819",
"202505091439",
"202505141324",
// As of 2025-07-02, no new IDs should be added here.
// They will be ran by the migrations.Migrate() call below.
}
}
if err := migrations.Migrate(); err != nil {
return err
}
for _, migrationID := range migrationIDs {
log.Trace().Str("migration_id", migrationID).Msg("Running migration")
needsFKDisabled := migrationsRequiringFKDisabled[migrationID]
// Since we disabled foreign keys for the migration, we need to check for
// constraint violations manually at the end of the migration.
if cfg.Type == types.DatabaseSqlite {
if needsFKDisabled {
// Disable foreign keys for this migration
if err := dbConn.Exec("PRAGMA foreign_keys = OFF").Error; err != nil {
return fmt.Errorf("disabling foreign keys for migration %s: %w", migrationID, err)
}
} else {
// Ensure foreign keys are enabled for this migration
if err := dbConn.Exec("PRAGMA foreign_keys = ON").Error; err != nil {
return fmt.Errorf("enabling foreign keys for migration %s: %w", migrationID, err)
}
}
// Run up to this specific migration (will only run the next pending migration)
if err := migrations.MigrateTo(migrationID); err != nil {
return fmt.Errorf("running migration %s: %w", migrationID, err)
}
}
if err := dbConn.Exec("PRAGMA foreign_keys = ON").Error; err != nil {
return fmt.Errorf("restoring foreign keys: %w", err)
}
// Run the rest of the migrations
if err := migrations.Migrate(); err != nil {
return err
}
// Check for constraint violations at the end
type constraintViolation struct {
Table string
RowID int
@@ -904,7 +1195,12 @@ func runMigrations(cfg types.DatabaseConfig, dbConn *gorm.DB, migrations *gormig
Msg("Foreign key constraint violated")
}
return fmt.Errorf("foreign key constraints violated")
return errForeignKeyConstraintsViolated
}
} else {
// PostgreSQL can run all migrations in one block - no foreign key issues
if err := migrations.Migrate(); err != nil {
return err
}
}
@@ -949,6 +1245,7 @@ func Read[T any](db *gorm.DB, fn func(rx *gorm.DB) (T, error)) (T, error) {
var no T
return no, err
}
return ret, nil
}
@@ -970,5 +1267,6 @@ func Write[T any](db *gorm.DB, fn func(tx *gorm.DB) (T, error)) (T, error) {
var no T
return no, err
}
return ret, tx.Commit().Error
}

View File

@@ -2,14 +2,11 @@ package db
import (
"database/sql"
"fmt"
"io"
"net/netip"
"os"
"os/exec"
"path/filepath"
"slices"
"sort"
"strings"
"testing"
"time"
@@ -24,10 +21,10 @@ import (
"zgo.at/zcache/v2"
)
// TestMigrationsSQLite is the main function for testing migrations,
// we focus on SQLite correctness as it is the main database used in headscale.
// All migrations that are worth testing should be added here.
func TestMigrationsSQLite(t *testing.T) {
// TestSQLiteMigrationAndDataValidation tests specific SQLite migration scenarios
// and validates data integrity after migration. All migrations that require data validation
// should be added here.
func TestSQLiteMigrationAndDataValidation(t *testing.T) {
ipp := func(p string) netip.Prefix {
return netip.MustParsePrefix(p)
}
@@ -43,12 +40,39 @@ func TestMigrationsSQLite(t *testing.T) {
tests := []struct {
dbPath string
wantFunc func(*testing.T, *HSDatabase)
wantErr string
}{
{
dbPath: "testdata/0-22-3-to-0-23-0-routes-are-dropped-2063.sqlite",
wantFunc: func(t *testing.T, h *HSDatabase) {
nodes, err := Read(h.DB, func(rx *gorm.DB) (types.Nodes, error) {
dbPath: "testdata/sqlite/0-22-3-to-0-23-0-routes-are-dropped-2063_dump.sql",
wantFunc: func(t *testing.T, hsdb *HSDatabase) {
t.Helper()
// Comprehensive data preservation validation for 0.22.3->0.23.0 migration
// Expected data from dump: 4 users, 17 pre_auth_keys, 14 machines/nodes, 12 routes
// Verify users data preservation - should have 4 users
users, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.User, error) {
return ListUsers(rx)
})
require.NoError(t, err)
assert.Len(t, users, 4, "should preserve all 4 users from original schema")
// Verify pre_auth_keys data preservation - should have 17 keys
preAuthKeys, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.PreAuthKey, error) {
var keys []types.PreAuthKey
err := rx.Find(&keys).Error
return keys, err
})
require.NoError(t, err)
assert.Len(t, preAuthKeys, 17, "should preserve all 17 pre_auth_keys from original schema")
// Verify all nodes data preservation - should have 14 nodes
allNodes, err := Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) {
return ListNodes(rx)
})
require.NoError(t, err)
assert.Len(t, allNodes, 14, "should preserve all 14 machines/nodes from original schema")
// Verify specific nodes and their route migration with detailed validation
nodes, err := Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) {
n1, err := GetNodeByID(rx, 1)
n26, err := GetNodeByID(rx, 26)
n31, err := GetNodeByID(rx, 31)
@@ -60,24 +84,66 @@ func TestMigrationsSQLite(t *testing.T) {
return types.Nodes{n1, n26, n31, n32}, nil
})
require.NoError(t, err)
assert.Len(t, nodes, 4, "should have retrieved 4 specific nodes")
// want := types.Routes{
// r(1, "0.0.0.0/0", true, false),
// r(1, "::/0", true, false),
// r(1, "10.9.110.0/24", true, true),
// r(26, "172.100.100.0/24", true, true),
// r(26, "172.100.100.0/24", true, false, false),
// r(31, "0.0.0.0/0", true, false),
// r(31, "0.0.0.0/0", true, false, false),
// r(31, "::/0", true, false),
// r(31, "::/0", true, false, false),
// r(32, "192.168.0.24/32", true, true),
// }
// Validate specific node data from dump file
nodesByID := make(map[uint64]*types.Node)
for i := range nodes {
nodesByID[nodes[i].ID.Uint64()] = nodes[i]
}
node1 := nodesByID[1]
node26 := nodesByID[26]
node31 := nodesByID[31]
node32 := nodesByID[32]
require.NotNil(t, node1, "node 1 should exist")
require.NotNil(t, node26, "node 26 should exist")
require.NotNil(t, node31, "node 31 should exist")
require.NotNil(t, node32, "node 32 should exist")
// Validate node data using cmp.Diff
expectedNodes := map[uint64]struct {
Hostname string
GivenName string
IPv4 string
}{
1: {Hostname: "test_hostname", GivenName: "test_given_name", IPv4: "100.64.0.1"},
26: {Hostname: "test_hostname", GivenName: "test_given_name", IPv4: "100.64.0.19"},
31: {Hostname: "test_hostname", GivenName: "test_given_name", IPv4: "100.64.0.7"},
32: {Hostname: "test_hostname", GivenName: "test_given_name", IPv4: "100.64.0.11"},
}
for nodeID, expected := range expectedNodes {
node := nodesByID[nodeID]
require.NotNil(t, node, "node %d should exist", nodeID)
actual := struct {
Hostname string
GivenName string
IPv4 string
}{
Hostname: node.Hostname,
GivenName: node.GivenName,
IPv4: node.IPv4.String(),
}
if diff := cmp.Diff(expected, actual); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() node %d mismatch (-want +got):\n%s", nodeID, diff)
}
}
// Validate that routes were properly migrated from routes table to approved_routes
// Based on the dump file routes data:
// Node 1 (machine_id 1): routes 1,2,3 (0.0.0.0/0 enabled, ::/0 enabled, 10.9.110.0/24 enabled+primary)
// Node 26 (machine_id 26): route 6 (172.100.100.0/24 enabled+primary), route 7 (172.100.100.0/24 disabled)
// Node 31 (machine_id 31): routes 8,10 (0.0.0.0/0 enabled, ::/0 enabled), routes 9,11 (duplicates disabled)
// Node 32 (machine_id 32): route 12 (192.168.0.24/32 enabled+primary)
want := [][]netip.Prefix{
{ipp("0.0.0.0/0"), ipp("10.9.110.0/24"), ipp("::/0")},
{ipp("172.100.100.0/24")},
{ipp("0.0.0.0/0"), ipp("::/0")},
{ipp("192.168.0.24/32")},
{ipp("0.0.0.0/0"), ipp("10.9.110.0/24"), ipp("::/0")}, // node 1: 3 enabled routes
{ipp("172.100.100.0/24")}, // node 26: 1 enabled route
{ipp("0.0.0.0/0"), ipp("::/0")}, // node 31: 2 enabled routes
{ipp("192.168.0.24/32")}, // node 32: 1 enabled route
}
var got [][]netip.Prefix
for _, node := range nodes {
@@ -85,14 +151,48 @@ func TestMigrationsSQLite(t *testing.T) {
}
if diff := cmp.Diff(want, got, util.PrefixComparer); diff != "" {
t.Errorf("TestMigrations() mismatch (-want +got):\n%s", diff)
t.Errorf("TestSQLiteMigrationAndDataValidation() route migration mismatch (-want +got):\n%s", diff)
}
// Verify routes table was dropped after migration
var routesTableExists bool
err = hsdb.DB.Raw("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='routes'").Row().Scan(&routesTableExists)
require.NoError(t, err)
assert.False(t, routesTableExists, "routes table should have been dropped after migration")
},
},
{
dbPath: "testdata/0-22-3-to-0-23-0-routes-fail-foreign-key-2076.sqlite",
wantFunc: func(t *testing.T, h *HSDatabase) {
node, err := Read(h.DB, func(rx *gorm.DB) (*types.Node, error) {
dbPath: "testdata/sqlite/0-22-3-to-0-23-0-routes-fail-foreign-key-2076_dump.sql",
wantFunc: func(t *testing.T, hsdb *HSDatabase) {
t.Helper()
// Comprehensive data preservation validation for foreign key constraint issue case
// Expected data from dump: 4 users, 2 pre_auth_keys, 8 nodes
// Verify users data preservation
users, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.User, error) {
return ListUsers(rx)
})
require.NoError(t, err)
assert.Len(t, users, 4, "should preserve all 4 users from original schema")
// Verify pre_auth_keys data preservation
preAuthKeys, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.PreAuthKey, error) {
var keys []types.PreAuthKey
err := rx.Find(&keys).Error
return keys, err
})
require.NoError(t, err)
assert.Len(t, preAuthKeys, 2, "should preserve all 2 pre_auth_keys from original schema")
// Verify all nodes data preservation
allNodes, err := Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) {
return ListNodes(rx)
})
require.NoError(t, err)
assert.Len(t, allNodes, 8, "should preserve all 8 nodes from original schema")
// Verify specific node route migration
node, err := Read(hsdb.DB, func(rx *gorm.DB) (*types.Node, error) {
return GetNodeByID(rx, 13)
})
require.NoError(t, err)
@@ -101,26 +201,26 @@ func TestMigrationsSQLite(t *testing.T) {
_ = types.Routes{
// These routes exists, but have no nodes associated with them
// when the migration starts.
// r(1, "0.0.0.0/0", true, true, false),
// r(1, "::/0", true, true, false),
// r(3, "0.0.0.0/0", true, true, false),
// r(3, "::/0", true, true, false),
// r(5, "0.0.0.0/0", true, true, false),
// r(5, "::/0", true, true, false),
// r(6, "0.0.0.0/0", true, true, false),
// r(6, "::/0", true, true, false),
// r(1, "0.0.0.0/0", true, false),
// r(1, "::/0", true, false),
// r(3, "0.0.0.0/0", true, false),
// r(3, "::/0", true, false),
// r(5, "0.0.0.0/0", true, false),
// r(5, "::/0", true, false),
// r(6, "0.0.0.0/0", true, false),
// r(6, "::/0", true, false),
// r(6, "10.0.0.0/8", true, false, false),
// r(7, "0.0.0.0/0", true, true, false),
// r(7, "::/0", true, true, false),
// r(7, "0.0.0.0/0", true, false),
// r(7, "::/0", true, false),
// r(7, "10.0.0.0/8", true, false, false),
// r(9, "0.0.0.0/0", true, true, false),
// r(9, "::/0", true, true, false),
// r(9, "10.0.0.0/8", true, true, false),
// r(11, "0.0.0.0/0", true, true, false),
// r(11, "::/0", true, true, false),
// r(11, "10.0.0.0/8", true, true, true),
// r(12, "0.0.0.0/0", true, true, false),
// r(12, "::/0", true, true, false),
// r(9, "0.0.0.0/0", true, false),
// r(9, "::/0", true, false),
// r(9, "10.0.0.0/8", true, false),
// r(11, "0.0.0.0/0", true, false),
// r(11, "::/0", true, false),
// r(11, "10.0.0.0/8", true, true),
// r(12, "0.0.0.0/0", true, false),
// r(12, "::/0", true, false),
// r(12, "10.0.0.0/8", true, false, false),
//
// These nodes exists, so routes should be kept.
@@ -131,8 +231,14 @@ func TestMigrationsSQLite(t *testing.T) {
}
want := []netip.Prefix{ipp("0.0.0.0/0"), ipp("10.18.80.2/32"), ipp("::/0")}
if diff := cmp.Diff(want, node.ApprovedRoutes, util.PrefixComparer); diff != "" {
t.Errorf("TestMigrations() mismatch (-want +got):\n%s", diff)
t.Errorf("TestSQLiteMigrationAndDataValidation() route migration mismatch (-want +got):\n%s", diff)
}
// Verify routes table was dropped after migration
var routesTableExists bool
err = hsdb.DB.Raw("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='routes'").Row().Scan(&routesTableExists)
require.NoError(t, err)
assert.False(t, routesTableExists, "routes table should have been dropped after migration")
},
},
// at 14:15:06 go run ./cmd/headscale preauthkeys list
@@ -143,9 +249,49 @@ func TestMigrationsSQLite(t *testing.T) {
// 4 | f20155.. | false | false | false | 2024-09-27 | 2024-09-27 | tag:test
// 5 | b212b9.. | false | false | false | 2024-09-27 | 2024-09-27 | tag:test,tag:woop,tag:dedu
{
dbPath: "testdata/0-23-0-to-0-24-0-preauthkey-tags-table.sqlite",
wantFunc: func(t *testing.T, h *HSDatabase) {
keys, err := Read(h.DB, func(rx *gorm.DB) ([]types.PreAuthKey, error) {
dbPath: "testdata/sqlite/0-23-0-to-0-24-0-preauthkey-tags-table_dump.sql",
wantFunc: func(t *testing.T, hsdb *HSDatabase) {
t.Helper()
// Comprehensive data preservation validation for pre-auth key tags migration
// Expected data from dump: 2 users (kratest, testkra), 5 pre_auth_keys with specific tags
// Verify users data preservation with specific user data
users, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.User, error) {
return ListUsers(rx)
})
require.NoError(t, err)
assert.Len(t, users, 2, "should preserve all 2 users from original schema")
// Validate specific user data from dump file using cmp.Diff
expectedUsers := []types.User{
{Model: gorm.Model{ID: 1}, Name: "kratest"},
{Model: gorm.Model{ID: 2}, Name: "testkra"},
}
if diff := cmp.Diff(expectedUsers, users,
cmpopts.IgnoreFields(types.User{}, "CreatedAt", "UpdatedAt", "DeletedAt", "DisplayName", "Email", "ProviderIdentifier", "Provider", "ProfilePicURL")); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() users mismatch (-want +got):\n%s", diff)
}
// Create maps for easier access in later validations
usersByName := make(map[string]*types.User)
for i := range users {
usersByName[users[i].Name] = &users[i]
}
kratest := usersByName["kratest"]
testkra := usersByName["testkra"]
// Verify all pre_auth_keys data preservation
allKeys, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.PreAuthKey, error) {
var keys []types.PreAuthKey
err := rx.Find(&keys).Error
return keys, err
})
require.NoError(t, err)
assert.Len(t, allKeys, 5, "should preserve all 5 pre_auth_keys from original schema")
// Verify specific pre-auth keys and their tag migration with exact data validation
keys, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.PreAuthKey, error) {
kratest, err := ListPreAuthKeysByUser(rx, 1) // kratest
if err != nil {
return nil, err
@@ -159,51 +305,104 @@ func TestMigrationsSQLite(t *testing.T) {
return append(kratest, testkra...), nil
})
require.NoError(t, err)
assert.Len(t, keys, 5)
want := []types.PreAuthKey{
// Create map for easier validation by ID
keysByID := make(map[uint64]*types.PreAuthKey)
for i := range keys {
keysByID[keys[i].ID] = &keys[i]
}
// Validate specific pre-auth key data and tag migration from pre_auth_key_acl_tags table
key1 := keysByID[1]
key2 := keysByID[2]
key3 := keysByID[3]
key4 := keysByID[4]
key5 := keysByID[5]
require.NotNil(t, key1, "pre_auth_key 1 should exist")
require.NotNil(t, key2, "pre_auth_key 2 should exist")
require.NotNil(t, key3, "pre_auth_key 3 should exist")
require.NotNil(t, key4, "pre_auth_key 4 should exist")
require.NotNil(t, key5, "pre_auth_key 5 should exist")
// Validate specific pre-auth key data and tag migration using cmp.Diff
expectedKeys := []types.PreAuthKey{
{
ID: 1,
Tags: []string{"tag:derp"},
ID: 1,
Key: "09b28f8c3351984874d46dace0a70177a8721933a950b663",
UserID: kratest.ID,
Tags: []string{"tag:derp"},
},
{
ID: 2,
Tags: []string{"tag:derp"},
ID: 2,
Key: "3112b953cb344191b2d5aec1b891250125bf7b437eac5d26",
UserID: kratest.ID,
Tags: []string{"tag:derp"},
},
{
ID: 3,
Tags: []string{"tag:derp", "tag:merp"},
ID: 3,
Key: "7c23b9f215961e7609527aef78bf82fb19064b002d78c36f",
UserID: kratest.ID,
Tags: []string{"tag:derp", "tag:merp"},
},
{
ID: 4,
Tags: []string{"tag:test"},
ID: 4,
Key: "f2015583852b725220cc4b107fb288a4cf7ac259bd458a32",
UserID: testkra.ID,
Tags: []string{"tag:test"},
},
{
ID: 5,
Tags: []string{"tag:test", "tag:woop", "tag:dedu"},
ID: 5,
Key: "b212b990165e897944dd3772786544402729fb349da50f57",
UserID: testkra.ID,
Tags: []string{"tag:test", "tag:woop", "tag:dedu"},
},
}
if diff := cmp.Diff(want, keys, cmp.Comparer(func(a, b []string) bool {
sort.Sort(sort.StringSlice(a))
sort.Sort(sort.StringSlice(b))
if diff := cmp.Diff(expectedKeys, keys, cmp.Comparer(func(a, b []string) bool {
slices.Sort(a)
slices.Sort(b)
return slices.Equal(a, b)
}), cmpopts.IgnoreFields(types.PreAuthKey{}, "Key", "UserID", "User", "CreatedAt", "Expiration")); diff != "" {
t.Errorf("TestMigrations() mismatch (-want +got):\n%s", diff)
}), cmpopts.IgnoreFields(types.PreAuthKey{}, "User", "CreatedAt", "Reusable", "Ephemeral", "Used", "Expiration")); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() pre-auth key tags migration mismatch (-want +got):\n%s", diff)
}
if h.DB.Migrator().HasTable("pre_auth_key_acl_tags") {
t.Errorf("TestMigrations() table pre_auth_key_acl_tags should not exist")
// Verify pre_auth_key_acl_tags table was dropped after migration
if hsdb.DB.Migrator().HasTable("pre_auth_key_acl_tags") {
t.Errorf("TestSQLiteMigrationAndDataValidation() table pre_auth_key_acl_tags should not exist after migration")
}
},
},
{
dbPath: "testdata/0-23-0-to-0-24-0-no-more-special-types.sqlite",
wantFunc: func(t *testing.T, h *HSDatabase) {
nodes, err := Read(h.DB, func(rx *gorm.DB) (types.Nodes, error) {
dbPath: "testdata/sqlite/0-23-0-to-0-24-0-no-more-special-types_dump.sql",
wantFunc: func(t *testing.T, hsdb *HSDatabase) {
t.Helper()
// Comprehensive data preservation validation for special types removal migration
// Expected data from dump: 2 users, 2 pre_auth_keys, 12 nodes
// Verify users data preservation
users, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.User, error) {
return ListUsers(rx)
})
require.NoError(t, err)
assert.Len(t, users, 2, "should preserve all 2 users from original schema")
// Verify pre_auth_keys data preservation
preAuthKeys, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.PreAuthKey, error) {
var keys []types.PreAuthKey
err := rx.Find(&keys).Error
return keys, err
})
require.NoError(t, err)
assert.Len(t, preAuthKeys, 2, "should preserve all 2 pre_auth_keys from original schema")
// Verify nodes data preservation and field validation
nodes, err := Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) {
return ListNodes(rx)
})
require.NoError(t, err)
assert.Len(t, nodes, 12, "should preserve all 12 nodes from original schema")
for _, node := range nodes {
assert.Falsef(t, node.MachineKey.IsZero(), "expected non zero machinekey")
@@ -213,7 +412,7 @@ func TestMigrationsSQLite(t *testing.T) {
assert.Falsef(t, node.DiscoKey.IsZero(), "expected non zero discokey")
assert.Contains(t, node.DiscoKey.String(), "discokey:")
assert.NotNil(t, node.IPv4)
assert.NotNil(t, node.IPv4)
assert.NotNil(t, node.IPv6)
assert.Len(t, node.Endpoints, 1)
assert.NotNil(t, node.Hostinfo)
assert.NotNil(t, node.MachineKey)
@@ -221,12 +420,31 @@ func TestMigrationsSQLite(t *testing.T) {
},
},
{
dbPath: "testdata/failing-node-preauth-constraint.sqlite",
wantFunc: func(t *testing.T, h *HSDatabase) {
nodes, err := Read(h.DB, func(rx *gorm.DB) (types.Nodes, error) {
dbPath: "testdata/sqlite/failing-node-preauth-constraint_dump.sql",
wantFunc: func(t *testing.T, hsdb *HSDatabase) {
t.Helper()
// Comprehensive data preservation validation for node-preauth constraint issue
// Expected data from dump: 1 user, 2 api_keys, 6 nodes
// Verify users data preservation
users, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.User, error) {
return ListUsers(rx)
})
require.NoError(t, err)
assert.Len(t, users, 1, "should preserve all 1 user from original schema")
// Verify api_keys data preservation
var apiKeyCount int
err = hsdb.DB.Raw("SELECT COUNT(*) FROM api_keys").Scan(&apiKeyCount).Error
require.NoError(t, err)
assert.Equal(t, 2, apiKeyCount, "should preserve all 2 api_keys from original schema")
// Verify nodes data preservation and field validation
nodes, err := Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) {
return ListNodes(rx)
})
require.NoError(t, err)
assert.Len(t, nodes, 6, "should preserve all 6 nodes from original schema")
for _, node := range nodes {
assert.Falsef(t, node.MachineKey.IsZero(), "expected non zero machinekey")
@@ -240,25 +458,262 @@ func TestMigrationsSQLite(t *testing.T) {
}
},
},
{
dbPath: "testdata/sqlite/wrongly-migrated-schema-0.25.1_dump.sql",
wantFunc: func(t *testing.T, hsdb *HSDatabase) {
t.Helper()
// Test migration of a database that was wrongly migrated in 0.25.1
// This database has several issues:
// 1. Missing proper user unique constraints (idx_provider_identifier, idx_name_provider_identifier, idx_name_no_provider_identifier)
// 2. Still has routes table that should have been migrated to node.approved_routes
// 3. Wrong FOREIGN KEY constraint on pre_auth_keys (CASCADE instead of SET NULL)
// 4. Missing some required indexes
// Verify users table data is preserved with specific user data
users, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.User, error) {
return ListUsers(rx)
})
require.NoError(t, err)
assert.Len(t, users, 2, "should preserve existing users")
// Validate specific user data from dump file using cmp.Diff
expectedUsers := []types.User{
{Model: gorm.Model{ID: 1}, Name: "user2"},
{Model: gorm.Model{ID: 2}, Name: "user1"},
}
if diff := cmp.Diff(expectedUsers, users,
cmpopts.IgnoreFields(types.User{}, "CreatedAt", "UpdatedAt", "DeletedAt", "DisplayName", "Email", "ProviderIdentifier", "Provider", "ProfilePicURL")); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() users mismatch (-want +got):\n%s", diff)
}
// Create maps for easier access in later validations
usersByName := make(map[string]*types.User)
for i := range users {
usersByName[users[i].Name] = &users[i]
}
user1 := usersByName["user1"]
user2 := usersByName["user2"]
// Verify nodes table data is preserved and routes migrated to approved_routes
nodes, err := Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) {
return ListNodes(rx)
})
require.NoError(t, err)
assert.Len(t, nodes, 3, "should preserve existing nodes")
// Validate specific node data from dump file
nodesByID := make(map[uint64]*types.Node)
for i := range nodes {
nodesByID[nodes[i].ID.Uint64()] = nodes[i]
}
node1 := nodesByID[1]
node2 := nodesByID[2]
node3 := nodesByID[3]
require.NotNil(t, node1, "node 1 should exist")
require.NotNil(t, node2, "node 2 should exist")
require.NotNil(t, node3, "node 3 should exist")
// Validate specific node field data using cmp.Diff
expectedNodes := map[uint64]struct {
Hostname string
GivenName string
IPv4 string
IPv6 string
UserID uint
}{
1: {Hostname: "node1", GivenName: "node1", IPv4: "100.64.0.1", IPv6: "fd7a:115c:a1e0::1", UserID: user2.ID},
2: {Hostname: "node2", GivenName: "node2", IPv4: "100.64.0.2", IPv6: "fd7a:115c:a1e0::2", UserID: user2.ID},
3: {Hostname: "node3", GivenName: "node3", IPv4: "100.64.0.3", IPv6: "fd7a:115c:a1e0::3", UserID: user1.ID},
}
for nodeID, expected := range expectedNodes {
node := nodesByID[nodeID]
require.NotNil(t, node, "node %d should exist", nodeID)
actual := struct {
Hostname string
GivenName string
IPv4 string
IPv6 string
UserID uint
}{
Hostname: node.Hostname,
GivenName: node.GivenName,
IPv4: node.IPv4.String(),
IPv6: func() string {
if node.IPv6 != nil {
return node.IPv6.String()
} else {
return ""
}
}(),
UserID: node.UserID,
}
if diff := cmp.Diff(expected, actual); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() node %d basic fields mismatch (-want +got):\n%s", nodeID, diff)
}
// Special validation for MachineKey content for node 1 only
if nodeID == 1 {
assert.Contains(t, node.MachineKey.String(), "mkey:1efe4388236c1c83fe0a19d3ce7c321ab81e138a4da57917c231ce4c01944409")
}
}
// Check that routes were migrated from routes table to node.approved_routes using cmp.Diff
// Original routes table had 4 routes for nodes 1, 2, 3:
// Node 1: 0.0.0.0/0 (enabled), ::/0 (enabled) -> should have 2 approved routes
// Node 2: 192.168.100.0/24 (enabled) -> should have 1 approved route
// Node 3: 10.0.0.0/8 (disabled) -> should have 0 approved routes
expectedRoutes := map[uint64][]netip.Prefix{
1: {netip.MustParsePrefix("0.0.0.0/0"), netip.MustParsePrefix("::/0")},
2: {netip.MustParsePrefix("192.168.100.0/24")},
3: nil,
}
actualRoutes := map[uint64][]netip.Prefix{
1: node1.ApprovedRoutes,
2: node2.ApprovedRoutes,
3: node3.ApprovedRoutes,
}
if diff := cmp.Diff(expectedRoutes, actualRoutes, util.PrefixComparer); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() routes migration mismatch (-want +got):\n%s", diff)
}
// Verify pre_auth_keys data is preserved with specific key data
preAuthKeys, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.PreAuthKey, error) {
var keys []types.PreAuthKey
err := rx.Find(&keys).Error
return keys, err
})
require.NoError(t, err)
assert.Len(t, preAuthKeys, 2, "should preserve existing pre_auth_keys")
// Validate specific pre_auth_key data from dump file using cmp.Diff
expectedKeys := []types.PreAuthKey{
{
ID: 1,
Key: "3d133ec953e31fd41edbd935371234f762b4bae300cea618",
UserID: user2.ID,
Reusable: true,
Used: true,
},
{
ID: 2,
Key: "9813cc1df1832259fb6322dad788bb9bec89d8a01eef683a",
UserID: user1.ID,
Reusable: true,
Used: true,
},
}
if diff := cmp.Diff(expectedKeys, preAuthKeys,
cmpopts.IgnoreFields(types.PreAuthKey{}, "User", "CreatedAt", "Expiration", "Ephemeral", "Tags")); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() pre_auth_keys mismatch (-want +got):\n%s", diff)
}
// Verify api_keys data is preserved with specific key data
var apiKeys []struct {
ID uint64
Prefix string
Hash []byte
CreatedAt string
Expiration string
LastSeen string
}
err = hsdb.DB.Raw("SELECT id, prefix, hash, created_at, expiration, last_seen FROM api_keys").Scan(&apiKeys).Error
require.NoError(t, err)
assert.Len(t, apiKeys, 1, "should preserve existing api_keys")
// Validate specific api_key data from dump file using cmp.Diff
expectedAPIKey := struct {
ID uint64
Prefix string
Hash []byte
}{
ID: 1,
Prefix: "ak_test",
Hash: []byte{0xde, 0xad, 0xbe, 0xef},
}
actualAPIKey := struct {
ID uint64
Prefix string
Hash []byte
}{
ID: apiKeys[0].ID,
Prefix: apiKeys[0].Prefix,
Hash: apiKeys[0].Hash,
}
if diff := cmp.Diff(expectedAPIKey, actualAPIKey); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() api_key mismatch (-want +got):\n%s", diff)
}
// Validate date fields separately since they need Contains check
assert.Contains(t, apiKeys[0].CreatedAt, "2025-12-31", "created_at should be preserved")
assert.Contains(t, apiKeys[0].Expiration, "2025-06-18", "expiration should be preserved")
// Verify that routes table no longer exists (should have been dropped)
var routesTableExists bool
err = hsdb.DB.Raw("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='routes'").Row().Scan(&routesTableExists)
require.NoError(t, err)
assert.False(t, routesTableExists, "routes table should have been dropped")
// Verify all required indexes exist with correct structure using cmp.Diff
expectedIndexes := []string{
"idx_users_deleted_at",
"idx_provider_identifier",
"idx_name_provider_identifier",
"idx_name_no_provider_identifier",
"idx_api_keys_prefix",
"idx_policies_deleted_at",
}
expectedIndexMap := make(map[string]bool)
for _, index := range expectedIndexes {
expectedIndexMap[index] = true
}
actualIndexMap := make(map[string]bool)
for _, indexName := range expectedIndexes {
var indexExists bool
err = hsdb.DB.Raw("SELECT COUNT(*) FROM sqlite_master WHERE type='index' AND name=?", indexName).Row().Scan(&indexExists)
require.NoError(t, err)
actualIndexMap[indexName] = indexExists
}
if diff := cmp.Diff(expectedIndexMap, actualIndexMap); diff != "" {
t.Errorf("TestSQLiteMigrationAndDataValidation() indexes existence mismatch (-want +got):\n%s", diff)
}
// Verify proper foreign key constraints are set
// Check that pre_auth_keys has correct FK constraint (SET NULL, not CASCADE)
var preAuthKeyConstraint string
err = hsdb.DB.Raw("SELECT sql FROM sqlite_master WHERE type='table' AND name='pre_auth_keys'").Row().Scan(&preAuthKeyConstraint)
require.NoError(t, err)
assert.Contains(t, preAuthKeyConstraint, "ON DELETE SET NULL", "pre_auth_keys should have SET NULL constraint")
assert.NotContains(t, preAuthKeyConstraint, "ON DELETE CASCADE", "pre_auth_keys should not have CASCADE constraint")
// Verify that user unique constraints work properly
// Try to create duplicate local user (should fail)
err = hsdb.DB.Create(&types.User{Name: users[0].Name}).Error
require.Error(t, err, "should not allow duplicate local usernames")
assert.Contains(t, err.Error(), "UNIQUE constraint", "should fail with unique constraint error")
},
},
}
for _, tt := range tests {
t.Run(tt.dbPath, func(t *testing.T) {
dbPath, err := testCopyOfDatabase(t, tt.dbPath)
if err != nil {
t.Fatalf("copying db for test: %s", err)
}
hsdb, err := NewHeadscaleDatabase(types.DatabaseConfig{
Type: "sqlite3",
Sqlite: types.SqliteConfig{
Path: dbPath,
},
}, "", emptyCache())
if err != nil && tt.wantErr != err.Error() {
t.Errorf("TestMigrations() unexpected error = %v, wantErr %v", err, tt.wantErr)
if !strings.HasSuffix(tt.dbPath, ".sql") {
t.Fatalf("TestSQLiteMigrationAndDataValidation only supports .sql files, got: %s", tt.dbPath)
}
hsdb := dbForTestWithPath(t, tt.dbPath)
if tt.wantFunc != nil {
tt.wantFunc(t, hsdb)
}
@@ -266,39 +721,27 @@ func TestMigrationsSQLite(t *testing.T) {
}
}
func testCopyOfDatabase(t *testing.T, src string) (string, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return "", err
}
if !sourceFileStat.Mode().IsRegular() {
return "", fmt.Errorf("%s is not a regular file", src)
}
source, err := os.Open(src)
if err != nil {
return "", err
}
defer source.Close()
tmpDir := t.TempDir()
fn := filepath.Base(src)
dst := filepath.Join(tmpDir, fn)
destination, err := os.Create(dst)
if err != nil {
return "", err
}
defer destination.Close()
_, err = io.Copy(destination, source)
return dst, err
}
func emptyCache() *zcache.Cache[types.RegistrationID, types.RegisterNode] {
return zcache.New[types.RegistrationID, types.RegisterNode](time.Minute, time.Hour)
}
func createSQLiteFromSQLFile(sqlFilePath, dbPath string) error {
db, err := sql.Open("sqlite", dbPath)
if err != nil {
return err
}
defer db.Close()
schemaContent, err := os.ReadFile(sqlFilePath)
if err != nil {
return err
}
_, err = db.Exec(string(schemaContent))
return err
}
// requireConstraintFailed checks if the error is a constraint failure with
// either SQLite and PostgreSQL error messages.
func requireConstraintFailed(t *testing.T, err error) {
@@ -415,7 +858,13 @@ func TestConstraints(t *testing.T) {
}
}
func TestMigrationsPostgres(t *testing.T) {
// TestPostgresMigrationAndDataValidation tests specific PostgreSQL migration scenarios
// and validates data integrity after migration. All migrations that require data validation
// should be added here.
//
// TODO(kradalby): Convert to use plain text SQL dumps instead of binary .pssql dumps for consistency
// with SQLite tests and easier version control.
func TestPostgresMigrationAndDataValidation(t *testing.T) {
tests := []struct {
name string
dbPath string
@@ -423,9 +872,10 @@ func TestMigrationsPostgres(t *testing.T) {
}{
{
name: "user-idx-breaking",
dbPath: "testdata/pre-24-postgresdb.pssql.dump",
wantFunc: func(t *testing.T, h *HSDatabase) {
users, err := Read(h.DB, func(rx *gorm.DB) ([]types.User, error) {
dbPath: "testdata/postgres/pre-24-postgresdb.pssql.dump",
wantFunc: func(t *testing.T, hsdb *HSDatabase) {
t.Helper()
users, err := Read(hsdb.DB, func(rx *gorm.DB) ([]types.User, error) {
return ListUsers(rx)
})
require.NoError(t, err)
@@ -472,9 +922,27 @@ func TestMigrationsPostgres(t *testing.T) {
func dbForTest(t *testing.T) *HSDatabase {
t.Helper()
return dbForTestWithPath(t, "")
}
func dbForTestWithPath(t *testing.T, sqlFilePath string) *HSDatabase {
t.Helper()
dbPath := t.TempDir() + "/headscale_test.db"
// If SQL file path provided, validate and create database from it
if sqlFilePath != "" {
// Validate that the file is a SQL text file
if !strings.HasSuffix(sqlFilePath, ".sql") {
t.Fatalf("dbForTestWithPath only accepts .sql files, got: %s", sqlFilePath)
}
err := createSQLiteFromSQLFile(sqlFilePath, dbPath)
if err != nil {
t.Fatalf("setting up database from SQL file %s: %s", sqlFilePath, err)
}
}
db, err := NewHeadscaleDatabase(
types.DatabaseConfig{
Type: "sqlite3",
@@ -489,7 +957,59 @@ func dbForTest(t *testing.T) *HSDatabase {
t.Fatalf("setting up database: %s", err)
}
t.Logf("database set up at: %s", dbPath)
if sqlFilePath != "" {
t.Logf("database set up from %s at: %s", sqlFilePath, dbPath)
} else {
t.Logf("database set up at: %s", dbPath)
}
return db
}
// TestSQLiteAllTestdataMigrations tests migration compatibility across all SQLite schemas
// in the testdata directory. It verifies they can be successfully migrated to the current
// schema version. This test only validates migration success, not data integrity.
//
// A lot of the schemas have been automatically generated with old Headscale binaries on empty databases
// (no user/node data):
// - `headscale_<VERSION>_schema.sql` (created with `sqlite3 headscale.db .schema`)
// - `headscale_<VERSION>_dump.sql` (created with `sqlite3 headscale.db .dump`)
// where `_dump.sql` contains the migration steps that have been applied to the database.
func TestSQLiteAllTestdataMigrations(t *testing.T) {
t.Parallel()
schemas, err := os.ReadDir("testdata/sqlite")
require.NoError(t, err)
t.Logf("loaded %d schemas", len(schemas))
for _, schema := range schemas {
if schema.IsDir() {
continue
}
t.Logf("validating: %s", schema.Name())
t.Run(schema.Name(), func(t *testing.T) {
t.Parallel()
dbPath := t.TempDir() + "/headscale_test.db"
// Setup a database with the old schema
schemaPath := filepath.Join("testdata/sqlite", schema.Name())
err := createSQLiteFromSQLFile(schemaPath, dbPath)
require.NoError(t, err)
_, err = NewHeadscaleDatabase(
types.DatabaseConfig{
Type: "sqlite3",
Sqlite: types.SqliteConfig{
Path: dbPath,
},
},
"",
emptyCache(),
)
require.NoError(t, err)
})
}
}

View File

@@ -11,9 +11,11 @@ import (
"github.com/stretchr/testify/assert"
)
const fiveHundredMillis = 500 * time.Millisecond
const oneHundredMillis = 100 * time.Millisecond
const fiftyMillis = 50 * time.Millisecond
const (
fiveHundred = 500 * time.Millisecond
oneHundred = 100 * time.Millisecond
fifty = 50 * time.Millisecond
)
// TestEphemeralGarbageCollectorGoRoutineLeak is a test for a goroutine leak in EphemeralGarbageCollector().
// It creates a new EphemeralGarbageCollector, schedules several nodes for deletion with a short expiry,
@@ -41,7 +43,7 @@ func TestEphemeralGarbageCollectorGoRoutineLeak(t *testing.T) {
go gc.Start()
// Schedule several nodes for deletion with short expiry
const expiry = fiftyMillis
const expiry = fifty
const numNodes = 100
// Set up wait group for expected deletions
@@ -56,7 +58,7 @@ func TestEphemeralGarbageCollectorGoRoutineLeak(t *testing.T) {
// Check nodes are deleted
deleteMutex.Lock()
assert.Equal(t, numNodes, len(deletedIDs), "Not all nodes were deleted")
assert.Len(t, deletedIDs, numNodes, "Not all nodes were deleted")
deleteMutex.Unlock()
// Schedule and immediately cancel to test that part of the code
@@ -76,7 +78,7 @@ func TestEphemeralGarbageCollectorGoRoutineLeak(t *testing.T) {
// Give any potential leaked goroutines a chance to exit
// Still need a small sleep here as we're checking for absence of goroutines
time.Sleep(oneHundredMillis)
time.Sleep(oneHundred)
// Check for leaked goroutines
finalGoroutines := runtime.NumGoroutine()
@@ -112,7 +114,7 @@ func TestEphemeralGarbageCollectorReschedule(t *testing.T) {
go gc.Start()
defer gc.Close()
const shortExpiry = fiftyMillis
const shortExpiry = fifty
const longExpiry = 1 * time.Hour
nodeID := types.NodeID(1)
@@ -128,7 +130,7 @@ func TestEphemeralGarbageCollectorReschedule(t *testing.T) {
// Verify that the node was deleted once
deleteMutex.Lock()
assert.Equal(t, 1, len(deletedIDs), "Node should be deleted exactly once")
assert.Len(t, deletedIDs, 1, "Node should be deleted exactly once")
assert.Equal(t, nodeID, deletedIDs[0], "The correct node should be deleted")
deleteMutex.Unlock()
}
@@ -155,7 +157,7 @@ func TestEphemeralGarbageCollectorCancelAndReschedule(t *testing.T) {
defer gc.Close()
nodeID := types.NodeID(1)
const expiry = fiftyMillis
const expiry = fifty
// Schedule node for deletion
gc.Schedule(nodeID, expiry)
@@ -172,7 +174,7 @@ func TestEphemeralGarbageCollectorCancelAndReschedule(t *testing.T) {
}
deleteMutex.Lock()
assert.Equal(t, 0, len(deletedIDs), "Node should not be deleted after cancellation")
assert.Empty(t, deletedIDs, "Node should not be deleted after cancellation")
deleteMutex.Unlock()
// Reschedule the node
@@ -189,7 +191,7 @@ func TestEphemeralGarbageCollectorCancelAndReschedule(t *testing.T) {
// Verify final state
deleteMutex.Lock()
assert.Equal(t, 1, len(deletedIDs), "Node should be deleted after rescheduling")
assert.Len(t, deletedIDs, 1, "Node should be deleted after rescheduling")
assert.Equal(t, nodeID, deletedIDs[0], "The correct node should be deleted")
deleteMutex.Unlock()
}
@@ -212,7 +214,7 @@ func TestEphemeralGarbageCollectorCloseBeforeTimerFires(t *testing.T) {
go gc.Start()
const longExpiry = 1 * time.Hour
const shortExpiry = fiftyMillis
const shortExpiry = fifty
// Schedule node deletion with a long expiry
gc.Schedule(types.NodeID(1), longExpiry)
@@ -225,7 +227,7 @@ func TestEphemeralGarbageCollectorCloseBeforeTimerFires(t *testing.T) {
// Verify that no deletion occurred
deleteMutex.Lock()
assert.Equal(t, 0, len(deletedIDs), "No node should be deleted when GC is closed before timer fires")
assert.Empty(t, deletedIDs, "No node should be deleted when GC is closed before timer fires")
deleteMutex.Unlock()
}
@@ -269,7 +271,7 @@ func TestEphemeralGarbageCollectorScheduleAfterClose(t *testing.T) {
// Give the GC time to fully close and clean up resources
// This is still time-based but only affects when we check the goroutine count,
// not the actual test logic
time.Sleep(oneHundredMillis)
time.Sleep(oneHundred)
close(gcClosedCheck)
}()
@@ -279,7 +281,7 @@ func TestEphemeralGarbageCollectorScheduleAfterClose(t *testing.T) {
gc.Schedule(nodeID, 1*time.Millisecond)
// Set up a timeout channel for our test
timeout := time.After(fiveHundredMillis)
timeout := time.After(fiveHundred)
// Check if any node was deleted (which shouldn't happen)
select {
@@ -329,7 +331,7 @@ func TestEphemeralGarbageCollectorConcurrentScheduleAndClose(t *testing.T) {
// Number of concurrent scheduling goroutines
const numSchedulers = 10
const nodesPerScheduler = 50
const schedulingDuration = fiveHundredMillis
const schedulingDuration = fiveHundred
// Use WaitGroup to wait for all scheduling goroutines to finish
var wg sync.WaitGroup
@@ -339,14 +341,14 @@ func TestEphemeralGarbageCollectorConcurrentScheduleAndClose(t *testing.T) {
stopScheduling := make(chan struct{})
// Launch goroutines that continuously schedule nodes
for i := 0; i < numSchedulers; i++ {
for schedulerIndex := range numSchedulers {
go func(schedulerID int) {
defer wg.Done()
baseNodeID := schedulerID * nodesPerScheduler
// Keep scheduling nodes until signaled to stop
for j := 0; j < nodesPerScheduler; j++ {
for j := range nodesPerScheduler {
select {
case <-stopScheduling:
return
@@ -358,7 +360,7 @@ func TestEphemeralGarbageCollectorConcurrentScheduleAndClose(t *testing.T) {
time.Sleep(time.Duration(rand.Intn(5)) * time.Millisecond)
}
}
}(i)
}(schedulerIndex)
}
// After a short delay, close the garbage collector while schedulers are still running
@@ -377,7 +379,7 @@ func TestEphemeralGarbageCollectorConcurrentScheduleAndClose(t *testing.T) {
wg.Wait()
// Wait a bit longer to allow any leaked goroutines to do their work
time.Sleep(oneHundredMillis)
time.Sleep(oneHundred)
// Check for leaks
finalGoroutines := runtime.NumGoroutine()

View File

@@ -17,6 +17,8 @@ import (
"tailscale.com/net/tsaddr"
)
var errGeneratedIPBytesInvalid = errors.New("generated ip bytes are invalid ip")
// IPAllocator is a singleton responsible for allocating
// IP addresses for nodes and making sure the same
// address is not handed out twice. There can only be one
@@ -236,7 +238,7 @@ func randomNext(pfx netip.Prefix) (netip.Addr, error) {
ip, ok := netip.AddrFromSlice(valInRange.Bytes())
if !ok {
return netip.Addr{}, fmt.Errorf("generated ip bytes are invalid ip")
return netip.Addr{}, errGeneratedIPBytesInvalid
}
if !pfx.Contains(ip) {

View File

@@ -7,15 +7,19 @@ import (
"net/netip"
"slices"
"sort"
"strconv"
"sync"
"testing"
"time"
"github.com/juanfont/headscale/hscontrol/types"
"github.com/juanfont/headscale/hscontrol/types/change"
"github.com/juanfont/headscale/hscontrol/util"
"github.com/rs/zerolog/log"
"gorm.io/gorm"
"tailscale.com/tailcfg"
"tailscale.com/types/key"
"tailscale.com/types/ptr"
)
const (
@@ -39,9 +43,7 @@ var (
// If no peer IDs are given, all peers are returned.
// If at least one peer ID is given, only these peer nodes will be returned.
func (hsdb *HSDatabase) ListPeers(nodeID types.NodeID, peerIDs ...types.NodeID) (types.Nodes, error) {
return Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) {
return ListPeers(rx, nodeID, peerIDs...)
})
return ListPeers(hsdb.DB, nodeID, peerIDs...)
}
// ListPeers returns peers of node, regardless of any Policy or if the node is expired.
@@ -64,15 +66,13 @@ func ListPeers(tx *gorm.DB, nodeID types.NodeID, peerIDs ...types.NodeID) (types
}
// ListNodes queries the database for either all nodes if no parameters are given
// or for the given nodes if at least one node ID is given as parameter
// or for the given nodes if at least one node ID is given as parameter.
func (hsdb *HSDatabase) ListNodes(nodeIDs ...types.NodeID) (types.Nodes, error) {
return Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) {
return ListNodes(rx, nodeIDs...)
})
return ListNodes(hsdb.DB, nodeIDs...)
}
// ListNodes queries the database for either all nodes if no parameters are given
// or for the given nodes if at least one node ID is given as parameter
// or for the given nodes if at least one node ID is given as parameter.
func ListNodes(tx *gorm.DB, nodeIDs ...types.NodeID) (types.Nodes, error) {
nodes := types.Nodes{}
if err := tx.
@@ -120,9 +120,7 @@ func getNode(tx *gorm.DB, uid types.UserID, name string) (*types.Node, error) {
}
func (hsdb *HSDatabase) GetNodeByID(id types.NodeID) (*types.Node, error) {
return Read(hsdb.DB, func(rx *gorm.DB) (*types.Node, error) {
return GetNodeByID(rx, id)
})
return GetNodeByID(hsdb.DB, id)
}
// GetNodeByID finds a Node by ID and returns the Node struct.
@@ -140,9 +138,7 @@ func GetNodeByID(tx *gorm.DB, id types.NodeID) (*types.Node, error) {
}
func (hsdb *HSDatabase) GetNodeByMachineKey(machineKey key.MachinePublic) (*types.Node, error) {
return Read(hsdb.DB, func(rx *gorm.DB) (*types.Node, error) {
return GetNodeByMachineKey(rx, machineKey)
})
return GetNodeByMachineKey(hsdb.DB, machineKey)
}
// GetNodeByMachineKey finds a Node by its MachineKey and returns the Node struct.
@@ -163,9 +159,7 @@ func GetNodeByMachineKey(
}
func (hsdb *HSDatabase) GetNodeByNodeKey(nodeKey key.NodePublic) (*types.Node, error) {
return Read(hsdb.DB, func(rx *gorm.DB) (*types.Node, error) {
return GetNodeByNodeKey(rx, nodeKey)
})
return GetNodeByNodeKey(hsdb.DB, nodeKey)
}
// GetNodeByNodeKey finds a Node by its NodeKey and returns the Node struct.
@@ -352,8 +346,8 @@ func (hsdb *HSDatabase) HandleNodeFromAuthPath(
registrationMethod string,
ipv4 *netip.Addr,
ipv6 *netip.Addr,
) (*types.Node, bool, error) {
var newNode bool
) (*types.Node, change.ChangeSet, error) {
var nodeChange change.ChangeSet
node, err := Write(hsdb.DB, func(tx *gorm.DB) (*types.Node, error) {
if reg, ok := hsdb.regCache.Get(registrationID); ok {
if node, _ := GetNodeByNodeKey(tx, reg.Node.NodeKey); node == nil {
@@ -405,7 +399,8 @@ func (hsdb *HSDatabase) HandleNodeFromAuthPath(
}
close(reg.Registered)
newNode = true
nodeChange = change.NodeAdded(node.ID)
return node, err
} else {
// If the node is already registered, this is a refresh.
@@ -413,6 +408,9 @@ func (hsdb *HSDatabase) HandleNodeFromAuthPath(
if err != nil {
return nil, err
}
nodeChange = change.KeyExpiry(node.ID)
return node, nil
}
}
@@ -420,7 +418,7 @@ func (hsdb *HSDatabase) HandleNodeFromAuthPath(
return nil, ErrNodeNotFoundRegistrationCache
})
return node, newNode, err
return node, nodeChange, err
}
func (hsdb *HSDatabase) RegisterNode(node types.Node, ipv4 *netip.Addr, ipv6 *netip.Addr) (*types.Node, error) {
@@ -446,6 +444,7 @@ func RegisterNode(tx *gorm.DB, node types.Node, ipv4 *netip.Addr, ipv6 *netip.Ad
if oldNode != nil && oldNode.UserID == node.UserID {
node.ID = oldNode.ID
node.GivenName = oldNode.GivenName
node.ApprovedRoutes = oldNode.ApprovedRoutes
ipv4 = oldNode.IPv4
ipv6 = oldNode.IPv6
}
@@ -592,17 +591,18 @@ func ensureUniqueGivenName(
// containing the expired nodes, and a boolean indicating if any nodes were found.
func ExpireExpiredNodes(tx *gorm.DB,
lastCheck time.Time,
) (time.Time, types.StateUpdate, bool) {
) (time.Time, []change.ChangeSet, bool) {
// use the time of the start of the function to ensure we
// dont miss some nodes by returning it _after_ we have
// checked everything.
started := time.Now()
expired := make([]*tailcfg.PeerChange, 0)
var updates []change.ChangeSet
nodes, err := ListNodes(tx)
if err != nil {
return time.Unix(0, 0), types.StateUpdate{}, false
return time.Unix(0, 0), nil, false
}
for _, node := range nodes {
if node.IsExpired() && node.Expiry.After(lastCheck) {
@@ -610,14 +610,15 @@ func ExpireExpiredNodes(tx *gorm.DB,
NodeID: tailcfg.NodeID(node.ID),
KeyExpiry: node.Expiry,
})
updates = append(updates, change.KeyExpiry(node.ID))
}
}
if len(expired) > 0 {
return started, types.UpdatePeerPatch(expired...), true
return started, updates, true
}
return started, types.StateUpdate{}, false
return started, nil, false
}
// EphemeralGarbageCollector is a garbage collector that will delete nodes after
@@ -730,3 +731,114 @@ func (e *EphemeralGarbageCollector) Start() {
}
}
}
func (hsdb *HSDatabase) CreateNodeForTest(user *types.User, hostname ...string) *types.Node {
if !testing.Testing() {
panic("CreateNodeForTest can only be called during tests")
}
if user == nil {
panic("CreateNodeForTest requires a valid user")
}
nodeName := "testnode"
if len(hostname) > 0 && hostname[0] != "" {
nodeName = hostname[0]
}
// Create a preauth key for the node
pak, err := hsdb.CreatePreAuthKey(types.UserID(user.ID), false, false, nil, nil)
if err != nil {
panic(fmt.Sprintf("failed to create preauth key for test node: %v", err))
}
nodeKey := key.NewNode()
machineKey := key.NewMachine()
discoKey := key.NewDisco()
node := &types.Node{
MachineKey: machineKey.Public(),
NodeKey: nodeKey.Public(),
DiscoKey: discoKey.Public(),
Hostname: nodeName,
UserID: user.ID,
RegisterMethod: util.RegisterMethodAuthKey,
AuthKeyID: ptr.To(pak.ID),
}
err = hsdb.DB.Save(node).Error
if err != nil {
panic(fmt.Sprintf("failed to create test node: %v", err))
}
return node
}
func (hsdb *HSDatabase) CreateRegisteredNodeForTest(user *types.User, hostname ...string) *types.Node {
if !testing.Testing() {
panic("CreateRegisteredNodeForTest can only be called during tests")
}
node := hsdb.CreateNodeForTest(user, hostname...)
err := hsdb.DB.Transaction(func(tx *gorm.DB) error {
_, err := RegisterNode(tx, *node, nil, nil)
return err
})
if err != nil {
panic(fmt.Sprintf("failed to register test node: %v", err))
}
registeredNode, err := hsdb.GetNodeByID(node.ID)
if err != nil {
panic(fmt.Sprintf("failed to get registered test node: %v", err))
}
return registeredNode
}
func (hsdb *HSDatabase) CreateNodesForTest(user *types.User, count int, hostnamePrefix ...string) []*types.Node {
if !testing.Testing() {
panic("CreateNodesForTest can only be called during tests")
}
if user == nil {
panic("CreateNodesForTest requires a valid user")
}
prefix := "testnode"
if len(hostnamePrefix) > 0 && hostnamePrefix[0] != "" {
prefix = hostnamePrefix[0]
}
nodes := make([]*types.Node, count)
for i := range count {
hostname := prefix + "-" + strconv.Itoa(i)
nodes[i] = hsdb.CreateNodeForTest(user, hostname)
}
return nodes
}
func (hsdb *HSDatabase) CreateRegisteredNodesForTest(user *types.User, count int, hostnamePrefix ...string) []*types.Node {
if !testing.Testing() {
panic("CreateRegisteredNodesForTest can only be called during tests")
}
if user == nil {
panic("CreateRegisteredNodesForTest requires a valid user")
}
prefix := "testnode"
if len(hostnamePrefix) > 0 && hostnamePrefix[0] != "" {
prefix = hostnamePrefix[0]
}
nodes := make([]*types.Node, count)
for i := range count {
hostname := prefix + "-" + strconv.Itoa(i)
nodes[i] = hsdb.CreateRegisteredNodeForTest(user, hostname)
}
return nodes
}

View File

@@ -6,7 +6,6 @@ import (
"math/big"
"net/netip"
"regexp"
"strconv"
"sync"
"testing"
"time"
@@ -26,82 +25,36 @@ import (
)
func (s *Suite) TestGetNode(c *check.C) {
user, err := db.CreateUser(types.User{Name: "test"})
c.Assert(err, check.IsNil)
user := db.CreateUserForTest("test")
pak, err := db.CreatePreAuthKey(types.UserID(user.ID), false, false, nil, nil)
c.Assert(err, check.IsNil)
_, err = db.getNode(types.UserID(user.ID), "testnode")
_, err := db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.NotNil)
nodeKey := key.NewNode()
machineKey := key.NewMachine()
node := &types.Node{
ID: 0,
MachineKey: machineKey.Public(),
NodeKey: nodeKey.Public(),
Hostname: "testnode",
UserID: user.ID,
RegisterMethod: util.RegisterMethodAuthKey,
AuthKeyID: ptr.To(pak.ID),
}
trx := db.DB.Save(node)
c.Assert(trx.Error, check.IsNil)
node := db.CreateNodeForTest(user, "testnode")
_, err = db.getNode(types.UserID(user.ID), "testnode")
c.Assert(err, check.IsNil)
c.Assert(node.Hostname, check.Equals, "testnode")
}
func (s *Suite) TestGetNodeByID(c *check.C) {
user, err := db.CreateUser(types.User{Name: "test"})
c.Assert(err, check.IsNil)
user := db.CreateUserForTest("test")
pak, err := db.CreatePreAuthKey(types.UserID(user.ID), false, false, nil, nil)
c.Assert(err, check.IsNil)
_, err = db.GetNodeByID(0)
_, err := db.GetNodeByID(0)
c.Assert(err, check.NotNil)
nodeKey := key.NewNode()
machineKey := key.NewMachine()
node := db.CreateNodeForTest(user, "testnode")
node := types.Node{
ID: 0,
MachineKey: machineKey.Public(),
NodeKey: nodeKey.Public(),
Hostname: "testnode",
UserID: user.ID,
RegisterMethod: util.RegisterMethodAuthKey,
AuthKeyID: ptr.To(pak.ID),
}
trx := db.DB.Save(&node)
c.Assert(trx.Error, check.IsNil)
_, err = db.GetNodeByID(0)
retrievedNode, err := db.GetNodeByID(node.ID)
c.Assert(err, check.IsNil)
c.Assert(retrievedNode.Hostname, check.Equals, "testnode")
}
func (s *Suite) TestHardDeleteNode(c *check.C) {
user, err := db.CreateUser(types.User{Name: "test"})
c.Assert(err, check.IsNil)
user := db.CreateUserForTest("test")
node := db.CreateNodeForTest(user, "testnode3")
nodeKey := key.NewNode()
machineKey := key.NewMachine()
node := types.Node{
ID: 0,
MachineKey: machineKey.Public(),
NodeKey: nodeKey.Public(),
Hostname: "testnode3",
UserID: user.ID,
RegisterMethod: util.RegisterMethodAuthKey,
}
trx := db.DB.Save(&node)
c.Assert(trx.Error, check.IsNil)
err = db.DeleteNode(&node)
err := db.DeleteNode(node)
c.Assert(err, check.IsNil)
_, err = db.getNode(types.UserID(user.ID), "testnode3")
@@ -109,42 +62,21 @@ func (s *Suite) TestHardDeleteNode(c *check.C) {
}
func (s *Suite) TestListPeers(c *check.C) {
user, err := db.CreateUser(types.User{Name: "test"})
c.Assert(err, check.IsNil)
user := db.CreateUserForTest("test")
pak, err := db.CreatePreAuthKey(types.UserID(user.ID), false, false, nil, nil)
c.Assert(err, check.IsNil)
_, err = db.GetNodeByID(0)
_, err := db.GetNodeByID(0)
c.Assert(err, check.NotNil)
for index := 0; index <= 10; index++ {
nodeKey := key.NewNode()
machineKey := key.NewMachine()
nodes := db.CreateNodesForTest(user, 11, "testnode")
node := types.Node{
ID: types.NodeID(index),
MachineKey: machineKey.Public(),
NodeKey: nodeKey.Public(),
Hostname: "testnode" + strconv.Itoa(index),
UserID: user.ID,
RegisterMethod: util.RegisterMethodAuthKey,
AuthKeyID: ptr.To(pak.ID),
}
trx := db.DB.Save(&node)
c.Assert(trx.Error, check.IsNil)
}
node0ByID, err := db.GetNodeByID(0)
firstNode := nodes[0]
peersOfFirstNode, err := db.ListPeers(firstNode.ID)
c.Assert(err, check.IsNil)
peersOfNode0, err := db.ListPeers(node0ByID.ID)
c.Assert(err, check.IsNil)
c.Assert(len(peersOfNode0), check.Equals, 9)
c.Assert(peersOfNode0[0].Hostname, check.Equals, "testnode2")
c.Assert(peersOfNode0[5].Hostname, check.Equals, "testnode7")
c.Assert(peersOfNode0[8].Hostname, check.Equals, "testnode10")
c.Assert(len(peersOfFirstNode), check.Equals, 10)
c.Assert(peersOfFirstNode[0].Hostname, check.Equals, "testnode-1")
c.Assert(peersOfFirstNode[5].Hostname, check.Equals, "testnode-6")
c.Assert(peersOfFirstNode[9].Hostname, check.Equals, "testnode-10")
}
func (s *Suite) TestExpireNode(c *check.C) {
@@ -485,7 +417,7 @@ func TestAutoApproveRoutes(t *testing.T) {
nodes, err := adb.ListNodes()
assert.NoError(t, err)
pm, err := pmf(users, nodes)
pm, err := pmf(users, nodes.ViewSlice())
require.NoError(t, err)
require.NotNil(t, pm)
@@ -589,6 +521,7 @@ func generateRandomNumber(t *testing.T, max int64) int64 {
if err != nil {
t.Fatalf("getting random number: %s", err)
}
return n.Int64() + 1
}
@@ -692,6 +625,7 @@ func TestRenameNode(t *testing.T) {
return err
}
_, err = RegisterNode(tx, node2, nil, nil)
return err
})
require.NoError(t, err)
@@ -792,6 +726,7 @@ func TestListPeers(t *testing.T) {
return err
}
_, err = RegisterNode(tx, node2, nil, nil)
return err
})
require.NoError(t, err)
@@ -804,30 +739,30 @@ func TestListPeers(t *testing.T) {
// No parameter means no filter, should return all peers
nodes, err = db.ListPeers(1)
require.NoError(t, err)
assert.Equal(t, len(nodes), 1)
assert.Equal(t, 1, len(nodes))
assert.Equal(t, "test2", nodes[0].Hostname)
// Empty node list should return all peers
nodes, err = db.ListPeers(1, types.NodeIDs{}...)
require.NoError(t, err)
assert.Equal(t, len(nodes), 1)
assert.Equal(t, 1, len(nodes))
assert.Equal(t, "test2", nodes[0].Hostname)
// No match in IDs should return empty list and no error
nodes, err = db.ListPeers(1, types.NodeIDs{3, 4, 5}...)
require.NoError(t, err)
assert.Equal(t, len(nodes), 0)
assert.Empty(t, nodes)
// Partial match in IDs
nodes, err = db.ListPeers(1, types.NodeIDs{2, 3}...)
require.NoError(t, err)
assert.Equal(t, len(nodes), 1)
assert.Equal(t, 1, len(nodes))
assert.Equal(t, "test2", nodes[0].Hostname)
// Several matched IDs, but node ID is still filtered out
nodes, err = db.ListPeers(1, types.NodeIDs{1, 2, 3}...)
require.NoError(t, err)
assert.Equal(t, len(nodes), 1)
assert.Equal(t, 1, len(nodes))
assert.Equal(t, "test2", nodes[0].Hostname)
}
@@ -876,6 +811,7 @@ func TestListNodes(t *testing.T) {
return err
}
_, err = RegisterNode(tx, node2, nil, nil)
return err
})
require.NoError(t, err)
@@ -888,32 +824,32 @@ func TestListNodes(t *testing.T) {
// No parameter means no filter, should return all nodes
nodes, err = db.ListNodes()
require.NoError(t, err)
assert.Equal(t, len(nodes), 2)
assert.Equal(t, 2, len(nodes))
assert.Equal(t, "test1", nodes[0].Hostname)
assert.Equal(t, "test2", nodes[1].Hostname)
// Empty node list should return all nodes
nodes, err = db.ListNodes(types.NodeIDs{}...)
require.NoError(t, err)
assert.Equal(t, len(nodes), 2)
assert.Equal(t, 2, len(nodes))
assert.Equal(t, "test1", nodes[0].Hostname)
assert.Equal(t, "test2", nodes[1].Hostname)
// No match in IDs should return empty list and no error
nodes, err = db.ListNodes(types.NodeIDs{3, 4, 5}...)
require.NoError(t, err)
assert.Equal(t, len(nodes), 0)
assert.Empty(t, nodes)
// Partial match in IDs
nodes, err = db.ListNodes(types.NodeIDs{2, 3}...)
require.NoError(t, err)
assert.Equal(t, len(nodes), 1)
assert.Equal(t, 1, len(nodes))
assert.Equal(t, "test2", nodes[0].Hostname)
// Several matched IDs
nodes, err = db.ListNodes(types.NodeIDs{1, 2, 3}...)
require.NoError(t, err)
assert.Equal(t, len(nodes), 2)
assert.Equal(t, 2, len(nodes))
assert.Equal(t, "test1", nodes[0].Hostname)
assert.Equal(t, "test2", nodes[1].Hostname)
}

View File

@@ -109,9 +109,7 @@ func ListPreAuthKeysByUser(tx *gorm.DB, uid types.UserID) ([]types.PreAuthKey, e
}
func (hsdb *HSDatabase) GetPreAuthKey(key string) (*types.PreAuthKey, error) {
return Read(hsdb.DB, func(rx *gorm.DB) (*types.PreAuthKey, error) {
return GetPreAuthKey(rx, key)
})
return GetPreAuthKey(hsdb.DB, key)
}
// GetPreAuthKey returns a PreAuthKey for a given key. The caller is responsible
@@ -155,11 +153,8 @@ func UsePreAuthKey(tx *gorm.DB, k *types.PreAuthKey) error {
// MarkExpirePreAuthKey marks a PreAuthKey as expired.
func ExpirePreAuthKey(tx *gorm.DB, k *types.PreAuthKey) error {
if err := tx.Model(&k).Update("Expiration", time.Now()).Error; err != nil {
return err
}
return nil
now := time.Now()
return tx.Model(&types.PreAuthKey{}).Where("id = ?", k.ID).Update("expiration", now).Error
}
func generateKey() (string, error) {

View File

@@ -1,16 +1,15 @@
package db
import (
"sort"
"slices"
"testing"
"github.com/juanfont/headscale/hscontrol/types"
"github.com/juanfont/headscale/hscontrol/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"tailscale.com/types/ptr"
"gopkg.in/check.v1"
"tailscale.com/types/ptr"
)
func (*Suite) TestCreatePreAuthKey(c *check.C) {
@@ -58,7 +57,7 @@ func (*Suite) TestPreAuthKeyACLTags(c *check.C) {
listedPaks, err := db.ListPreAuthKeys(types.UserID(user.ID))
c.Assert(err, check.IsNil)
gotTags := listedPaks[0].Proto().GetAclTags()
sort.Sort(sort.StringSlice(gotTags))
slices.Sort(gotTags)
c.Assert(gotTags, check.DeepEquals, tags)
}

110
hscontrol/db/schema.sql Normal file
View File

@@ -0,0 +1,110 @@
-- This file is the representation of the SQLite schema of Headscale.
-- It is the "source of truth" and is used to validate any migrations
-- that are run against the database to ensure it ends in the expected state.
CREATE TABLE migrations(id text,PRIMARY KEY(id));
CREATE TABLE users(
id integer PRIMARY KEY AUTOINCREMENT,
name text,
display_name text,
email text,
provider_identifier text,
provider text,
profile_pic_url text,
created_at datetime,
updated_at datetime,
deleted_at datetime
);
CREATE INDEX idx_users_deleted_at ON users(deleted_at);
-- The following three UNIQUE indexes work together to enforce the user identity model:
--
-- 1. Users can be either local (provider_identifier is NULL) or from external providers (provider_identifier set)
-- 2. Each external provider identifier must be unique across the system
-- 3. Local usernames must be unique among local users
-- 4. The same username can exist across different providers with different identifiers
--
-- Examples:
-- - Can create local user "alice" (provider_identifier=NULL)
-- - Can create external user "alice" with GitHub (name="alice", provider_identifier="alice_github")
-- - Can create external user "alice" with Google (name="alice", provider_identifier="alice_google")
-- - Cannot create another local user "alice" (blocked by idx_name_no_provider_identifier)
-- - Cannot create another user with provider_identifier="alice_github" (blocked by idx_provider_identifier)
-- - Cannot create user "bob" with provider_identifier="alice_github" (blocked by idx_name_provider_identifier)
CREATE UNIQUE INDEX idx_provider_identifier ON users(
provider_identifier
) WHERE provider_identifier IS NOT NULL;
CREATE UNIQUE INDEX idx_name_provider_identifier ON users(
name,
provider_identifier
);
CREATE UNIQUE INDEX idx_name_no_provider_identifier ON users(
name
) WHERE provider_identifier IS NULL;
CREATE TABLE pre_auth_keys(
id integer PRIMARY KEY AUTOINCREMENT,
key text,
user_id integer,
reusable numeric,
ephemeral numeric DEFAULT false,
used numeric DEFAULT false,
tags text,
expiration datetime,
created_at datetime,
CONSTRAINT fk_pre_auth_keys_user FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE SET NULL
);
CREATE TABLE api_keys(
id integer PRIMARY KEY AUTOINCREMENT,
prefix text,
hash blob,
expiration datetime,
last_seen datetime,
created_at datetime
);
CREATE UNIQUE INDEX idx_api_keys_prefix ON api_keys(prefix);
CREATE TABLE nodes(
id integer PRIMARY KEY AUTOINCREMENT,
machine_key text,
node_key text,
disco_key text,
endpoints text,
host_info text,
ipv4 text,
ipv6 text,
hostname text,
given_name varchar(63),
user_id integer,
register_method text,
forced_tags text,
auth_key_id integer,
last_seen datetime,
expiry datetime,
approved_routes text,
created_at datetime,
updated_at datetime,
deleted_at datetime,
CONSTRAINT fk_nodes_user FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_nodes_auth_key FOREIGN KEY(auth_key_id) REFERENCES pre_auth_keys(id)
);
CREATE TABLE policies(
id integer PRIMARY KEY AUTOINCREMENT,
data text,
created_at datetime,
updated_at datetime,
deleted_at datetime
);
CREATE INDEX idx_policies_deleted_at ON policies(deleted_at);

View File

@@ -0,0 +1,345 @@
// Package sqliteconfig provides type-safe configuration for SQLite databases
// with proper enum validation and URL generation for modernc.org/sqlite driver.
package sqliteconfig
import (
"errors"
"fmt"
"strings"
)
// Errors returned by config validation.
var (
ErrPathEmpty = errors.New("path cannot be empty")
ErrBusyTimeoutNegative = errors.New("busy_timeout must be >= 0")
ErrInvalidJournalMode = errors.New("invalid journal_mode")
ErrInvalidAutoVacuum = errors.New("invalid auto_vacuum")
ErrWALAutocheckpoint = errors.New("wal_autocheckpoint must be >= -1")
ErrInvalidSynchronous = errors.New("invalid synchronous")
)
const (
// DefaultBusyTimeout is the default busy timeout in milliseconds.
DefaultBusyTimeout = 10000
)
// JournalMode represents SQLite journal_mode pragma values.
// Journal modes control how SQLite handles write transactions and crash recovery.
//
// Performance vs Durability Tradeoffs:
//
// WAL (Write-Ahead Logging) - Recommended for production:
// - Best performance for concurrent reads/writes
// - Readers don't block writers, writers don't block readers
// - Excellent crash recovery with minimal data loss risk
// - Uses additional .wal and .shm files
// - Default choice for Headscale production deployments
//
// DELETE - Traditional rollback journal:
// - Good performance for single-threaded access
// - Readers block writers and vice versa
// - Reliable crash recovery but with exclusive locking
// - Creates temporary journal files during transactions
// - Suitable for low-concurrency scenarios
//
// TRUNCATE - Similar to DELETE but faster cleanup:
// - Slightly better performance than DELETE
// - Same concurrency limitations as DELETE
// - Faster transaction commit by truncating instead of deleting journal
//
// PERSIST - Journal file remains between transactions:
// - Avoids file creation/deletion overhead
// - Same concurrency limitations as DELETE
// - Good for frequent small transactions
//
// MEMORY - Journal kept in memory:
// - Fastest performance but NO crash recovery
// - Data loss risk on power failure or crash
// - Only suitable for temporary or non-critical data
//
// OFF - No journaling:
// - Maximum performance but NO transaction safety
// - High risk of database corruption on crash
// - Should only be used for read-only or disposable databases
type JournalMode string
const (
// JournalModeWAL enables Write-Ahead Logging (RECOMMENDED for production).
// Best concurrent performance + crash recovery. Uses additional .wal/.shm files.
JournalModeWAL JournalMode = "WAL"
// JournalModeDelete uses traditional rollback journaling.
// Good single-threaded performance, readers block writers. Creates temp journal files.
JournalModeDelete JournalMode = "DELETE"
// JournalModeTruncate is like DELETE but with faster cleanup.
// Slightly better performance than DELETE, same safety with exclusive locking.
JournalModeTruncate JournalMode = "TRUNCATE"
// JournalModePersist keeps journal file between transactions.
// Good for frequent transactions, avoids file creation/deletion overhead.
JournalModePersist JournalMode = "PERSIST"
// JournalModeMemory keeps journal in memory (DANGEROUS).
// Fastest performance but NO crash recovery - data loss on power failure.
JournalModeMemory JournalMode = "MEMORY"
// JournalModeOff disables journaling entirely (EXTREMELY DANGEROUS).
// Maximum performance but high corruption risk. Only for disposable databases.
JournalModeOff JournalMode = "OFF"
)
// IsValid returns true if the JournalMode is valid.
func (j JournalMode) IsValid() bool {
switch j {
case JournalModeWAL, JournalModeDelete, JournalModeTruncate,
JournalModePersist, JournalModeMemory, JournalModeOff:
return true
default:
return false
}
}
// String returns the string representation.
func (j JournalMode) String() string {
return string(j)
}
// AutoVacuum represents SQLite auto_vacuum pragma values.
// Auto-vacuum controls how SQLite reclaims space from deleted data.
//
// Performance vs Storage Tradeoffs:
//
// INCREMENTAL - Recommended for production:
// - Reclaims space gradually during normal operations
// - Minimal performance impact on writes
// - Database size shrinks automatically over time
// - Can manually trigger with PRAGMA incremental_vacuum
// - Good balance of space efficiency and performance
//
// FULL - Automatic space reclamation:
// - Immediately reclaims space on every DELETE/DROP
// - Higher write overhead due to page reorganization
// - Keeps database file size minimal
// - Can cause significant slowdowns on large deletions
// - Best for applications with frequent deletes and limited storage
//
// NONE - No automatic space reclamation:
// - Fastest write performance (no vacuum overhead)
// - Database file only grows, never shrinks
// - Deleted space is reused but file size remains large
// - Requires manual VACUUM to reclaim space
// - Best for write-heavy workloads where storage isn't constrained
type AutoVacuum string
const (
// AutoVacuumNone disables automatic space reclamation.
// Fastest writes, file only grows. Requires manual VACUUM to reclaim space.
AutoVacuumNone AutoVacuum = "NONE"
// AutoVacuumFull immediately reclaims space on every DELETE/DROP.
// Minimal file size but slower writes. Can impact performance on large deletions.
AutoVacuumFull AutoVacuum = "FULL"
// AutoVacuumIncremental reclaims space gradually (RECOMMENDED for production).
// Good balance: minimal write impact, automatic space management over time.
AutoVacuumIncremental AutoVacuum = "INCREMENTAL"
)
// IsValid returns true if the AutoVacuum is valid.
func (a AutoVacuum) IsValid() bool {
switch a {
case AutoVacuumNone, AutoVacuumFull, AutoVacuumIncremental:
return true
default:
return false
}
}
// String returns the string representation.
func (a AutoVacuum) String() string {
return string(a)
}
// Synchronous represents SQLite synchronous pragma values.
// Synchronous mode controls how aggressively SQLite flushes data to disk.
//
// Performance vs Durability Tradeoffs:
//
// NORMAL - Recommended for production:
// - Good balance of performance and safety
// - Syncs at critical moments (transaction commits in WAL mode)
// - Very low risk of corruption, minimal performance impact
// - Safe with WAL mode even with power loss
// - Default choice for most production applications
//
// FULL - Maximum durability:
// - Syncs to disk after every write operation
// - Highest data safety, virtually no corruption risk
// - Significant performance penalty (up to 50% slower)
// - Recommended for critical data where corruption is unacceptable
//
// EXTRA - Paranoid mode:
// - Even more aggressive syncing than FULL
// - Maximum possible data safety
// - Severe performance impact
// - Only for extremely critical scenarios
//
// OFF - Maximum performance, minimum safety:
// - No syncing, relies on OS to flush data
// - Fastest possible performance
// - High risk of corruption on power failure or crash
// - Only suitable for non-critical or easily recreatable data
type Synchronous string
const (
// SynchronousOff disables syncing (DANGEROUS).
// Fastest performance but high corruption risk on power failure. Avoid in production.
SynchronousOff Synchronous = "OFF"
// SynchronousNormal provides balanced performance and safety (RECOMMENDED).
// Good performance with low corruption risk. Safe with WAL mode on power loss.
SynchronousNormal Synchronous = "NORMAL"
// SynchronousFull provides maximum durability with performance cost.
// Syncs after every write. Up to 50% slower but virtually no corruption risk.
SynchronousFull Synchronous = "FULL"
// SynchronousExtra provides paranoid-level data safety (EXTREME).
// Maximum safety with severe performance impact. Rarely needed in practice.
SynchronousExtra Synchronous = "EXTRA"
)
// IsValid returns true if the Synchronous is valid.
func (s Synchronous) IsValid() bool {
switch s {
case SynchronousOff, SynchronousNormal, SynchronousFull, SynchronousExtra:
return true
default:
return false
}
}
// String returns the string representation.
func (s Synchronous) String() string {
return string(s)
}
// Config holds SQLite database configuration with type-safe enums.
// This configuration balances performance, durability, and operational requirements
// for Headscale's SQLite database usage patterns.
type Config struct {
Path string // file path or ":memory:"
BusyTimeout int // milliseconds (0 = default/disabled)
JournalMode JournalMode // journal mode (affects concurrency and crash recovery)
AutoVacuum AutoVacuum // auto vacuum mode (affects storage efficiency)
WALAutocheckpoint int // pages (-1 = default/not set, 0 = disabled, >0 = enabled)
Synchronous Synchronous // synchronous mode (affects durability vs performance)
ForeignKeys bool // enable foreign key constraints (data integrity)
}
// Default returns the production configuration optimized for Headscale's usage patterns.
// This configuration prioritizes:
// - Concurrent access (WAL mode for multiple readers/writers)
// - Data durability with good performance (NORMAL synchronous)
// - Automatic space management (INCREMENTAL auto-vacuum)
// - Data integrity (foreign key constraints enabled)
// - Reasonable timeout for busy database scenarios (10s)
func Default(path string) *Config {
return &Config{
Path: path,
BusyTimeout: DefaultBusyTimeout,
JournalMode: JournalModeWAL,
AutoVacuum: AutoVacuumIncremental,
WALAutocheckpoint: 1000,
Synchronous: SynchronousNormal,
ForeignKeys: true,
}
}
// Memory returns a configuration for in-memory databases.
func Memory() *Config {
return &Config{
Path: ":memory:",
WALAutocheckpoint: -1, // not set, use driver default
ForeignKeys: true,
}
}
// Validate checks if all configuration values are valid.
func (c *Config) Validate() error {
if c.Path == "" {
return ErrPathEmpty
}
if c.BusyTimeout < 0 {
return fmt.Errorf("%w, got %d", ErrBusyTimeoutNegative, c.BusyTimeout)
}
if c.JournalMode != "" && !c.JournalMode.IsValid() {
return fmt.Errorf("%w: %s", ErrInvalidJournalMode, c.JournalMode)
}
if c.AutoVacuum != "" && !c.AutoVacuum.IsValid() {
return fmt.Errorf("%w: %s", ErrInvalidAutoVacuum, c.AutoVacuum)
}
if c.WALAutocheckpoint < -1 {
return fmt.Errorf("%w, got %d", ErrWALAutocheckpoint, c.WALAutocheckpoint)
}
if c.Synchronous != "" && !c.Synchronous.IsValid() {
return fmt.Errorf("%w: %s", ErrInvalidSynchronous, c.Synchronous)
}
return nil
}
// ToURL builds a properly encoded SQLite connection string using _pragma parameters
// compatible with modernc.org/sqlite driver.
func (c *Config) ToURL() (string, error) {
if err := c.Validate(); err != nil {
return "", fmt.Errorf("invalid config: %w", err)
}
var pragmas []string
// Add pragma parameters only if they're set (non-zero/non-empty)
if c.BusyTimeout > 0 {
pragmas = append(pragmas, fmt.Sprintf("busy_timeout=%d", c.BusyTimeout))
}
if c.JournalMode != "" {
pragmas = append(pragmas, fmt.Sprintf("journal_mode=%s", c.JournalMode))
}
if c.AutoVacuum != "" {
pragmas = append(pragmas, fmt.Sprintf("auto_vacuum=%s", c.AutoVacuum))
}
if c.WALAutocheckpoint >= 0 {
pragmas = append(pragmas, fmt.Sprintf("wal_autocheckpoint=%d", c.WALAutocheckpoint))
}
if c.Synchronous != "" {
pragmas = append(pragmas, fmt.Sprintf("synchronous=%s", c.Synchronous))
}
if c.ForeignKeys {
pragmas = append(pragmas, "foreign_keys=ON")
}
// Handle different database types
var baseURL string
if c.Path == ":memory:" {
baseURL = ":memory:"
} else {
baseURL = "file:" + c.Path
}
// Add parameters without encoding = signs
if len(pragmas) > 0 {
var queryParts []string
for _, pragma := range pragmas {
queryParts = append(queryParts, "_pragma="+pragma)
}
baseURL += "?" + strings.Join(queryParts, "&")
}
return baseURL, nil
}

View File

@@ -0,0 +1,211 @@
package sqliteconfig
import (
"testing"
)
func TestJournalMode(t *testing.T) {
tests := []struct {
mode JournalMode
valid bool
}{
{JournalModeWAL, true},
{JournalModeDelete, true},
{JournalModeTruncate, true},
{JournalModePersist, true},
{JournalModeMemory, true},
{JournalModeOff, true},
{JournalMode("INVALID"), false},
{JournalMode(""), false},
}
for _, tt := range tests {
t.Run(string(tt.mode), func(t *testing.T) {
if got := tt.mode.IsValid(); got != tt.valid {
t.Errorf("JournalMode(%q).IsValid() = %v, want %v", tt.mode, got, tt.valid)
}
})
}
}
func TestAutoVacuum(t *testing.T) {
tests := []struct {
mode AutoVacuum
valid bool
}{
{AutoVacuumNone, true},
{AutoVacuumFull, true},
{AutoVacuumIncremental, true},
{AutoVacuum("INVALID"), false},
{AutoVacuum(""), false},
}
for _, tt := range tests {
t.Run(string(tt.mode), func(t *testing.T) {
if got := tt.mode.IsValid(); got != tt.valid {
t.Errorf("AutoVacuum(%q).IsValid() = %v, want %v", tt.mode, got, tt.valid)
}
})
}
}
func TestSynchronous(t *testing.T) {
tests := []struct {
mode Synchronous
valid bool
}{
{SynchronousOff, true},
{SynchronousNormal, true},
{SynchronousFull, true},
{SynchronousExtra, true},
{Synchronous("INVALID"), false},
{Synchronous(""), false},
}
for _, tt := range tests {
t.Run(string(tt.mode), func(t *testing.T) {
if got := tt.mode.IsValid(); got != tt.valid {
t.Errorf("Synchronous(%q).IsValid() = %v, want %v", tt.mode, got, tt.valid)
}
})
}
}
func TestConfigValidate(t *testing.T) {
tests := []struct {
name string
config *Config
wantErr bool
}{
{
name: "valid default config",
config: Default("/path/to/db.sqlite"),
},
{
name: "empty path",
config: &Config{
Path: "",
},
wantErr: true,
},
{
name: "negative busy timeout",
config: &Config{
Path: "/path/to/db.sqlite",
BusyTimeout: -1,
},
wantErr: true,
},
{
name: "invalid journal mode",
config: &Config{
Path: "/path/to/db.sqlite",
JournalMode: JournalMode("INVALID"),
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.config.Validate()
if (err != nil) != tt.wantErr {
t.Errorf("Config.Validate() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestConfigToURL(t *testing.T) {
tests := []struct {
name string
config *Config
want string
}{
{
name: "default config",
config: Default("/path/to/db.sqlite"),
want: "file:/path/to/db.sqlite?_pragma=busy_timeout=10000&_pragma=journal_mode=WAL&_pragma=auto_vacuum=INCREMENTAL&_pragma=wal_autocheckpoint=1000&_pragma=synchronous=NORMAL&_pragma=foreign_keys=ON",
},
{
name: "memory config",
config: Memory(),
want: ":memory:?_pragma=foreign_keys=ON",
},
{
name: "minimal config",
config: &Config{
Path: "/simple/db.sqlite",
WALAutocheckpoint: -1, // not set
},
want: "file:/simple/db.sqlite",
},
{
name: "custom config",
config: &Config{
Path: "/custom/db.sqlite",
BusyTimeout: 5000,
JournalMode: JournalModeDelete,
WALAutocheckpoint: -1, // not set
Synchronous: SynchronousFull,
ForeignKeys: true,
},
want: "file:/custom/db.sqlite?_pragma=busy_timeout=5000&_pragma=journal_mode=DELETE&_pragma=synchronous=FULL&_pragma=foreign_keys=ON",
},
{
name: "memory with custom timeout",
config: &Config{
Path: ":memory:",
BusyTimeout: 2000,
WALAutocheckpoint: -1, // not set
ForeignKeys: true,
},
want: ":memory:?_pragma=busy_timeout=2000&_pragma=foreign_keys=ON",
},
{
name: "wal autocheckpoint zero",
config: &Config{
Path: "/test.db",
WALAutocheckpoint: 0,
},
want: "file:/test.db?_pragma=wal_autocheckpoint=0",
},
{
name: "all options",
config: &Config{
Path: "/full.db",
BusyTimeout: 15000,
JournalMode: JournalModeWAL,
AutoVacuum: AutoVacuumFull,
WALAutocheckpoint: 1000,
Synchronous: SynchronousExtra,
ForeignKeys: true,
},
want: "file:/full.db?_pragma=busy_timeout=15000&_pragma=journal_mode=WAL&_pragma=auto_vacuum=FULL&_pragma=wal_autocheckpoint=1000&_pragma=synchronous=EXTRA&_pragma=foreign_keys=ON",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.config.ToURL()
if err != nil {
t.Errorf("Config.ToURL() error = %v", err)
return
}
if got != tt.want {
t.Errorf("Config.ToURL() = %q, want %q", got, tt.want)
}
})
}
}
func TestConfigToURLInvalid(t *testing.T) {
config := &Config{
Path: "",
BusyTimeout: -1,
}
_, err := config.ToURL()
if err == nil {
t.Error("Config.ToURL() with invalid config should return error")
}
}

View File

@@ -0,0 +1,269 @@
package sqliteconfig
import (
"database/sql"
"path/filepath"
"strings"
"testing"
_ "modernc.org/sqlite"
)
const memoryDBPath = ":memory:"
// TestSQLiteDriverPragmaIntegration verifies that the modernc.org/sqlite driver
// correctly applies all pragma settings from URL parameters, ensuring they work
// the same as the old SQL PRAGMA statements approach.
func TestSQLiteDriverPragmaIntegration(t *testing.T) {
tests := []struct {
name string
config *Config
expected map[string]any
}{
{
name: "default configuration",
config: Default("/tmp/test.db"),
expected: map[string]any{
"busy_timeout": 10000,
"journal_mode": "wal",
"auto_vacuum": 2, // INCREMENTAL = 2
"wal_autocheckpoint": 1000,
"synchronous": 1, // NORMAL = 1
"foreign_keys": 1, // ON = 1
},
},
{
name: "memory database with foreign keys",
config: Memory(),
expected: map[string]any{
"foreign_keys": 1, // ON = 1
},
},
{
name: "custom configuration",
config: &Config{
Path: "/tmp/custom.db",
BusyTimeout: 5000,
JournalMode: JournalModeDelete,
AutoVacuum: AutoVacuumFull,
WALAutocheckpoint: 1000,
Synchronous: SynchronousFull,
ForeignKeys: true,
},
expected: map[string]any{
"busy_timeout": 5000,
"journal_mode": "delete",
"auto_vacuum": 1, // FULL = 1
"wal_autocheckpoint": 1000,
"synchronous": 2, // FULL = 2
"foreign_keys": 1, // ON = 1
},
},
{
name: "foreign keys disabled",
config: &Config{
Path: "/tmp/no_fk.db",
ForeignKeys: false,
},
expected: map[string]any{
// foreign_keys should not be set (defaults to 0/OFF)
"foreign_keys": 0,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create temporary database file if not memory
if tt.config.Path == memoryDBPath {
// For memory databases, no changes needed
} else {
tempDir := t.TempDir()
dbPath := filepath.Join(tempDir, "test.db")
// Update config with actual temp path
configCopy := *tt.config
configCopy.Path = dbPath
tt.config = &configCopy
}
// Generate URL and open database
url, err := tt.config.ToURL()
if err != nil {
t.Fatalf("Failed to generate URL: %v", err)
}
t.Logf("Opening database with URL: %s", url)
db, err := sql.Open("sqlite", url)
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
defer db.Close()
// Test connection
if err := db.Ping(); err != nil {
t.Fatalf("Failed to ping database: %v", err)
}
// Verify each expected pragma setting
for pragma, expectedValue := range tt.expected {
t.Run("pragma_"+pragma, func(t *testing.T) {
var actualValue any
query := "PRAGMA " + pragma
err := db.QueryRow(query).Scan(&actualValue)
if err != nil {
t.Fatalf("Failed to query %s: %v", query, err)
}
t.Logf("%s: expected=%v, actual=%v", pragma, expectedValue, actualValue)
// Handle type conversion for comparison
switch expected := expectedValue.(type) {
case int:
if actual, ok := actualValue.(int64); ok {
if int64(expected) != actual {
t.Errorf("%s: expected %d, got %d", pragma, expected, actual)
}
} else {
t.Errorf("%s: expected int %d, got %T %v", pragma, expected, actualValue, actualValue)
}
case string:
if actual, ok := actualValue.(string); ok {
if expected != actual {
t.Errorf("%s: expected %q, got %q", pragma, expected, actual)
}
} else {
t.Errorf("%s: expected string %q, got %T %v", pragma, expected, actualValue, actualValue)
}
default:
t.Errorf("Unsupported expected type for %s: %T", pragma, expectedValue)
}
})
}
})
}
}
// TestForeignKeyConstraintEnforcement verifies that foreign key constraints
// are actually enforced when enabled via URL parameters.
func TestForeignKeyConstraintEnforcement(t *testing.T) {
tempDir := t.TempDir()
dbPath := filepath.Join(tempDir, "fk_test.db")
config := Default(dbPath)
url, err := config.ToURL()
if err != nil {
t.Fatalf("Failed to generate URL: %v", err)
}
db, err := sql.Open("sqlite", url)
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
defer db.Close()
// Create test tables with foreign key relationship
schema := `
CREATE TABLE parent (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE child (
id INTEGER PRIMARY KEY,
parent_id INTEGER NOT NULL,
name TEXT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES parent(id)
);
`
if _, err := db.Exec(schema); err != nil {
t.Fatalf("Failed to create schema: %v", err)
}
// Insert parent record
if _, err := db.Exec("INSERT INTO parent (id, name) VALUES (1, 'Parent 1')"); err != nil {
t.Fatalf("Failed to insert parent: %v", err)
}
// Test 1: Valid foreign key should work
_, err = db.Exec("INSERT INTO child (id, parent_id, name) VALUES (1, 1, 'Child 1')")
if err != nil {
t.Fatalf("Valid foreign key insert failed: %v", err)
}
// Test 2: Invalid foreign key should fail
_, err = db.Exec("INSERT INTO child (id, parent_id, name) VALUES (2, 999, 'Child 2')")
if err == nil {
t.Error("Expected foreign key constraint violation, but insert succeeded")
} else if !contains(err.Error(), "FOREIGN KEY constraint failed") {
t.Errorf("Expected foreign key constraint error, got: %v", err)
} else {
t.Logf("✓ Foreign key constraint correctly enforced: %v", err)
}
// Test 3: Deleting referenced parent should fail
_, err = db.Exec("DELETE FROM parent WHERE id = 1")
if err == nil {
t.Error("Expected foreign key constraint violation when deleting referenced parent")
} else if !contains(err.Error(), "FOREIGN KEY constraint failed") {
t.Errorf("Expected foreign key constraint error on delete, got: %v", err)
} else {
t.Logf("✓ Foreign key constraint correctly prevented parent deletion: %v", err)
}
}
// TestJournalModeValidation verifies that the journal_mode setting is applied correctly.
func TestJournalModeValidation(t *testing.T) {
modes := []struct {
mode JournalMode
expected string
}{
{JournalModeWAL, "wal"},
{JournalModeDelete, "delete"},
{JournalModeTruncate, "truncate"},
{JournalModeMemory, "memory"},
}
for _, tt := range modes {
t.Run(string(tt.mode), func(t *testing.T) {
tempDir := t.TempDir()
dbPath := filepath.Join(tempDir, "journal_test.db")
config := &Config{
Path: dbPath,
JournalMode: tt.mode,
ForeignKeys: true,
}
url, err := config.ToURL()
if err != nil {
t.Fatalf("Failed to generate URL: %v", err)
}
db, err := sql.Open("sqlite", url)
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
defer db.Close()
var actualMode string
err = db.QueryRow("PRAGMA journal_mode").Scan(&actualMode)
if err != nil {
t.Fatalf("Failed to query journal_mode: %v", err)
}
if actualMode != tt.expected {
t.Errorf("journal_mode: expected %q, got %q", tt.expected, actualMode)
} else {
t.Logf("✓ journal_mode correctly set to: %s", actualMode)
}
})
}
}
// contains checks if a string contains a substring (helper function).
func contains(str, substr string) bool {
return strings.Contains(str, substr)
}

View File

@@ -1,7 +1,6 @@
package db
import (
"context"
"log"
"net/url"
"os"
@@ -84,7 +83,7 @@ func newPostgresTestDB(t *testing.T) *HSDatabase {
func newPostgresDBForTest(t *testing.T) *url.URL {
t.Helper()
ctx := context.Background()
ctx := t.Context()
srv, err := postgrestest.Start(ctx)
if err != nil {
t.Fatal(err)

View File

@@ -0,0 +1,59 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-01-20 15:24:32.036023546+00:00','2023-01-20 15:24:32.036023546+00:00',NULL,'test_username');
INSERT INTO users VALUES(2,'2023-01-20 15:24:37.819763186+00:00','2023-01-20 15:24:37.819763186+00:00',NULL,'test_username2');
INSERT INTO users VALUES(3,'2023-03-14 18:44:35.748065603+00:00','2023-03-14 18:44:35.748065603+00:00',NULL,'test_username3');
INSERT INTO users VALUES(4,'2023-10-28 10:11:58.184072133+00:00','2023-10-28 10:11:58.184072133+00:00',NULL,'test_username4');
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,"user_id" integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
INSERT INTO pre_auth_keys VALUES(1,'abc',3,0,0,1,'2023-03-14 18:48:00.276961537+00:00','2023-03-14 19:47:00+00:00');
INSERT INTO pre_auth_keys VALUES(2,'abc',3,0,0,1,'2023-03-19 02:03:37.127380891+00:00','2023-03-19 03:03:00+00:00');
INSERT INTO pre_auth_keys VALUES(3,'abc',3,0,0,1,'2023-07-12 16:29:17.255869839+00:00','2023-07-12 17:29:17.253994971+00:00');
INSERT INTO pre_auth_keys VALUES(4,'abc',4,0,0,0,'2023-10-28 10:12:25.105521216+00:00','2023-10-28 11:12:25.103560646+00:00');
INSERT INTO pre_auth_keys VALUES(5,'abc',4,0,0,1,'2023-10-28 11:19:38.120019211+00:00','2023-10-28 12:19:38.118375437+00:00');
INSERT INTO pre_auth_keys VALUES(6,'abc',4,0,0,1,'2023-10-28 11:47:58.0406679+00:00','2023-10-28 12:47:58.036681164+00:00');
INSERT INTO pre_auth_keys VALUES(7,'abc',4,0,0,1,'2023-10-30 15:14:21.038723484+00:00','2023-10-30 16:14:21.03662712+00:00');
INSERT INTO pre_auth_keys VALUES(8,'abc',4,0,0,1,'2023-10-30 16:18:12.358594006+00:00','2023-10-30 17:18:12.357173229+00:00');
INSERT INTO pre_auth_keys VALUES(9,'abc',4,0,0,1,'2023-10-31 16:00:05.806877017+00:00','2023-10-31 17:00:05.801991493+00:00');
INSERT INTO pre_auth_keys VALUES(10,'abc',1,0,0,1,'2023-10-31 16:17:04.813054795+00:00','2023-10-31 17:17:04.809264757+00:00');
INSERT INTO pre_auth_keys VALUES(11,'abc',1,0,0,1,'2023-11-20 21:03:07.524801178+00:00','2023-11-20 22:03:07.521904023+00:00');
INSERT INTO pre_auth_keys VALUES(12,'abc',1,0,0,1,'2024-01-09 16:53:26.73433598+00:00','2024-01-09 17:53:26.730815243+00:00');
INSERT INTO pre_auth_keys VALUES(13,'abc',1,0,0,0,'2024-01-15 10:57:54.79892743+00:00','2024-01-15 11:57:54.797213855+00:00');
INSERT INTO pre_auth_keys VALUES(14,'abc',3,0,0,1,'2024-02-09 11:11:44.760824633+00:00','2024-02-09 12:11:44.757791384+00:00');
INSERT INTO pre_auth_keys VALUES(15,'abc',1,0,0,1,'2024-02-09 15:58:39.383257853+00:00','2024-02-09 16:58:39.381325589+00:00');
INSERT INTO pre_auth_keys VALUES(16,'abc',3,0,0,1,'2024-02-15 14:28:52.808875211+00:00','2024-02-15 15:28:52.806886242+00:00');
INSERT INTO pre_auth_keys VALUES(17,'abc',3,0,0,1,'2024-03-22 09:14:48.915733965+00:00','2024-03-22 10:14:48.913376104+00:00');
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_addresses` text,`hostname` text,`given_name` varchar(63),"user_id" integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
INSERT INTO machines VALUES(1,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.1','test_hostname','test_given_name',2,'cli','null',0,'2024-08-21 08:40:52.222825283+00:00','2024-08-21 08:18:52.242124403+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-01-20 15:25:20.356129891+00:00','2024-08-21 08:40:52.222881482+00:00',NULL);
INSERT INTO machines VALUES(3,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.3','test_hostname','test_given_name',1,'cli','null',0,'2024-08-21 08:40:56.62914289+00:00','2024-08-21 08:18:46.63998217+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-01-20 15:35:03.370060441+00:00','2024-08-21 08:40:56.629253788+00:00',NULL);
INSERT INTO machines VALUES(6,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.6','test_hostname','test_given_name',3,'authkey','[]',2,'2023-03-20 19:41:31.098518915+00:00','2023-03-20 19:40:35.242992108+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-03-19 02:04:05.008046059+00:00','2023-03-20 19:41:31.098577514+00:00',NULL);
INSERT INTO machines VALUES(9,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.9','test_hostname','test_given_name',1,'cli','null',0,'2024-07-29 13:49:30.299050593+00:00','2024-07-29 13:48:10.308424118+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-07-27 08:56:16.70263804+00:00','2024-07-29 13:49:30.299142293+00:00',NULL);
INSERT INTO machines VALUES(14,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.2','test_hostname','test_given_name',1,'cli','null',0,'2024-08-21 08:40:55.887260826+00:00','2024-08-21 08:18:45.907361083+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-10-10 18:41:13.821106556+00:00','2024-08-21 08:40:55.887344424+00:00',NULL);
INSERT INTO machines VALUES(24,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.16','test_hostname','test_given_name',1,'cli','null',0,'2024-08-21 08:40:53.141335445+00:00','2024-08-21 08:18:43.153446351+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-12-05 10:35:59.888379379+00:00','2024-08-21 08:40:53.141393344+00:00',NULL);
INSERT INTO machines VALUES(26,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.19','test_hostname','test_given_name',1,'authkey','[]',12,'2024-08-21 08:40:53.117322135+00:00','2024-08-21 08:18:43.129839273+00:00','0001-01-01 00:00:00+00:00','{}','[]','2024-01-09 16:54:15.190375117+00:00','2024-08-21 08:40:53.117392533+00:00',NULL);
INSERT INTO machines VALUES(27,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.10','test_hostname','test_given_name',3,'authkey','[]',14,'2024-08-21 08:40:17.737469943+00:00','2024-08-21 08:18:47.747596039+00:00','0001-01-01 00:00:00+00:00','{}','[]','2024-02-09 11:12:06.970690104+00:00','2024-08-21 08:40:17.737524142+00:00',NULL);
INSERT INTO machines VALUES(28,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.5','test_hostname','test_given_name',1,'cli','null',0,'2024-08-16 16:10:15.388306191+00:00','2024-08-16 15:42:50.445601237+00:00','0001-01-01 00:00:00+00:00','{}','[]','2024-02-09 12:05:40.426476827+00:00','2024-08-16 16:10:15.38838619+00:00',NULL);
INSERT INTO machines VALUES(30,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.4','test_hostname','test_given_name',1,'authkey','[]',15,'2024-08-21 08:40:58.279528619+00:00','2024-08-21 08:18:48.290788011+00:00','0001-01-01 00:00:00+00:00','{}','[]','2024-02-09 15:58:53.072455801+00:00','2024-08-21 08:40:58.279725115+00:00',NULL);
INSERT INTO machines VALUES(31,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.7','test_hostname','test_given_name',3,'authkey','[]',16,'2024-08-21 08:40:59.118548501+00:00','2024-08-21 08:18:49.131796048+00:00','0001-01-01 00:00:00+00:00','{}','[]','2024-02-15 14:29:11.751167192+00:00','2024-08-21 08:40:59.118634099+00:00',NULL);
INSERT INTO machines VALUES(32,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.11','test_hostname','test_given_name',1,'cli','null',0,'2024-08-21 08:40:11.534414289+00:00','2024-08-21 08:18:51.548310242+00:00','0001-01-01 00:00:00+00:00','{}','[]','2024-03-05 21:21:27.482961607+00:00','2024-08-21 08:40:11.534488588+00:00',NULL);
INSERT INTO machines VALUES(33,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.12','test_hostname','test_given_name',3,'authkey','[]',17,'2024-07-24 14:02:32.230464112+00:00','2024-07-24 13:58:06.34346502+00:00','0001-01-01 00:00:00+00:00','{}','[]','2024-03-22 09:15:06.999732064+00:00','2024-07-24 14:02:32.230542511+00:00',NULL);
INSERT INTO machines VALUES(34,'f3c6d0e51ae64e6020827a70fb345e8ca1225acfe2e5064b6d3611ed2ffc0a7b','c2ef0d2e0ec342d836e45690c7f6e4b986553b78997e08c55fbe28238283e30f','7808fad26f34fb919895224f80e01979074d8b8af4b81d2fa465134c20795e11','100.64.0.8','test_hostname','test_given_name',1,'cli','null',0,'2024-08-20 18:55:03.645637741+00:00','2024-08-20 18:53:33.573112275+00:00','0001-01-01 00:00:00+00:00','{}','[]','2024-05-12 18:10:18.529512769+00:00','2024-08-20 18:55:03.64569204+00:00',NULL);
CREATE TABLE `routes` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`));
INSERT INTO routes VALUES(1,'2023-06-07 19:33:30.351228569+00:00','2024-02-09 12:12:46.846169943+00:00',NULL,1,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(2,'2023-06-07 19:33:30.374825485+00:00','2024-02-09 12:12:46.85904672+00:00',NULL,1,'::/0',1,1,0);
INSERT INTO routes VALUES(3,'2023-06-07 19:40:59.371440019+00:00','2024-02-09 12:12:50.579469958+00:00',NULL,1,'10.9.110.0/24',1,1,1);
INSERT INTO routes VALUES(6,'2024-01-09 16:54:15.230556693+00:00','2024-01-09 16:56:18.454994668+00:00',NULL,26,'172.100.100.0/24',1,1,1);
INSERT INTO routes VALUES(7,'2024-01-09 16:54:15.244301546+00:00','2024-01-09 16:54:15.244301546+00:00',NULL,26,'172.100.100.0/24',1,0,0);
INSERT INTO routes VALUES(8,'2024-02-15 14:29:11.80450206+00:00','2024-02-15 14:31:33.693110756+00:00',NULL,31,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(9,'2024-02-15 14:29:11.819498226+00:00','2024-02-15 14:29:11.819498226+00:00',NULL,31,'0.0.0.0/0',1,0,0);
INSERT INTO routes VALUES(10,'2024-02-15 14:29:11.83141704+00:00','2024-02-15 14:31:33.710242987+00:00',NULL,31,'::/0',1,1,0);
INSERT INTO routes VALUES(11,'2024-02-15 14:29:11.843494351+00:00','2024-02-15 14:29:11.843494351+00:00',NULL,31,'::/0',1,0,0);
INSERT INTO routes VALUES(12,'2024-08-16 14:58:46.162834956+00:00','2024-08-16 14:59:46.380224608+00:00',NULL,32,'192.168.0.24/32',1,1,1);
CREATE TABLE `kvs` (`key` text,`value` text);
CREATE TABLE `pre_auth_key_acl_tags` (`id` integer,`pre_auth_key_id` integer,`tag` text,PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON "users"(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
COMMIT;

View File

@@ -0,0 +1,52 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_addresses` text,`hostname` text,`given_name` varchar(63),"user_id" integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
INSERT INTO machines VALUES(2,'dda8a58fa5db0d02a7351518342b1c1b6c57be2300e9d2c2600b42310c272560','8133aaff1056f74ba062d65ed71c619531b0d8bb3f455f9623ca62b21c765796','d5d8b487956f8ab8186682cd1cc8b1c0d1f38df3e0af2f1e100db219d72d05ca','fd7a:115c:a1e0::2,100.64.0.2','user6','user6',2,'oidc',NULL,0,'2023-08-10 20:39:17.723753+00:00','2023-08-10 20:38:29.407452+00:00','2023-08-11 04:31:47.962903+00:00','{"IPNVersion":"1.46.1-te42e60103-g4cea91365","BackendLogID":"3b49a2a5ab87c374de316f31901b27386e91803b577512c47fb770c4c2491f62","OS":"macOS","OSVersion":"12.6.8","Package":"IPNExtension","DeviceModel":"MacBookPro16,1","Hostname":"user6","Machine":"x86_64","GoArch":"amd64","GoArchVar":"v1","GoVersion":"go1.21rc3","Services":[{"Proto":"peerapi6","Port":47166},{"Proto":"peerapi4","Port":46590},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":false,"HairPinning":false,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":true,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":2,"DERPLatency":{"1-v4":0.113968906,"10-v4":0.023436893,"11-v4":0.198267412,"12-v4":0.061961581,"13-v4":0.031651191,"14-v4":0.146547143,"16-v4":0.114270957,"17-v4":0.023428486,"18-v4":0.144492636,"19-v4":0.150996698,"2-v4":0.012436127,"20-v4":0.166397065,"21-v4":0.064436639,"22-v4":0.169095616,"24-v4":0.070928559,"3-v4":0.197250582,"4-v4":0.162028147,"5-v4":0.220367619,"6-v4":0.225762119,"7-v4":0.114449341,"8-v4":0.135539131,"9-v4":0.054314979}},"Userspace":false,"UserspaceRouter":true}','["67.58.239.134:41641","192.168.2.63:41641"]','2023-08-08 03:42:32.227355+00:00','2023-08-11 04:31:47.968673+00:00',NULL);
INSERT INTO machines VALUES(13,'5418566216128c1d55cb729d08b020c0948a4974c7ec8631ca2d87c94a57c62f','2df745735e7a024f59385687404555917d904c0cc6b2b4c376d86005fa0c50e9','bc23afab27bd633c993e5feb0cbc64b463bd06bd74e5b0ed34aa0c59db1241cc','fd7a:115c:a1e0::1,100.64.0.1','private-access','private-access',1,'authkey','["tag:routers-general"]',2,'2024-08-21 09:10:42.082477+00:00','2024-08-21 09:10:42.124509+00:00','0001-01-01 00:00:00+00:00','{"IPNVersion":"1.68.1-t92eacec73","BackendLogID":"ace1ce1f1029d84582595b60a979159f7ffc2d088c58bc58ce957d5b5d76ab65","OS":"linux","OSVersion":"6.1.102-111.182.amzn2023.aarch64","Container":true,"Distro":"alpine","DistroVersion":"3.18.6","Desktop":false,"Hostname":"private-access","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.22.4","RoutableIPs":["0.0.0.0/0","::/0","10.0.0.0/8","10.18.80.2/32"],"Services":[{"Proto":"peerapi6","Port":59780},{"Proto":"peerapi4","Port":58436},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":false,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":true,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":10,"DERPLatency":{"1-v4":0.072225784,"10-v4":0.006838935,"11-v4":0.190929032,"12-v4":0.059929235,"13-v4":0.034135764,"14-v4":0.160624902,"16-v4":0.081274428,"17-v4":0.027732861,"18-v4":0.152569261,"19-v4":0.156006631,"2-v4":0.021369602,"20-v4":0.191327522,"21-v4":0.072034124,"22-v4":0.17290295,"23-v4":0.24451928,"24-v4":0.07036978,"3-v4":0.218839858,"4-v4":0.154432955,"5-v4":0.205852211,"7-v4":0.106623559,"8-v4":0.142767263,"9-v4":0.055452594}},"Cloud":"aws","Userspace":false,"UserspaceRouter":false}','["54.218.81.157:55438","10.18.95.117:55438","172.17.0.1:55438"]','2023-08-09 07:25:28.410294+00:00','2024-08-21 09:10:42.125774+00:00',NULL);
INSERT INTO machines VALUES(14,'45b7283a09376c6e4a0e91c791cd7ed62d3ab67af04e2ab65ea769f13b5d01a8','3f122817b7daec63358d7f32037157cc0742b236ebe10159200e04661846dc12','ca8c018c9a84e1ee5bea886b353b85a1cbc41b26bad1a8ea09250a73ee3bc224','fd7a:115c:a1e0::3,100.64.0.3','user5','user5',2,'oidc',NULL,0,'2023-09-05 20:17:56.144957+00:00','2023-09-05 20:17:15.131619+00:00','2023-09-02 02:14:29.91958+00:00','{"IPNVersion":"1.48.1-t528f95da6-gc4e4acad7","BackendLogID":"105b508bb534b33b1fbbfcab5d1b35b2f8aa14898f7f1deb79f82a0b4556a337","OS":"macOS","OSVersion":"12.6.8","Package":"IPNExtension","DeviceModel":"MacBookPro16,1","Hostname":"user5","Machine":"x86_64","GoArch":"amd64","GoArchVar":"v1","GoVersion":"go1.21.0","Services":[{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":false,"HairPinning":false,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":true,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":2,"DERPLatency":{"1-v4":0.110587393,"10-v4":0.021509598,"11-v4":0.196329449,"12-v4":0.059015905,"13-v4":0.028908204,"14-v4":0.14475452,"16-v4":0.089070015,"17-v4":0.021616309,"18-v4":0.14320796,"19-v4":0.144814647,"2-v4":0.010198952,"20-v4":0.164708226,"21-v4":0.110530864,"22-v4":0.169718648,"24-v4":0.110470627,"3-v4":0.198647468,"4-v4":0.162606553,"5-v4":0.218460376,"6-v4":0.23733193,"7-v4":0.114587062,"8-v4":0.140155524,"9-v4":0.052894305}},"Userspace":false,"UserspaceRouter":true}','["67.58.239.134:41641","192.168.2.63:41641"]','2023-08-10 20:41:58.499623+00:00','2023-09-05 20:17:56.146062+00:00',NULL);
INSERT INTO machines VALUES(15,'46b10c2ee93b1da403a87d7d57eecd9b3bf47ce58425742bc44bb8967984f3e9','35e6f69d23d17c13c48c45c0b74d1c3db85b21736151bcc06933939dface88b0','393ae3076213aae7a3ac11bc08fb0ad5c690ee5c50a4522f209fb5b018ecc958','fd7a:115c:a1e0::4,100.64.0.4','user3','user3',3,'oidc',NULL,0,'2023-09-06 02:43:29.503895+00:00','2023-09-06 02:43:49.511926+00:00','2023-09-06 23:17:20.322291+00:00','{"IPNVersion":"1.46.1-te42e60103-g4cea91365","BackendLogID":"8f10b84dbe2a45b68242bbf236952cfe88fdce68de11d6c21d4ea9b6a3cbe0e4","OS":"macOS","OSVersion":"13.5.0","Package":"IPNExtension","DeviceModel":"MacBookPro16,1","Hostname":"user3","Machine":"x86_64","GoArch":"amd64","GoArchVar":"v1","GoVersion":"go1.21rc3","Services":[{"Proto":"peerapi6","Port":40203},{"Proto":"peerapi4","Port":37067},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":false,"HairPinning":false,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":true,"WorkingICMPv4":false,"UPnP":true,"PMP":false,"PCP":false,"PreferredDERP":13,"DERPLatency":{"12-v4":0.026085574,"13-v4":0.00640859,"9-v4":0.024989145}},"Userspace":false,"UserspaceRouter":true}','["8.36.226.139:41641","192.168.5.49:41641"]','2023-08-10 21:11:29.400994+00:00','2023-09-06 02:43:49.512388+00:00',NULL);
INSERT INTO machines VALUES(16,'785f4b01cbbafb26f69acc95913f87c18f91b400526a8fea867e57d1f6979199','26ff15bb8b839d2648dd5ec3dd751c31a96c56604c9bcc7865dad2a285092b11','03dd9981e5e2b580dfc7c4fc6614e99dfa44671810a04f43b351d4a081fedfd7','fd7a:115c:a1e0::5,100.64.0.5','user1','user1',4,'oidc',NULL,0,'2023-09-06 02:44:13.123335+00:00','2023-09-06 02:43:43.131322+00:00','2023-09-06 22:13:57.020939+00:00','{"IPNVersion":"1.48.1-t528f95da6-gc4e4acad7","BackendLogID":"40e9bb1b2cc2f8a56648c6a892cfc00c0f03d2457822a59606e95d75a1e82fec","OS":"macOS","OSVersion":"13.5.0","Package":"IPNExtension","DeviceModel":"MacBookPro15,1","Hostname":"user1","Machine":"x86_64","GoArch":"amd64","GoArchVar":"v1","GoVersion":"go1.21.0","Services":[{"Proto":"peerapi6","Port":44445},{"Proto":"peerapi4","Port":41053},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":false,"HairPinning":false,"WorkingIPv6":true,"OSHasIPv6":true,"WorkingUDP":true,"WorkingICMPv4":false,"HavePortMap":true,"UPnP":true,"PMP":false,"PCP":false,"PreferredDERP":2,"DERPLatency":{"10-v4":0.178866462,"17-v4":0.17890099,"17-v6":0.178871041,"2-v4":0.083849135,"2-v6":0.085625895}},"Userspace":false,"UserspaceRouter":true}','["73.241.238.118:59407","73.241.238.118:57965","[2601:646:c500:3ad0:694f:e60a:54dd:9236]:41641","73.241.238.118:11709","73.241.238.118:41902","73.241.238.118:57674","73.241.238.118:41641","10.0.0.158:57965","[2601:646:c500:3ad0::670e]:57965","[2601:646:c500:3ad0:ce6:7064:450d:a01a]:57965","[2601:646:c500:3ad0:694f:e60a:54dd:9236]:57965"]','2023-08-10 23:58:34.357314+00:00','2023-09-06 02:44:13.123879+00:00',NULL);
INSERT INTO machines VALUES(17,'85892b41a04ffab78009c9129a87006e9af9335d4e3521939acddfb5a3edc0f1','7e7d018c338666e72b3b5ec2cc5e987bb294a88320740f07c9a337f07c2228b6','96425c4e4c62419e780b920f117183b77be80bc370f3d528bbd0bf4384703f2f','fd7a:115c:a1e0::6,100.64.0.6','user4','user4',2,'oidc',NULL,0,'2023-09-12 22:58:03.464908+00:00','2023-09-12 22:58:03.37758+00:00','2023-09-12 22:58:08.958716+00:00','{"IPNVersion":"1.48.1-t528f95da6-gc4e4acad7","BackendLogID":"5feae6bec74c6b933912936cfe4647f220d31d4aae9595838e0d5ab93c6ae277","OS":"macOS","OSVersion":"13.5.2","Package":"IPNExtension","DeviceModel":"MacBookPro18,1","Hostname":"user4","NoLogsNoSupport":true,"Machine":"arm64","GoArch":"arm64","GoVersion":"go1.21.0","Services":[{"Proto":"peerapi6","Port":64551},{"Proto":"peerapi4","Port":61927},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":false,"HairPinning":false,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":true,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":2,"DERPLatency":{"10-v4":0.021871917,"17-v4":0.072667291,"2-v4":0.010047084}},"Userspace":false,"UserspaceRouter":true}','["67.58.239.134:41641","192.168.2.205:41641"]','2023-08-24 06:16:01.898323+00:00','2023-09-12 22:58:08.961416+00:00',NULL);
INSERT INTO machines VALUES(18,'d1b2d75439d096b762a8c197377a37c7e771edd51f2a2146114af94756afa696','2da1fa2a8beeed09aede703c44b045bdb21a8819e505b91ed54b66599a3d61e4','37ad3823ffdada188c1710388f1cd242646e66a60d7554f38e069d8df90b064f','fd7a:115c:a1e0::7,100.64.0.7','user7','user7',3,'oidc',NULL,0,'2023-09-14 03:45:00.450227+00:00','2023-09-14 03:44:59.144507+00:00','2023-09-13 22:23:33.608107+00:00','{"IPNVersion":"1.48.1-t528f95da6-gc4e4acad7","BackendLogID":"fdcd2df9a10448a038e3afbdd166762d8917c2f10f4d49c2d257c2269f7a3ef3","OS":"macOS","OSVersion":"13.5.2","Package":"IPNExtension","DeviceModel":"MacBookPro16,1","Hostname":"user7","NoLogsNoSupport":true,"Machine":"x86_64","GoArch":"amd64","GoArchVar":"v1","GoVersion":"go1.21.0","Services":[{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":false,"HairPinning":false,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":true,"WorkingICMPv4":false,"UPnP":true,"PMP":false,"PCP":false,"PreferredDERP":13,"DERPLatency":{"1-v4":0.106408989,"10-v4":0.03490791,"11-v4":0.175664039,"12-v4":0.025765898,"13-v4":0.006238122,"14-v4":0.113346949,"16-v4":0.047132419,"17-v4":0.034994123,"18-v4":0.117520649,"19-v4":0.114357219,"2-v4":0.031949238,"20-v4":0.186615346,"21-v4":0.035247054,"22-v4":0.130433232,"23-v4":0.219779149,"24-v4":0.077523355,"3-v4":0.195639797,"4-v4":0.123427047,"5-v4":0.172791876,"6-v4":0.249922387,"7-v4":0.11796353,"8-v4":0.108542864,"9-v4":0.025837496}},"Userspace":false,"UserspaceRouter":true}','["8.36.226.139:41641","192.168.5.49:41641"]','2023-09-12 17:26:45.871277+00:00','2023-09-14 03:45:00.451656+00:00',NULL);
INSERT INTO machines VALUES(19,'0509c7634a68d962a11eb677b0914303e626af043ec1fe4e12c2dc5d45516cb8','5ba0a0384cffe3faf0a050ad8c5bd73a508faa63441b0fb8502c57313a4c523f','12d047ca5a667e2f4a02ac77994c3b6bd85359efa3810df372c0aad3a576a018','fd7a:115c:a1e0::8,100.64.0.8','user2','user2',2,'oidc','null',0,'2024-07-05 23:25:37.618298+00:00','2024-07-05 23:25:37.386862+00:00','2024-07-06 23:07:22.092685+00:00','{"IPNVersion":"1.68.2-tc79c500c7","BackendLogID":"047f3d6f49ca7c0990ff0084cb14f3aa3b8c41d40e4979ae7626d267bf8bca73","OS":"macOS","Package":"tailscaled","Hostname":"user2","Machine":"arm64","GoArch":"arm64","GoVersion":"go1.22.4","Services":[{"Proto":"peerapi-dns-proxy","Port":1}],"Userspace":false,"UserspaceRouter":true}','["156.47.240.192:61820","192.168.2.205:61820"]','2024-07-05 23:07:20.301108+00:00','2024-07-06 23:07:22.101717+00:00',NULL);
CREATE TABLE `kvs` (`key` text,`value` text);
INSERT INTO kvs VALUES('db_version','1');
CREATE TABLE `pre_auth_key_acl_tags` (`id` integer,`pre_auth_key_id` integer,`tag` text,PRIMARY KEY (`id`));
INSERT INTO pre_auth_key_acl_tags VALUES(1,1,'tag:routers-general');
INSERT INTO pre_auth_key_acl_tags VALUES(2,2,'tag:routers-general');
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,"user_id" integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
INSERT INTO pre_auth_keys VALUES(1,'832bf4265e26f5a5d4ea3593f652ed0df64cf9250f70ee23',1,'t','t','t','2023-08-08 01:52:38.951578+00:00','2033-08-05 01:52:38.949719+00:00');
INSERT INTO pre_auth_keys VALUES(2,'c304da0964e5ff7b299a6426b413ad729b898bc2c2d829aa',1,'f','f','t','2023-08-09 07:12:47.593913+00:00','2023-08-09 08:12:47.591239+00:00');
CREATE TABLE `routes` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`));
INSERT INTO routes VALUES(1,'2023-08-08 03:37:36.017468+00:00','2023-08-08 03:37:36.031681+00:00',NULL,1,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(2,'2023-08-08 03:37:36.021527+00:00','2023-08-08 03:37:36.035791+00:00',NULL,1,'::/0',1,1,0);
INSERT INTO routes VALUES(3,'2023-08-08 04:30:41.584823+00:00','2023-08-08 04:30:41.597683+00:00',NULL,3,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(4,'2023-08-08 04:30:41.589517+00:00','2023-08-08 04:30:41.601622+00:00',NULL,3,'::/0',1,1,0);
INSERT INTO routes VALUES(7,'2023-08-08 15:23:37.871901+00:00','2023-08-08 15:23:37.883309+00:00',NULL,5,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(8,'2023-08-08 15:23:37.874743+00:00','2023-08-08 15:23:37.886933+00:00',NULL,5,'::/0',1,1,0);
INSERT INTO routes VALUES(9,'2023-08-09 02:32:42.366585+00:00','2023-08-09 02:32:42.377397+00:00',NULL,6,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(10,'2023-08-09 02:32:42.368994+00:00','2023-08-09 02:32:42.37993+00:00',NULL,6,'::/0',1,1,0);
INSERT INTO routes VALUES(11,'2023-08-09 02:32:42.370746+00:00','2023-08-09 02:32:42.370746+00:00',NULL,6,'10.0.0.0/8',1,0,0);
INSERT INTO routes VALUES(12,'2023-08-09 02:55:13.294542+00:00','2023-08-09 02:55:13.307086+00:00',NULL,7,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(13,'2023-08-09 02:55:13.297551+00:00','2023-08-09 02:55:13.310197+00:00',NULL,7,'::/0',1,1,0);
INSERT INTO routes VALUES(14,'2023-08-09 02:55:13.299975+00:00','2023-08-09 02:55:13.299975+00:00',NULL,7,'10.0.0.0/8',1,0,0);
INSERT INTO routes VALUES(89,'2023-08-09 05:10:16.439999+00:00','2023-08-09 05:10:16.455326+00:00',NULL,9,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(90,'2023-08-09 05:10:16.445257+00:00','2023-08-09 05:10:16.458885+00:00',NULL,9,'::/0',1,1,0);
INSERT INTO routes VALUES(91,'2023-08-09 05:10:16.448348+00:00','2023-08-09 06:18:14.219819+00:00',NULL,9,'10.0.0.0/8',1,1,0);
INSERT INTO routes VALUES(166,'2023-08-09 06:18:09.248571+00:00','2023-08-09 06:18:09.262669+00:00',NULL,11,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(167,'2023-08-09 06:18:09.251732+00:00','2023-08-09 06:18:09.266107+00:00',NULL,11,'::/0',1,1,0);
INSERT INTO routes VALUES(168,'2023-08-09 06:18:09.253883+00:00','2023-08-09 06:18:14.222585+00:00',NULL,11,'10.0.0.0/8',1,1,1);
INSERT INTO routes VALUES(169,'2023-08-09 06:34:33.350442+00:00','2023-08-09 06:34:33.361231+00:00',NULL,12,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(170,'2023-08-09 06:34:33.352935+00:00','2023-08-09 06:34:33.364731+00:00',NULL,12,'::/0',1,1,0);
INSERT INTO routes VALUES(171,'2023-08-09 06:34:33.354735+00:00','2023-08-09 06:34:33.354735+00:00',NULL,12,'10.0.0.0/8',1,0,0);
INSERT INTO routes VALUES(172,'2023-08-09 07:25:28.459499+00:00','2023-08-09 07:25:28.459499+00:00',NULL,13,'10.0.0.0/8',1,0,0);
INSERT INTO routes VALUES(173,'2023-08-09 07:25:28.465389+00:00','2023-08-09 07:25:28.506247+00:00',NULL,13,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(174,'2023-08-09 07:25:28.473006+00:00','2023-08-09 07:25:28.51642+00:00',NULL,13,'::/0',1,1,0);
INSERT INTO routes VALUES(175,'2023-08-11 22:09:28.25414+00:00','2023-08-11 22:09:30.021129+00:00',NULL,13,'10.18.80.2/32',1,1,1);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-08-08 01:46:05.562873+00:00','2023-08-08 01:46:05.562873+00:00',NULL,'routers');
INSERT INTO users VALUES(2,'2023-08-08 03:42:32.218269+00:00','2023-08-08 03:42:32.218269+00:00',NULL,'user2');
INSERT INTO users VALUES(3,'2023-08-10 21:11:29.386521+00:00','2023-08-10 21:11:29.386521+00:00',NULL,'user3');
INSERT INTO users VALUES(4,'2023-08-10 23:58:34.343848+00:00','2023-08-10 23:58:34.343848+00:00',NULL,'user4');
COMMIT;

View File

@@ -0,0 +1,40 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
CREATE TABLE `users` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text,CONSTRAINT `uni_users_name` UNIQUE (`name`));
INSERT INTO users VALUES(1,'2024-09-27 14:26:08.573622915+00:00','2024-09-27 14:26:08.573622915+00:00',NULL,'user2');
INSERT INTO users VALUES(2,'2024-09-27 14:26:17.094350688+00:00','2024-09-27 14:26:17.094350688+00:00',NULL,'user1');
CREATE TABLE `pre_auth_keys` (`id` integer PRIMARY KEY AUTOINCREMENT,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'3d133ec953e31fd41edbd935371234f762b4bae300cea618',1,1,0,1,'2024-09-27 14:26:14.737869796+00:00','2024-09-28 14:26:14.736601748+00:00');
INSERT INTO pre_auth_keys VALUES(2,'9813cc1df1832259fb6322dad788bb9bec89d8a01eef683a',2,1,0,1,'2024-09-27 14:26:23.181049239+00:00','2024-09-28 14:26:23.179903567+00:00');
CREATE TABLE `routes` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
CREATE TABLE `pre_auth_key_acl_tags` (`id` integer PRIMARY KEY AUTOINCREMENT,`pre_auth_key_id` integer,`tag` text,CONSTRAINT `fk_pre_auth_keys_acl_tags` FOREIGN KEY (`pre_auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE CASCADE);
CREATE TABLE `api_keys` (`id` integer PRIMARY KEY AUTOINCREMENT,`prefix` text,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime);
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer PRIMARY KEY AUTOINCREMENT,`machine_key` text,`node_key` text,`disco_key` text,`endpoints` text,`host_info` text,`hostinfo` text,`ipv4` text,`ipv6` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:1efe4388236c1c83fe0a19d3ce7c321ab81e138a4da57917c231ce4c01944409','nodekey:4091de8ee569b46a0cf322ae7350e80f3af4ccfd6d83a27ad4ce455982bd0f52','discokey:0ec0a701b7596a230fff993483c12019951899920fbc1eefa90f73f05147ea20','["172.19.0.5:50477"]','{"IPNVersion":"1.74.1-t0ca17be4a","BackendLogID":"ef6d8598273807218f7589f6c957f09d0caa2c146b71a22ab417bc2cd2c61e32","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.9","Desktop":false,"Package":"container","Hostname":"ts-1-74-9r0gv5","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.1","Services":[{"Proto":"peerapi4","Port":48783},{"Proto":"peerapi6","Port":61271},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.74.1-t0ca17be4a","BackendLogID":"ef6d8598273807218f7589f6c957f09d0caa2c146b71a22ab417bc2cd2c61e32","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.9","Desktop":false,"Package":"container","Hostname":"ts-1-74-9r0gv5","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.1","Services":[{"Proto":"peerapi4","Port":48783},{"Proto":"peerapi6","Port":61271},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.75.24.109','fd7a:115c:a1e0:6558:d71d:c420:6693:2137','ts-1-74-9r0gv5','ts-1-74-9r0gv5',1,'authkey','[]',1,'2024-09-27 14:26:16.86266134+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:14.818308317+00:00','2024-09-27 14:26:16.865671604+00:00',NULL);
INSERT INTO nodes VALUES(2,'mkey:779766343bd0311dd043e61f4e5ab13b43dbd9fef3c243aad406aac43146f566','nodekey:ae80297e118d23f00e029c89c82c53cf575803c40e0dfab5bf3f34213b265731','discokey:591540881c8a783dcfeeb1dbe049ce9a9b74347b6a96c0f17452735cb1de6c2f','["172.19.0.9:59415"]','{"IPNVersion":"1.73.0-dev20240911-t98f4dd985","BackendLogID":"98d5b64d1713a8048c260dc0a18d453bae0f144fdcccb31445356d30ef890a0b","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.9","Desktop":false,"Hostname":"ts-head-2rx0pf","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.1","Services":[{"Proto":"peerapi4","Port":62304},{"Proto":"peerapi6","Port":58495},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.73.0-dev20240911-t98f4dd985","BackendLogID":"98d5b64d1713a8048c260dc0a18d453bae0f144fdcccb31445356d30ef890a0b","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.9","Desktop":false,"Hostname":"ts-head-2rx0pf","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.1","Services":[{"Proto":"peerapi4","Port":62304},{"Proto":"peerapi6","Port":58495},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.66.134.61','fd7a:115c:a1e0:9f2a:7124:e520:c18e:1a70','ts-head-2rx0pf','ts-head-2rx0pf',1,'authkey','[]',1,'2024-09-27 14:26:16.872651222+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:14.824358847+00:00','2024-09-27 14:26:16.875317527+00:00',NULL);
INSERT INTO nodes VALUES(3,'mkey:233ecd117c36c1e5a635b1658fd54369fddf38b5312adf8aae38dfe6506fdf47','nodekey:2a53f1bbefae24a4724201379a05d32c84fc8c86fb2c856334a904ac53a3b827','discokey:acda4e99407eed3b807b81649998d69f93e9c28ce6e4dc1032686b45a70bca09','["172.19.0.6:38747"]','{"IPNVersion":"1.72.1-tf4a95663c","BackendLogID":"6d2ed9adf12339635cbe3098b0000898e1206217be28203e914c561b48d18d14","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.8","Desktop":false,"Package":"container","Hostname":"ts-1-72-tiaqxm","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.22.5","Services":[{"Proto":"peerapi4","Port":35537},{"Proto":"peerapi6","Port":52493},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.72.1-tf4a95663c","BackendLogID":"6d2ed9adf12339635cbe3098b0000898e1206217be28203e914c561b48d18d14","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.8","Desktop":false,"Package":"container","Hostname":"ts-1-72-tiaqxm","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.22.5","Services":[{"Proto":"peerapi4","Port":35537},{"Proto":"peerapi6","Port":52493},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.122.53.94','fd7a:115c:a1e0:7ff3:3849:312e:e0ce:b130','ts-1-72-tiaqxm','ts-1-72-tiaqxm',1,'authkey','[]',1,'2024-09-27 14:26:16.876448699+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:14.826628358+00:00','2024-09-27 14:26:16.877346245+00:00',NULL);
INSERT INTO nodes VALUES(4,'mkey:faa7947734ef7763fd18f23502b934d53d6f8120f6ff95dd3fd1efcda16b9b60','nodekey:2b463a60a90b18a43b64aab223e1f52887d67579b645eec44489c51ff0246e59','discokey:a4a8a7340733bc6fd01f9e3932e2c76311b06e63ed6d5f014e703bd02d664923','["172.19.0.4:40007"]','{"IPNVersion":"1.58.2-tb0e1bbb62","BackendLogID":"d136d72e6814dece6a96d1be183c76365a2998969a33b6dbcbcfa3fbc36c3441","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.5","Desktop":false,"Hostname":"ts-1-58-1nvqo9","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.21.5","Services":[{"Proto":"peerapi4","Port":39487},{"Proto":"peerapi6","Port":54215},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.58.2-tb0e1bbb62","BackendLogID":"d136d72e6814dece6a96d1be183c76365a2998969a33b6dbcbcfa3fbc36c3441","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.5","Desktop":false,"Hostname":"ts-1-58-1nvqo9","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.21.5","Services":[{"Proto":"peerapi4","Port":39487},{"Proto":"peerapi6","Port":54215},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.81.207.12','fd7a:115c:a1e0:6eab:4356:d2b2:3ec6:db5e','ts-1-58-1nvqo9','ts-1-58-1nvqo9',1,'authkey','[]',1,'2024-09-27 14:26:16.867951657+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:14.830098209+00:00','2024-09-27 14:26:16.872950015+00:00',NULL);
INSERT INTO nodes VALUES(5,'mkey:1dc2e7d2021e5e0ecfd5769e007088c570c24f92d72f8c81e9cbafaf651c321e','nodekey:ffde0f4d4b9a2365e2c62c47e86597565c7f95a47f0efe3468501d45e844cf31','discokey:aca5c0f12ea887b46ec89d4a2f5759587689a33757026760557bc9cf94979f4d','["172.19.0.7:46344"]','{"IPNVersion":"1.56.1-tf1ea3161a","BackendLogID":"c6ebd81c20af7b4aa066b458c48232d155b39b4cf2f51eb2247fdf75b7f133f6","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.5","Desktop":false,"Hostname":"ts-1-56-z9manh","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.21.5","Services":[{"Proto":"peerapi4","Port":58612},{"Proto":"peerapi6","Port":41402},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.56.1-tf1ea3161a","BackendLogID":"c6ebd81c20af7b4aa066b458c48232d155b39b4cf2f51eb2247fdf75b7f133f6","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.5","Desktop":false,"Hostname":"ts-1-56-z9manh","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.21.5","Services":[{"Proto":"peerapi4","Port":58612},{"Proto":"peerapi6","Port":41402},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.66.133.106','fd7a:115c:a1e0:fbd2:e73f:b9c7:6f65:b22f','ts-1-56-z9manh','ts-1-56-z9manh',1,'authkey','[]',1,'2024-09-27 14:26:16.878707293+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:14.830352877+00:00','2024-09-27 14:26:16.878994587+00:00',NULL);
INSERT INTO nodes VALUES(6,'mkey:a6b1a81c08622e5ba6ce0411be5d7a4a1cc9c56e1e2cb255a1411540a0353c5c','nodekey:951c0e942b007a32eada6c4de231537a49144ff36144ba09989142e48400aa72','discokey:a3addac173e10230313a823b88444fd082183dbd7a13b503c70eba1766ee5b5f','["172.19.0.8:40676"]','{"IPNVersion":"1.73.100-t7dcf65a10","BackendLogID":"352b9c938ef6fffd1e9d7b357370a9413abf57590c97f2176684b0572426c72c","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.8","Desktop":false,"Package":"container","Hostname":"ts-unstable-qxkobr","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.0","Services":[{"Proto":"peerapi4","Port":56973},{"Proto":"peerapi6","Port":51259},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.73.100-t7dcf65a10","BackendLogID":"352b9c938ef6fffd1e9d7b357370a9413abf57590c97f2176684b0572426c72c","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.8","Desktop":false,"Package":"container","Hostname":"ts-unstable-qxkobr","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.0","Services":[{"Proto":"peerapi4","Port":56973},{"Proto":"peerapi6","Port":51259},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.90.160.114','fd7a:115c:a1e0:8f5b:5b4c:2619:eb78:588d','ts-unstable-qxkobr','ts-unstable-qxkobr',1,'authkey','[]',1,'2024-09-27 14:26:16.872053136+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:14.846863625+00:00','2024-09-27 14:26:16.873881395+00:00',NULL);
INSERT INTO nodes VALUES(7,'mkey:49add8704a1d2ed2981cff46ca48eb8ebaf3c8c454b9b8ad23ad1f9e422aff48','nodekey:8fea100f6c7f4ad2d8104701611d1e071f3b7f97a74e447a668e8de15547e126','discokey:73ca6a00fbcd8d630566f9329c82c9a3d024430cdfec638347e87ad19add737d','["172.19.0.13:44781"]','{"IPNVersion":"1.58.2-tb0e1bbb62","BackendLogID":"40d54901b911fd583dfb54bbf328450fa1da24291a65c68a1b6799808e2c2952","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.5","Desktop":false,"Hostname":"ts-1-58-fvd14i","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.21.5","Services":[{"Proto":"peerapi4","Port":57976},{"Proto":"peerapi6","Port":55540},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.58.2-tb0e1bbb62","BackendLogID":"40d54901b911fd583dfb54bbf328450fa1da24291a65c68a1b6799808e2c2952","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.5","Desktop":false,"Hostname":"ts-1-58-fvd14i","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.21.5","Services":[{"Proto":"peerapi4","Port":57976},{"Proto":"peerapi6","Port":55540},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.104.229.213','fd7a:115c:a1e0:2652:4049:544d:31b3:7e65','ts-1-58-fvd14i','ts-1-58-fvd14i',2,'authkey','[]',2,'2024-09-27 14:26:25.289265425+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:23.255563272+00:00','2024-09-27 14:26:25.293329154+00:00',NULL);
INSERT INTO nodes VALUES(8,'mkey:232725e99c1aa8f275259e6a88e59f77d3e5a8644f987c3be56b9a9d8b0b6803','nodekey:9fff7b41b1e7739214078737b4d473518509916fd429f37dbcd21538cb420413','discokey:184f4a42db7e71f4c002befb59fe200aada0514b3290d4609258797f414c4246','["172.19.0.12:40625"]','{"IPNVersion":"1.74.1-t0ca17be4a","BackendLogID":"40d20ee5cc6374aecea21b6d996be3dddfde1a14a72f43b88abcf54ac4dc7393","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.9","Desktop":false,"Package":"container","Hostname":"ts-1-74-m8xzkz","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.1","Services":[{"Proto":"peerapi4","Port":50864},{"Proto":"peerapi6","Port":57864},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.74.1-t0ca17be4a","BackendLogID":"40d20ee5cc6374aecea21b6d996be3dddfde1a14a72f43b88abcf54ac4dc7393","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.9","Desktop":false,"Package":"container","Hostname":"ts-1-74-m8xzkz","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.1","Services":[{"Proto":"peerapi4","Port":50864},{"Proto":"peerapi6","Port":57864},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.103.73.167','fd7a:115c:a1e0:9094:220b:d07c:2ada:afa8','ts-1-74-m8xzkz','ts-1-74-m8xzkz',2,'authkey','[]',2,'2024-09-27 14:26:25.298808764+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:23.257602115+00:00','2024-09-27 14:26:25.299937061+00:00',NULL);
INSERT INTO nodes VALUES(9,'mkey:d86a2d3bf33f28068f41bcf28eaef65874e75645b8a209b8e8ff75b982fd3030','nodekey:b791922bf53ca56cf20eddab18f70819dd974e88f81e0899468bbdb5ce57a947','discokey:3053d621f5f6a66bed296ca47950c73c6baeac05f363e6b93f4de436e5480912','["172.19.0.11:35503"]','{"IPNVersion":"1.56.1-tf1ea3161a","BackendLogID":"0dcd9913179fdd831ed881b2c4bbdbd34f8c35cdc291b770af1de2bd6f65406f","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.5","Desktop":false,"Hostname":"ts-1-56-d68ebk","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.21.5","Services":[{"Proto":"peerapi4","Port":60691},{"Proto":"peerapi6","Port":52294},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.56.1-tf1ea3161a","BackendLogID":"0dcd9913179fdd831ed881b2c4bbdbd34f8c35cdc291b770af1de2bd6f65406f","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.5","Desktop":false,"Hostname":"ts-1-56-d68ebk","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.21.5","Services":[{"Proto":"peerapi4","Port":60691},{"Proto":"peerapi6","Port":52294},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.66.151.35','fd7a:115c:a1e0:3bb0:cb5d:ce50:aff7:e909','ts-1-56-d68ebk','ts-1-56-d68ebk',2,'authkey','[]',2,'2024-09-27 14:26:25.295234746+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:23.259854709+00:00','2024-09-27 14:26:25.299175891+00:00',NULL);
INSERT INTO nodes VALUES(10,'mkey:7c5d3c34416dcba5331cb4e982f2a39628e0f20af864f2dc3d374c78c3127f3f','nodekey:f9ce61c929baab74b66c15d06e1ed029b4a810b208cbcf09fc833579ef4c2d1d','discokey:6cf5becf49993e8346022e336d009aed97fc336b06bf5233f41fdd958125552e','["172.19.0.10:49139"]','{"IPNVersion":"1.73.100-t7dcf65a10","BackendLogID":"c8babece2de39ecf1fb604a6308ed4682bc80d57a20469f2a0a963839a3cf89a","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.8","Desktop":false,"Package":"container","Hostname":"ts-unstable-rww2w3","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.0","Services":[{"Proto":"peerapi4","Port":34210},{"Proto":"peerapi6","Port":33839},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.73.100-t7dcf65a10","BackendLogID":"c8babece2de39ecf1fb604a6308ed4682bc80d57a20469f2a0a963839a3cf89a","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.8","Desktop":false,"Package":"container","Hostname":"ts-unstable-rww2w3","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.0","Services":[{"Proto":"peerapi4","Port":34210},{"Proto":"peerapi6","Port":33839},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.80.216.124','fd7a:115c:a1e0:862b:7842:203c:b321:bc21','ts-unstable-rww2w3','ts-unstable-rww2w3',2,'authkey','[]',2,'2024-09-27 14:26:25.306378593+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:23.264221272+00:00','2024-09-27 14:26:25.307441765+00:00',NULL);
INSERT INTO nodes VALUES(11,'mkey:011d835011ce062b6d4599e12db61b40a0232841733bc562924e81f8fa27e918','nodekey:b0102b4105fee529bf2b639cda917764435532499bbe1e5b196912ade3fad74e','discokey:28b9ca33497f8e61af9a650ab7043c1c889c3dda3fc5502e57b26aa34320f92f','["172.19.0.14:33800"]','{"IPNVersion":"1.72.1-tf4a95663c","BackendLogID":"073c48058a504ed882178e356d461aa1ea43d2f0b18eb791dc776aafecb2916e","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.8","Desktop":false,"Package":"container","Hostname":"ts-1-72-au8tie","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.22.5","Services":[{"Proto":"peerapi4","Port":38962},{"Proto":"peerapi6","Port":42239},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.72.1-tf4a95663c","BackendLogID":"073c48058a504ed882178e356d461aa1ea43d2f0b18eb791dc776aafecb2916e","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.8","Desktop":false,"Package":"container","Hostname":"ts-1-72-au8tie","Machine":"aarch64","GoArch":"arm64","GoVersion":"go1.22.5","Services":[{"Proto":"peerapi4","Port":38962},{"Proto":"peerapi6","Port":42239},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.88.147.164','fd7a:115c:a1e0:82b7:17b5:cc3d:7714:4a61','ts-1-72-au8tie','ts-1-72-au8tie',2,'authkey','[]',2,'2024-09-27 14:26:25.305073961+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:23.266659201+00:00','2024-09-27 14:26:25.305586505+00:00',NULL);
INSERT INTO nodes VALUES(12,'mkey:7c2bcc073197a9e56d0eb13f0328e75768223569c2f4468d83d9ae05bfa50c5d','nodekey:d51788b3908c85e1d80ccc7f91e12d482e5da7dfb30d2f65f7161592d67a7f2e','discokey:a332f1553d1ad958abbe91dc0e3fc661e8f78864839f4bc7f8c8b0f12ef4e450','["172.19.0.15:47328"]','{"IPNVersion":"1.73.0-dev20240911-t98f4dd985","BackendLogID":"51a7c7677a3758f7a6c77fa555ab4834a0f5e7482bb64ddcde02c73ec9c2a138","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.9","Desktop":false,"Hostname":"ts-head-ujp4xa","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.1","Services":[{"Proto":"peerapi4","Port":55532},{"Proto":"peerapi6","Port":55720},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','{"IPNVersion":"1.73.0-dev20240911-t98f4dd985","BackendLogID":"51a7c7677a3758f7a6c77fa555ab4834a0f5e7482bb64ddcde02c73ec9c2a138","OS":"linux","OSVersion":"6.8.0-36-generic","Container":true,"Distro":"alpine","DistroVersion":"3.18.9","Desktop":false,"Hostname":"ts-head-ujp4xa","Machine":"aarch64","GoArch":"arm64","GoArchVar":"v8.0","GoVersion":"go1.23.1","Services":[{"Proto":"peerapi4","Port":55532},{"Proto":"peerapi6","Port":55720},{"Proto":"peerapi-dns-proxy","Port":1}],"NetInfo":{"MappingVariesByDestIP":null,"HairPinning":null,"WorkingIPv6":false,"OSHasIPv6":true,"WorkingUDP":false,"WorkingICMPv4":false,"UPnP":false,"PMP":false,"PCP":false,"PreferredDERP":999,"FirewallMode":"ipt-default"},"Userspace":false,"UserspaceRouter":false,"AppConnector":false}','100.120.55.122','fd7a:115c:a1e0:b9b:d74c:e55a:c201:eb5','ts-head-ujp4xa','ts-head-ujp4xa',2,'authkey','[]',2,'2024-09-27 14:26:25.30691872+00:00','0001-01-01 00:00:00+00:00','2024-09-27 14:26:23.274483531+00:00','2024-09-27 14:26:25.30791685+00:00',NULL);
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
DELETE FROM sqlite_sequence;
INSERT INTO sqlite_sequence VALUES('nodes',12);
INSERT INTO sqlite_sequence VALUES('users',2);
INSERT INTO sqlite_sequence VALUES('pre_auth_keys',2);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,40 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
CREATE TABLE `users` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text,CONSTRAINT `uni_users_name` UNIQUE (`name`));
INSERT INTO users VALUES(1,'2024-09-27 14:12:26.861201+02:00','2024-09-27 14:12:26.861201+02:00',NULL,'kratest');
INSERT INTO users VALUES(2,'2024-09-27 14:12:33.550973+02:00','2024-09-27 14:12:33.550973+02:00',NULL,'testkra');
CREATE TABLE `pre_auth_keys` (`id` integer PRIMARY KEY AUTOINCREMENT,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'09b28f8c3351984874d46dace0a70177a8721933a950b663',1,0,0,0,'2024-09-27 12:12:38.242797+00:00','2024-09-27 13:12:38.241063+00:00');
INSERT INTO pre_auth_keys VALUES(2,'3112b953cb344191b2d5aec1b891250125bf7b437eac5d26',1,0,0,0,'2024-09-27 12:12:55.365396+00:00','2024-09-27 13:12:55.363595+00:00');
INSERT INTO pre_auth_keys VALUES(3,'7c23b9f215961e7609527aef78bf82fb19064b002d78c36f',1,0,0,0,'2024-09-27 12:13:32.99926+00:00','2024-09-27 13:13:32.997848+00:00');
INSERT INTO pre_auth_keys VALUES(4,'f2015583852b725220cc4b107fb288a4cf7ac259bd458a32',2,0,0,0,'2024-09-27 12:14:52.719795+00:00','2024-09-27 13:14:52.717783+00:00');
INSERT INTO pre_auth_keys VALUES(5,'b212b990165e897944dd3772786544402729fb349da50f57',2,0,0,0,'2024-09-27 12:15:06.869006+00:00','2024-09-27 13:15:06.86619+00:00');
CREATE TABLE `routes` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
CREATE TABLE `pre_auth_key_acl_tags` (`id` integer PRIMARY KEY AUTOINCREMENT,`pre_auth_key_id` integer,`tag` text,CONSTRAINT `fk_pre_auth_keys_acl_tags` FOREIGN KEY (`pre_auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_key_acl_tags VALUES(1,1,'tag:derp');
INSERT INTO pre_auth_key_acl_tags VALUES(2,2,'tag:derp');
INSERT INTO pre_auth_key_acl_tags VALUES(3,3,'tag:derp');
INSERT INTO pre_auth_key_acl_tags VALUES(4,3,'tag:merp');
INSERT INTO pre_auth_key_acl_tags VALUES(5,4,'tag:test');
INSERT INTO pre_auth_key_acl_tags VALUES(6,5,'tag:test');
INSERT INTO pre_auth_key_acl_tags VALUES(7,5,'tag:woop');
INSERT INTO pre_auth_key_acl_tags VALUES(8,5,'tag:dedu');
CREATE TABLE `api_keys` (`id` integer PRIMARY KEY AUTOINCREMENT,`prefix` text,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime);
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer PRIMARY KEY AUTOINCREMENT,`machine_key` text,`node_key` text,`disco_key` text,`endpoints` text,`host_info` text,`ipv4` text,`ipv6` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
DELETE FROM sqlite_sequence;
INSERT INTO sqlite_sequence VALUES('nodes',0);
INSERT INTO sqlite_sequence VALUES('users',2);
INSERT INTO sqlite_sequence VALUES('pre_auth_keys',5);
INSERT INTO sqlite_sequence VALUES('pre_auth_key_acl_tags',8);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,34 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
INSERT INTO api_keys VALUES(1,'hFKcRjLyfw',X'243261243130242e68554a6739332e6658333061326457723637464f2e6146424c74726e4542474c6c746437597a4253534d6f3677326d3944664d61','2023-04-09 22:34:28.624250346+00:00','2023-07-08 22:34:28.559681279+00:00',NULL);
INSERT INTO api_keys VALUES(2,'88Wbitubag',X'243261243130246f7932506d53375033334b733861376e7745434f3665674e776e517659374b5474326a30686958446c6c55696c3568513948307665','2024-07-28 21:59:38.786936789+00:00','2024-10-26 21:59:38.724189498+00:00',NULL);
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
INSERT INTO migrations VALUES('202501311657');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,`tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE SET NULL);
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`));
INSERT INTO nodes VALUES(1,'mkey:a0ab77456320823945ae0331823e3c0d516fae9585bd42698dfa1ac3d7679e63','nodekey:7c84167ab68f494942de14deb83587fd841843de2bac105b6c670048c160554f','discokey:53075b3c6cad3b62a2a29caea61beeb93f66b8c75cb89dac465236a5bbf57759','hostname_1','given_name1',1,'cli','["tag:sshclient","tag:ssh"]',0,'2025-02-05 16:46:13.960213431+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-03-30 23:18:17.612740902+00:00','2025-02-05 16:46:13.960284003+00:00',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(2,'mkey:f63dda7495db68077080364ba4109f48dee7a59310b9ed4968beb40d038eb622','nodekey:8186817337049e092e6ea02507091d8e9686924d46ad0e74a90370ec0113c440','discokey:28a2df7e73b8196c6859c94329443a28f9605b2b83541b685c1db666bd835775','hostname_2','given_name2',1,'cli','["tag:sshclient"]',0,'2024-07-30 17:37:24.266006395+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-03-30 23:20:01.05202704+00:00','2024-07-30 17:37:24.266082813+00:00',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(3,'mkey:0af53661fedf5143af3ea79e596928302e51c9fc9f0ea9ed1f2bb7d54778b80e','nodekey:8defd8272fd2851601158b2444fc8d1ab12b6187ec5db154b7a83bb75b2ce952','discokey:ba9d1ffac1997acbd8d281b8711699daa77ed91691772683ebbfdaafa2518a52','hostname_3','given_name3',1,'cli','["tag:ssh"]',0,'2025-02-05 16:48:00.460606473+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-03-30 23:36:04.930844845+00:00','2025-02-05 16:48:00.460679869+00:00',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:365e2055485de89e65e63c13e426b1ec5d5606327d63955b38be1d3f8cbbac6c','nodekey:996b9814e405f572fc0338f91b0c53f3a3a9a5b1ae0d2846d179195778d50909','discokey:ed72cb545b46b3e2ed0332f9cb4d7f4e774ea5834e2cbadc43c9bf7918ef2503','hostname_4','given_name4',1,'cli','["tag:ssh"]',0,'2025-02-05 16:48:00.460607206+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-03-31 15:51:56.149734121+00:00','2025-02-05 16:48:00.46092239+00:00',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(5,'mkey:1d04be488182a66cd7df4596ac59a40613eac6465a331af9ac6c91bb70754a25','nodekey:9b617f3e7941ac70b76f0e40c55543173e0432d4a9bb8bcb8b25d93b60a5da0e','discokey:15834557115cb889e8362e7f2cae1cfd7e78e754cb7310cff6b5c5b5d3027e35','hostname_5','given_name5',1,'cli','["tag:sshclient","tag:ssh"]',0,'2023-04-21 15:07:38.796218079+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-04-21 13:16:19.148836255+00:00','2024-04-17 15:39:21.339518261+00:00',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(6,'mkey:ed649503734e31eafad7f884ac8ee36ba0922c57cda8b6946cb439b1ed645676','nodekey:200484e66b43012eca81ec8850e4b5d1dd8fa538dfebdaac718f202cd2f1f955','discokey:600651ed2436ce5a49e71b3980f93070d888e6d65d608a64be29fdeed9f7bd6b','hostname_6','given_name6',1,'cli','["tag:ssh"]',0,'2023-07-09 16:56:18.876491583+00:00','0001-01-01 00:00:00+00:00','{}','[]','2023-05-07 10:30:54.520661376+00:00','2024-04-17 15:39:23.182648721+00:00',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-03-30 23:08:54.151102578+00:00','2023-03-30 23:08:54.151102578+00:00',NULL,'username_1','display_name_1','email_1@example.com',NULL,NULL,NULL);
DELETE FROM sqlite_sequence;
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,97 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,"user_id" integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'c0e73b52c1706fcceea368ae07c19c0e91fbe1f78eff2f7b',1,0,1,0,'2022-02-26 17:02:32.568878371+00:00','2022-02-26 18:11:15.388354971+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'ad293159f9506a02d6de4730e5a2ddb74f9fd4033919ecc5',1,0,1,1,'2022-02-26 17:08:07.828690446+00:00','2022-02-26 18:11:18.890985216+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(3,'66c7e0fbf74010ea2e153d35ffa0f3c48380ef38960d1fd1',1,0,0,1,'2022-02-26 17:11:54.149663776+00:00','2022-02-26 17:16:54.147175388+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(4,'cdbb69c88fabdc2609050c7f99e8ebdea6fcf81a50d802fc',1,0,0,1,'2022-02-26 17:15:34.160746962+00:00','2022-02-26 17:20:34.15935255+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(6,'0a99889a217a2f9cdd20082faadd5c90e72c83a47093a63a',1,0,0,1,'2022-03-04 07:27:17.535172209+00:00','2022-03-04 07:32:17.531871524+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(10,'6e88409e3883c1a47249e428030afd4a46bdaf3adb3b74c1',4,0,0,1,'2022-04-01 20:43:21.757703546+00:00','2022-04-01 20:48:21.756458144+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(13,'9d3c2bde9fcef181a3141dfe59d449bf03f6779dad3580e0',1,0,0,1,'2022-06-26 13:19:48.533865696+00:00','2022-06-26 13:24:48.532164552+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(16,'00b123d52ea8f58379b740fdc5c898b02330ab9b366cb1b4',1,0,0,1,'2023-02-12 06:21:30.15120385+00:00','2023-02-12 06:26:30.140082454+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(17,'c471ce93392c0d3040af0cf6166f4f578c3c66dd180b6e0b',1,0,0,1,'2023-02-12 06:26:55.829311638+00:00','2023-02-12 06:31:55.824701077+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(18,'fe0a438e67687540efcbbbc28c8e6c1b8ac1216f99de33d4',1,0,0,1,'2023-02-12 06:31:13.245185592+00:00','2023-02-12 06:36:13.241695106+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(19,'5a469043f1fa43ff11e54ea242dd882a81aea68f168b9a34',1,0,0,1,'2023-02-12 06:31:13.622545545+00:00','2023-02-12 06:36:13.560890824+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(20,'8b31d9a38282dfe07ffcebdfbd40db6b9e49997c93bed570',1,0,0,1,'2023-02-28 12:45:48.518939706+00:00','2023-02-28 12:50:48.445951259+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(21,'47a4216f2b4e5885d4e53a3de2ffe95521d8a708ca26d31e',1,0,0,1,'2023-02-28 12:45:48.53865321+00:00','2023-02-28 12:50:48.439132728+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(22,'1b7be83871f396e4544c8445acfc8d308dbfe29c7f0197f0',1,0,0,1,'2023-02-28 12:45:48.538806791+00:00','2023-02-28 12:50:48.445073692+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(23,'c9f364adba95c6c46c162eaa3786702805595841c0150927',1,0,0,1,'2023-05-05 08:08:16.73107293+00:00','2023-05-05 08:13:16.722921676+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(24,'a90c87e30fa22ffee39e5ce157dd22c909f2026295e3bce4',1,0,0,1,'2023-08-14 14:36:52.042138928+00:00','2023-08-14 14:41:52.038644473+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(25,'bb059cde5663619a8918bde19b9f8236085725554d9d78c2',1,0,0,1,'2023-08-14 16:15:33.722630834+00:00','2023-08-14 16:20:33.719604033+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(26,'0733b8fc67adc82644c87a95947b24c5d368c633cff92eb4',1,0,0,1,'2023-08-29 06:30:44.934900329+00:00','2023-08-29 06:35:44.931280114+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(27,'567f3a39066fd99c567d14bcc374b25cee0ad71af08b9054',1,0,0,1,'2023-11-03 17:53:45.857200883+00:00','2023-11-03 17:58:45.853742836+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(30,'8aa13c93cbef46d36c8159da51fb41a469ae04f932980890',1,0,0,1,'2024-07-29 12:24:27.140614087+00:00','2024-07-29 12:29:27.136525982+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(31,'9314b171abc433d73b8db297c1c5c65dae0be53d39a71520',1,0,0,1,'2024-08-07 18:35:12.375119763+00:00','2024-08-07 18:40:12.371590392+00:00',NULL);
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,"node_id" integer,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(7,'2023-01-15 14:41:49.445054371+01:00','2023-01-29 10:12:11.959527554+01:00',NULL,14,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(8,'2023-01-15 14:41:49.452617331+01:00','2023-01-29 10:12:13.154311101+01:00',NULL,14,'::/0',1,1,0);
INSERT INTO routes VALUES(9,'2024-05-05 07:16:02.944084847+02:00','2024-05-05 13:25:02.977065366+02:00',NULL,3,'10.138.98.32/27',1,1,1);
INSERT INTO routes VALUES(10,'2024-05-05 07:16:02.95709561+02:00','2024-05-05 13:25:04.513930181+02:00',NULL,3,'192.168.208.0/20',1,1,1);
INSERT INTO routes VALUES(11,'2024-05-05 12:46:08.770263657+02:00','2024-05-05 12:46:39.012076195+02:00',NULL,27,'172.19.128.0/20',1,1,1);
INSERT INTO routes VALUES(12,'2024-05-05 12:46:08.779527998+02:00','2024-05-05 12:46:39.843489833+02:00',NULL,27,'10.68.0.0/14',1,1,1);
INSERT INTO routes VALUES(13,'2024-05-05 12:46:08.787239639+02:00','2024-05-05 12:46:40.983839193+02:00',NULL,27,'10.243.219.68/31',1,1,1);
INSERT INTO routes VALUES(14,'2024-05-05 12:46:08.794135892+02:00','2024-08-18 08:45:35.831813635+02:00',NULL,27,'10.30.155.128/25',1,1,1);
INSERT INTO routes VALUES(15,'2024-05-05 12:46:08.799975671+02:00','2024-05-05 12:46:44.333956126+02:00',NULL,27,'10.64.0.0/13',1,1,1);
INSERT INTO routes VALUES(16,'2024-05-05 12:46:08.806879988+02:00','2024-05-05 12:46:45.422824419+02:00',NULL,27,'192.168.0.0/16',1,1,1);
INSERT INTO routes VALUES(17,'2024-08-08 20:44:22.76306591+02:00','2024-12-21 12:10:07.339044415+01:00',NULL,31,'172.27.33.0/24',1,1,1);
INSERT INTO routes VALUES(18,'2024-08-08 20:47:33.469970726+02:00','2024-12-21 12:10:07.442783446+01:00',NULL,31,'10.151.196.0/23',1,1,1);
INSERT INTO routes VALUES(21,'2024-08-08 20:54:05.146666051+02:00','2024-12-21 12:10:07.538738125+01:00',NULL,31,'192.168.33.128/26',1,1,1);
INSERT INTO routes VALUES(23,'2024-08-08 20:54:05.162212208+02:00','2024-12-21 12:10:07.644714175+01:00',NULL,31,'10.69.87.96/27',1,1,1);
INSERT INTO routes VALUES(25,'2024-08-08 20:54:05.179419681+02:00','2024-12-21 12:10:07.753927883+01:00',NULL,31,'192.168.240.184/30',1,1,1);
INSERT INTO routes VALUES(26,'2024-08-08 20:54:05.186132539+02:00','2024-12-21 12:10:07.871905187+01:00',NULL,31,'172.19.162.160/27',1,1,1);
INSERT INTO routes VALUES(28,'2024-08-08 20:54:05.202442818+02:00','2024-12-21 12:10:07.972132539+01:00',NULL,31,'172.30.190.136/30',1,1,1);
INSERT INTO routes VALUES(31,'2024-08-08 20:54:05.246698925+02:00','2024-12-21 12:10:08.150358433+01:00',NULL,31,'10.241.118.90/31',1,1,1);
INSERT INTO routes VALUES(32,'2024-08-08 20:54:05.256984635+02:00','2024-12-21 12:10:08.349521909+01:00',NULL,31,'192.168.0.0/17',1,1,1);
INSERT INTO routes VALUES(37,'2024-08-08 20:54:05.300971626+02:00','2024-12-21 12:10:08.553265285+01:00',NULL,31,'192.168.192.0/19',1,1,1);
INSERT INTO routes VALUES(43,'2024-08-08 20:54:05.383430747+02:00','2024-12-21 12:10:08.66112581+01:00',NULL,31,'172.29.254.8/29',1,1,1);
INSERT INTO routes VALUES(47,'2024-08-08 20:54:05.443181025+02:00','2024-12-21 12:10:08.826993878+01:00',NULL,31,'172.18.8.0/22',1,1,1);
INSERT INTO routes VALUES(48,'2024-08-08 20:54:05.449778605+02:00','2024-12-21 12:10:09.237117302+01:00',NULL,31,'10.169.34.250/31',1,1,1);
INSERT INTO routes VALUES(49,'2024-09-03 06:43:34.875117755+02:00','2024-12-21 12:10:09.342259317+01:00',NULL,31,'172.24.0.0/16',1,1,1);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
INSERT INTO api_keys VALUES(1,'S2nn85NliD',X'24326224313224437447593364536a63344d6548427a3266435a6d7a4f6f3972575178476b616e703962563435326157387753476364753947454b75','2022-12-25 21:35:28.644697962+01:00','2023-03-22 06:22:18.724817647+01:00',NULL);
INSERT INTO api_keys VALUES(2,'1KZkpEyiMH',X'24326224313224746474656e31394e30496e4f626952327a6f466f574f337749306d73684a453242455270723865557a483171747943436b4c333965','2023-03-22 06:22:18.339101298+01:00','2023-04-13 09:32:24.318715268+02:00',NULL);
INSERT INTO api_keys VALUES(3,'6yBMrqvEDX',X'2432622431322450757377786d6145352e503449364f4c36767069394f7a3948783837494879723050457752397a684b49594b56434d5250384c7a53','2023-04-13 09:32:23.864995051+02:00','2023-07-12 07:32:23.45+00:00',NULL);
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,"hostname" text,"user_id" integer,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`given_name` varchar(63),`forced_tags` text,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:6a9f06fccf0eff626075428e16c07c2e93464667a67c84dd0efadb1a74761d72','nodekey:d0d67c955181f1a9369a471496e1004678eebd93660394949848e61c7132ef9e','discokey:7667a90b1915f5cb3f725d159cd3f8bc3e46f6244df25f45d7fadc830a6d064e','web-05',1,'authKey',3,'2025-01-24 17:18:58.879117852+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["198.139.228.73:16016","[a5dd:542c:6998:997c:2d87:61b0:c760:ab6f]:56919","112.221.140.130:19743","[6520:763a:5fe2:8e88:5c8e:5b03:eeb1:5588]:20840","[7670:9084:a917:1173:70ce:2798:c805:66dc]:50297","[6f5b:219b:2f0b:cc08:a034:6936:d96b:11be]:28318","60.210.210.203:14631","66.181.120.138:15464"]','2022-02-26 18:11:55.92837512+01:00','2025-01-24 17:18:58.87921789+01:00',NULL,'node001',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(3,'mkey:ba9e14b963dd3a5953c9a32a58947ab98fa5ca44c492210b694a2a3fef2b06aa','nodekey:9d11ad4d2879c577b58cf0533f25b19eaa2d85f79f38becbc5a89c464df074af','discokey:6fce22b965a1d56764028a8e04abe388ea727db682c21c321e20f8900b0883ff','lt-38',7,'authKey',NULL,'2025-01-24 21:00:03.638659475+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["51.107.242.7:55191","[ce6f:3f5b:da2f:8382:f3a1:e2d4:1c47:fe5e]:25604"]','2022-03-01 19:26:46.242187887+01:00','2025-01-24 21:00:03.638914306+01:00',NULL,'node003',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:f67b11e9aff08b81a9d1e13ac991b7951575a60da19e32e89d0342f349aa6df5','nodekey:6fc38db24bf19fd60a01408ec2ad89add0a28013d1723540bd188e4c72cd006f','discokey:1f79ad4a4889d4333d6ac1c0c3879ffbe422d7d466e7532a17ab0974832f4f7e','laptop-41',1,'authKey',6,'2025-01-23 10:46:09.470903946+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c199:e8ca:c1bb:8364:dde8:bf3e:9467:c050]:61218","168.120.224.160:52272","184.61.212.248:29690","[32a5:51:afc3:d256:5b83:97cd:bb34:13c1]:63964"]','2022-03-04 08:27:19.383566031+01:00','2025-01-23 10:46:09.47099081+01:00',NULL,'node004',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(5,'mkey:a98f853b653cd80bb22b2610fa9fd575989eb00cf7d726e131f2f2b600752b20','nodekey:08816b57ddb7244a6893e67601caf0bbe341ab32e851d5e9272c265aff2dfa6d','discokey:fd250ccb73dab47b884d89d99263d1ee60f2901d9e9782357f5718a7b6b11b05','lt-42',8,'authKey',NULL,'2025-01-24 15:55:31.927025416+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[875:166d:8d6f:e053:bbe6:1c6d:843f:25b4]:11215","196.188.180.254:52309","180.187.196.169:52502"]','2022-03-05 13:54:23.660591381+01:00','2025-01-24 15:55:31.927258245+01:00',NULL,'node005',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(6,'mkey:5cb6e4bdb7176296568c0bc83af4b3731b3a59c18d985818e74c92bbbda4b1cd','nodekey:ccf1754b9a331d4f2dbb8dce7cab241a2613dff1ae489f468f4ba5f930c724fc','discokey:9a208d9bbd1b1fc35285a325e4b3c91a9151e812bdc8b49278a8d2271895b4ec','web-14',1,'authkey',NULL,'2025-01-22 13:52:30.302827092+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["166.111.217.41:13979","[cda1:789a:9f90:f1b0:df03:71a6:2bf8:b975]:20326","[ebe:748c:c594:2bd:9c6b:3518:a118:c54d]:30356"]','2022-03-21 15:52:20.739594362+01:00','2025-01-22 13:52:30.303085169+01:00',NULL,'node006',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(7,'mkey:bee1775fbab5753b808bfdd48d573fb328354515d0141ee3fcc18d49d13bc917','nodekey:6ad35a7f984fa1de838c163807b20ecc35cbbfe7ec2ec72880c5e50cad0a14a3','discokey:534f4aaa96a2f2f411d499c8d6867803c3462c25fdc5ca72b41c6634e84c1d8c','db-70',4,'authkey',10,'2025-01-24 23:11:36.767081207+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["3.26.132.25:924","[1293:e44:fa71:9ae2:ee7c:64ff:5bb2:705a]:8071","[2263:abdc:1461:efa1:8cca:7009:f84:3747]:3731","[ca4e:2134:74e7:8888:8b8:32ea:a7cd:e6fc]:53863","[f38c:fd3b:43da:7790:faf4:7da2:8df9:7bd1]:32916","147.168.107.56:35336"]','2022-04-01 22:43:27.318756043+02:00','2025-01-24 23:11:36.767680407+01:00',NULL,'node007',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(8,'mkey:e16c0484cd8458ffbd8ddf0ce4908e82ac5bd0ecf329cb1a5b618b89a4a72742','nodekey:5b9be700a2b1b5dca7c1b2953b8e06e0df8d6702f2aa0143ea9a674e0600e6c4','discokey:9eb34382a19dbf5e405bc3801acb7b1e0bc6f1b5c7c4632ea4c277b3241284eb','laptop-34',7,'authkey',NULL,'2025-01-24 10:53:08.967670007+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c901:4170:7a7:1a98:5474:f0a8:1722:830b]:48874","39.36.112.35:10587","68.226.133.92:29098","11.142.49.170:22792"]','2022-04-03 09:38:46.178224968+02:00','2025-01-24 10:53:08.967898387+01:00',NULL,'node008',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(9,'mkey:ab4157b902f026d4f8fd2180a463453049a7fab9488eff84c5e78cefaccb6e9b','nodekey:b848066a92746001cc9678f5b459f0849be0a00ac0126c95d4bb9ba25686f671','discokey:f52b49b12ffcd4ba40697f9f3367fc65db950348315d8da283a68181b2c0ab85','laptop-05',7,'cli',NULL,'2025-01-23 17:54:23.678930678+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["116.140.148.134:50513","[862d:91db:1faa:c25:4bb3:1882:ebe2:dc36]:34449","[d95c:d244:1457:ef8d:92a3:17f8:a38c:efed]:16770","215.159.49.214:32988","136.206.88.82:20612"]','2022-04-09 09:43:07.09027176+02:00','2025-01-23 17:54:23.679048069+01:00',NULL,'node009',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(10,'mkey:b6578985271145f84a1edd7bb3410551addc2b122cc3d3645916eecc612d287f','nodekey:5f327f104bc03d7a238a03a4f34b05c1c8a569215b25623f16a74c1afcbd49a6','discokey:df34ffd51349629e037e70c81280b8afc0dbeff254e8c0621033294998bee371','db-93',1,'authkey',NULL,'2025-01-18 10:08:12.942196784+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["215.10.187.249:19488","[bfe7:ebf6:e338:79a6:dba:4051:a7df:10]:31519"]','2022-06-26 13:57:07.40762063+02:00','2025-01-18 10:08:12.942403965+01:00',NULL,'node010',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(11,'mkey:1aee722e316e87b8ae056d72807d1ebb4338198e6ba62e36ec4e3b07873d218a','nodekey:99b698ecc210ced8962dd6862962c80c78301e5ecf598e011b1361c916db48f3','discokey:7f6ec7e95b93b35c02b66e1f28070998ddbf32d273252ef8500d7ab8c14a7d3f','email-44',1,'authkey',13,'2025-01-24 21:00:02.220787051+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["87.139.180.4:64685","[bae8:1f82:ff78:e8a8:235e:a50e:c131:2e8]:43129","[3486:5bc7:ada8:8da1:9df9:3cc6:d018:ee8b]:65112","43.182.159.11:27315"]','2022-06-26 15:19:50.566498735+02:00','2025-01-24 21:00:02.221354141+01:00',NULL,'node011',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(14,'mkey:4edbeff705459e7e5d0df80d42abce8d3db49137e013cbe38416aa2d0e77e4de','nodekey:149c771cccddad67f62a6cdf8ebc282692d3f8138e6749e3bcb8044209f30ea8','discokey:7773ea1a30faff0ef3d64186b00fc7f0d584c68eea4e3d75ad6dab5cfb54bee4','email-49',1,'authkey',NULL,'2025-01-23 06:42:37.593813869+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["61.59.238.85:46024","221.176.225.4:60304","[59f1:edd4:571:ac10:e700:fdbe:6084:e1eb]:43774","[88a8:d815:f927:150a:2c5b:9952:2587:818f]:33169"]','2022-09-26 16:07:54.206927686+02:00','2025-01-23 06:42:37.594039595+01:00',NULL,'node014',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(23,'mkey:ec475b374671562006704de6f1be902a3d75079e8c9a3b52e6c3d6dc37d3086a','nodekey:655232f4f4205ddc98661144bd7a05a975f44a3f01ed22e18927e6265329104a','discokey:b30f00fbda4b3a7ed66ff30ac8c41c0c1c04a775756543f27155e1b93f947eca','db-05',1,'authkey',23,'2025-01-21 14:51:26.001774373+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f2e:fd97:b513:b737:33f3:dd2b:df4:a90e]:41096","155.239.169.182:41163","[c908:b81c:b4c8:38d3:e311:b3f6:3067:227c]:11541","[f41f:b9e9:9205:210a:4ff9:ab34:57fd:3148]:21852"]','2023-05-05 10:08:17.301597525+02:00','2025-01-21 14:51:26.002382861+01:00',NULL,'node023','[]','100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(24,'mkey:cba1a93252cc66c9c35844b930b8177743e0ca3113b4a311c9ba3eecf98711d6','nodekey:7e3609ff22b18500773cdb42aa9a1c70de5a1b47f4fc5b85f8ec9620cc2d3a56','discokey:f3289ecda9660d9b664adef04a184e4c940003a0abf08c2a04bd46d87ab3c90c','db-91',1,'authkey',25,'2025-01-13 15:02:48.676721758+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e9c0:d5fd:b25c:8cc7:4c58:b666:3fc1:2814]:11543","30.125.129.134:36303","[213c:e72:d34:c59c:d4fa:8bb5:f6d3:d691]:24926","83.92.114.14:38013","223.127.253.143:5148","[e946:63ba:5369:b6db:2d37:8922:57e5:faa8]:51269","39.143.235.96:56031"]','2023-08-14 18:15:34.292188686+02:00','2025-01-13 15:02:48.67679754+01:00',NULL,'node024','[]','100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(25,'mkey:94e59581d400e61de9be0f51fd13a3610f6110f7c43f8b361c5b53e5b1821d6e','nodekey:d6203177612c4aff07781f0286b7122009b77d10bda31f18a01a3acdc73608da','discokey:8ed1202f1da5d66b2a9603359e9812f357a0f584636fa05b9a0a575e57e530cb','email-69',1,'authkey',26,'2025-01-21 07:41:05.58787908+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["110.245.60.227:50528","33.141.84.140:39332","141.199.13.112:28607","94.8.65.228:34575","58.211.127.215:33647"]','2023-08-29 08:30:45.518580154+02:00','2025-01-21 07:41:05.58844064+01:00',NULL,'node025','[]','100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(26,'mkey:04be3f20a566914418fa6e299f6b40484b6855fb2440cc997f2d457ef6a627a3','nodekey:257eb51ebf3703ce03c5ee07794cbbb6f94b24fd06ca914dc910e7741d55fea5','discokey:2ab4bdebe4ffe03d3a66246b6bb8a8289cb73c0f07aa4484d1ef3fdd6e17dd23','desktop-14',1,'authkey',27,'2025-01-24 23:00:24.184727782+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[3d31:7ec5:7635:7b6c:c7d0:cf70:bb45:6922]:16454","[80d6:f9fd:44f8:58b7:2049:70d4:721:139d]:31272","173.46.200.67:17932","62.215.78.119:52651"]','2023-11-03 18:53:48.108033118+01:00','2025-01-24 23:00:24.185295273+01:00',NULL,'node026','[]','100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(27,'mkey:b0c1eaf2df8d6cdc328d4cdde4ca8f8ee66fc736845c38b9fbb47df19e5137fe','nodekey:c20b516b77faec9611cb1644e7ac0578f7542751d78bcb9eefda307d610838d2','discokey:79580271b2031ba56f1616b7f8a491e7389cefb24e906d9bb99d3da5d045de9b','srv-56',7,'authkey',NULL,'2025-01-24 20:00:03.216855282+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["13.225.162.245:60672","[5101:751a:5e00:cf46:8b50:8ba9:3c8e:4c7c]:33862","[b9fe:3630:1807:826:a4a6:e5d2:532c:bdc8]:43617","[25b5:5b72:2ecc:193c:b61e:329:81c6:5af6]:39854","214.128.115.35:43726","[436d:61b:9834:b0e0:b2ed:b452:6330:34ee]:59171","[13a0:b8ff:bebb:d48:e16e:869d:b542:531b]:17201","44.157.88.255:43418"]','2023-12-29 19:18:10.814399482+01:00','2025-01-24 20:00:03.217108129+01:00',NULL,'node027','[]','100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(29,'mkey:6e0a32694e0a2bddbcc71d9489cbb76439f43ceffa40ab8bf070a695be120390','nodekey:0c36c35d4cba9e0b70a945ab88622097fa8659da6c7a20b0e4cbee1dea649075','discokey:ce88ad8d792775af9639e6295818cb416fb0ad24bfa6550f00722ee8095399c7','db-48',1,'authkey',NULL,'2025-01-24 20:00:05.821912941+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[60b9:155d:3b4a:1ade:51ce:e1f3:a6b8:8e5e]:42022","[ce74:4042:3405:dbfb:8e1b:2f01:5a55:6f49]:20536","[37ed:24ee:1ca9:2cdf:be79:d10a:1247:263c]:27485","199.22.246.223:36955"]','2024-06-02 09:46:39.307697473+02:00','2025-01-24 20:00:05.822130692+01:00',NULL,'node029','[]','100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(30,'mkey:93318ff3d9920d6be01eb5166a608fd76c094851aa925e55a2725c6dc99bbb3f','nodekey:cab6cdb81dff8d8a9eccb84d2ff9561bea8840a090f3ea1ae27e94b02ccd6744','discokey:4b472fdd9a6ab4f56f46139d55d525e17dfedd61aa11a0c62a02ebd80aef354e','email-50',1,'authkey',30,'2025-01-17 00:08:28.17211431+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2f41:257d:dc1b:c709:ea6c:1ad2:ba8e:af48]:60708","[c7df:a6c9:ae51:6570:f6b6:7d2c:1803:50f0]:6218","62.26.91.22:45257","37.207.25.123:5981"]','2024-07-29 14:24:27.684620193+02:00','2025-01-17 00:08:28.17277623+01:00',NULL,'node030','[]','100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(31,'mkey:ac01d01cd1e709938d07f3585184eef337024d32e80ceeddcb943ff8ca54cdd4','nodekey:d5906ed493f8df3fddb09fed829736f1274cb8120d6bcd33846a90460215a40d','discokey:0d4fc211bccbaa9f89e9ac73a33f4f682afe9d6ba7f722f5373cb1254787f2ef','srv-37',1,'authkey',31,'2025-01-24 17:05:22.207236228+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["49.111.96.135:35528","[abc1:b7cd:f18:6ed2:4b5a:9dce:3f08:8c17]:333","206.118.184.48:48132","7.64.160.114:11101"]','2024-08-07 20:35:12.944541318+02:00','2025-01-24 17:05:22.207871517+01:00',NULL,'node031','[]','100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(32,'mkey:8010732f3bbb0f58f3002b645258dbbc7d6c5cfebf8a485685a84da9b30dcf00','nodekey:d34dac3b348cd2d100ba36a85b42542cfe1dc74d51197caf50b138fea1401168','discokey:e28e9f435da77357942130f3923bb584773e6812d8d27fdc6dce20cc0cc0f752','lt-44',1,'cli',NULL,'2025-01-24 23:20:53.282115214+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["85.212.234.244:43593","161.5.250.27:14020","[cd55:bf01:5540:c30:3981:7f71:a471:4993]:25285","24.16.62.70:35569","213.115.82.246:7596","195.216.27.246:54466","[c47f:35c9:41fe:6f5:a40d:3e8b:6679:411e]:12963","19.205.218.60:63516","116.228.193.194:44296","[ee98:8de3:1f5b:731c:751b:ba46:a4a7:8760]:23245","[6eb3:8c34:e6c9:4c6a:25c9:89ca:c165:354e]:65112","[7003:63bb:6429:d463:96a6:990:2bdc:217d]:4300","[d820:584e:2b46:6915:6420:3056:f76:9e33]:48885"]','2024-10-26 07:18:04.947942936+02:00','2025-01-24 23:20:53.282346841+01:00',NULL,'node032',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2022-02-26 18:00:56.104436744+01:00','2024-09-14 08:51:13.31135114+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2022-04-01 22:30:02.657653341+02:00','2024-09-14 08:55:27.877614108+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2024-05-05 07:08:47.915309504+02:00','2024-09-14 08:55:02.778476991+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2024-09-14 08:57:26.215082073+02:00','2024-09-14 08:57:26.215082073+02:00',NULL,'user008','','',NULL,NULL,'');
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE UNIQUE INDEX idx_provider_identifier ON users (provider_identifier) WHERE provider_identifier IS NOT NULL;
CREATE UNIQUE INDEX idx_name_provider_identifier ON users (name,provider_identifier);
CREATE UNIQUE INDEX idx_name_no_provider_identifier ON users (name) WHERE provider_identifier IS NULL;
COMMIT;

View File

@@ -0,0 +1,95 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,"user_id" integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'c0e73b52c1706fcceea368ae07c19c0e91fbe1f78eff2f7b',1,0,1,0,'2022-02-26 17:02:32.568878371+00:00','2022-02-26 18:11:15.388354971+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'ad293159f9506a02d6de4730e5a2ddb74f9fd4033919ecc5',1,0,1,1,'2022-02-26 17:08:07.828690446+00:00','2022-02-26 18:11:18.890985216+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(3,'66c7e0fbf74010ea2e153d35ffa0f3c48380ef38960d1fd1',1,0,0,1,'2022-02-26 17:11:54.149663776+00:00','2022-02-26 17:16:54.147175388+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(4,'cdbb69c88fabdc2609050c7f99e8ebdea6fcf81a50d802fc',1,0,0,1,'2022-02-26 17:15:34.160746962+00:00','2022-02-26 17:20:34.15935255+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(6,'0a99889a217a2f9cdd20082faadd5c90e72c83a47093a63a',1,0,0,1,'2022-03-04 07:27:17.535172209+00:00','2022-03-04 07:32:17.531871524+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(10,'6e88409e3883c1a47249e428030afd4a46bdaf3adb3b74c1',4,0,0,1,'2022-04-01 20:43:21.757703546+00:00','2022-04-01 20:48:21.756458144+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(13,'9d3c2bde9fcef181a3141dfe59d449bf03f6779dad3580e0',1,0,0,1,'2022-06-26 13:19:48.533865696+00:00','2022-06-26 13:24:48.532164552+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(16,'00b123d52ea8f58379b740fdc5c898b02330ab9b366cb1b4',1,0,0,1,'2023-02-12 06:21:30.15120385+00:00','2023-02-12 06:26:30.140082454+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(17,'c471ce93392c0d3040af0cf6166f4f578c3c66dd180b6e0b',1,0,0,1,'2023-02-12 06:26:55.829311638+00:00','2023-02-12 06:31:55.824701077+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(18,'fe0a438e67687540efcbbbc28c8e6c1b8ac1216f99de33d4',1,0,0,1,'2023-02-12 06:31:13.245185592+00:00','2023-02-12 06:36:13.241695106+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(19,'5a469043f1fa43ff11e54ea242dd882a81aea68f168b9a34',1,0,0,1,'2023-02-12 06:31:13.622545545+00:00','2023-02-12 06:36:13.560890824+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(20,'8b31d9a38282dfe07ffcebdfbd40db6b9e49997c93bed570',1,0,0,1,'2023-02-28 12:45:48.518939706+00:00','2023-02-28 12:50:48.445951259+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(21,'47a4216f2b4e5885d4e53a3de2ffe95521d8a708ca26d31e',1,0,0,1,'2023-02-28 12:45:48.53865321+00:00','2023-02-28 12:50:48.439132728+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(22,'1b7be83871f396e4544c8445acfc8d308dbfe29c7f0197f0',1,0,0,1,'2023-02-28 12:45:48.538806791+00:00','2023-02-28 12:50:48.445073692+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(23,'c9f364adba95c6c46c162eaa3786702805595841c0150927',1,0,0,1,'2023-05-05 08:08:16.73107293+00:00','2023-05-05 08:13:16.722921676+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(24,'a90c87e30fa22ffee39e5ce157dd22c909f2026295e3bce4',1,0,0,1,'2023-08-14 14:36:52.042138928+00:00','2023-08-14 14:41:52.038644473+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(25,'bb059cde5663619a8918bde19b9f8236085725554d9d78c2',1,0,0,1,'2023-08-14 16:15:33.722630834+00:00','2023-08-14 16:20:33.719604033+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(26,'0733b8fc67adc82644c87a95947b24c5d368c633cff92eb4',1,0,0,1,'2023-08-29 06:30:44.934900329+00:00','2023-08-29 06:35:44.931280114+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(27,'567f3a39066fd99c567d14bcc374b25cee0ad71af08b9054',1,0,0,1,'2023-11-03 17:53:45.857200883+00:00','2023-11-03 17:58:45.853742836+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(30,'8aa13c93cbef46d36c8159da51fb41a469ae04f932980890',1,0,0,1,'2024-07-29 12:24:27.140614087+00:00','2024-07-29 12:29:27.136525982+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(31,'9314b171abc433d73b8db297c1c5c65dae0be53d39a71520',1,0,0,1,'2024-08-07 18:35:12.375119763+00:00','2024-08-07 18:40:12.371590392+00:00',NULL);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
INSERT INTO api_keys VALUES(1,'S2nn85NliD',X'24326224313224626f6979756458356735466b4e316d795a44596f622e744441784835724a39306538436c7a4f51384e374f3153466479454c706261','2022-12-25 21:35:28.644697962+01:00','2023-03-22 06:22:18.724817647+01:00',NULL);
INSERT INTO api_keys VALUES(2,'1KZkpEyiMH',X'243262243132247652305238364b30727533524b5735777658706f5275684d37727173306549352f585772656a32394e4472594a7339556f55493843','2023-03-22 06:22:18.339101298+01:00','2023-04-13 09:32:24.318715268+02:00',NULL);
INSERT INTO api_keys VALUES(3,'6yBMrqvEDX',X'24326224313224676f6d4556557a2e45695a7354775663414c714252656f4e3572714d364643322f2f7466794652344d7a6c344f504953656845504b','2023-04-13 09:32:23.864995051+02:00','2023-07-12 07:32:23.45+00:00',NULL);
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,"hostname" text,"user_id" integer,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`given_name` varchar(63),`forced_tags` text,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:6a9f06fccf0eff626075428e16c07c2e93464667a67c84dd0efadb1a74761d72','nodekey:d0d67c955181f1a9369a471496e1004678eebd93660394949848e61c7132ef9e','discokey:7667a90b1915f5cb3f725d159cd3f8bc3e46f6244df25f45d7fadc830a6d064e','web-05',1,'authKey',3,'2025-01-30 19:38:27.812993984+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["198.139.228.73:16016","[a5dd:542c:6998:997c:2d87:61b0:c760:ab6f]:56919","112.221.140.130:19743","[6520:763a:5fe2:8e88:5c8e:5b03:eeb1:5588]:20840","[7670:9084:a917:1173:70ce:2798:c805:66dc]:50297"]','2022-02-26 18:11:55.92837512+01:00','2025-01-30 19:38:27.813720595+01:00',NULL,'node001',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(3,'mkey:67287ef80f62664d68f3050e68ced4e8f78e173151801529551d42fd8e951b40','nodekey:6afc027970c1ddf9b3544b8c49223dcafe436a51384f80bb341a8f8322bef6d8','discokey:86693fc9f959f11015f3ff457b8d62381a6542e2eef097e2b6bdd679175c975b','srv-24',7,'authKey',NULL,'2025-01-29 12:28:39.61495602+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2cbd:607c:5e91:ea51:38ed:557:fd0:3405]:48307","[790b:6b18:8ac1:afa8:c2d3:f6b:37f6:623f]:41499"]','2022-03-01 19:26:46.242187887+01:00','2025-01-29 12:28:39.615036412+01:00',NULL,'node003',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:e0630dc6f407e6064c010dbef10b982c6e9d731706cc13b10993b542e81edf47','nodekey:44f96cda7202665271958eac8a3cfb120ea72209ee88d93fac3c23aeafa3a993','discokey:48b58784e2acdad30028ceed18bc9e7bd5fae3605dbef1a40f3f38a705adef9d','desktop-44',1,'authKey',6,'2025-01-30 17:44:08.255021526+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b53b:c286:a007:e851:dc6e:8152:82a5:22ca]:25604","[ff9b:6bbd:77bc:323d:12e4:22ba:b712:80c]:37729","[1e76:19af:e817:9a33:4f83:366e:b686:6362]:39521","57.71.157.166:9055","[c199:e8ca:c1bb:8364:dde8:bf3e:9467:c050]:61218"]','2022-03-04 08:27:19.383566031+01:00','2025-01-30 17:44:08.255111155+01:00',NULL,'node004',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(5,'mkey:4f7673e616b40b313ef69fd390e9c4bdb4c80f66840defb02c37d6f2fa152c5c','nodekey:91ee8b593bb0599e9583a692dabef9528423878f737f7bfdf339fc02bbe8ab47','discokey:fb3b2c151a0d277e77837dc2a5e96fe8f05bbefa770a84822689ec2c63dfe358','email-24',8,'authKey',NULL,'2025-01-30 07:11:28.440822489+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6add:4288:4372:c9ce:7cee:4852:e6d0:9d56]:44968","[884b:b2cc:e2f3:ab06:131b:e30c:69a2:363]:32943","49.81.27.127:23839"]','2022-03-05 13:54:23.660591381+01:00','2025-01-30 07:11:28.441136461+01:00',NULL,'node005',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(6,'mkey:e8a549e38c8301af3c044ff9ca1df86c814bc9c9a62bddd28ff47ebd9b113d07','nodekey:f0188064db0f31b49e1048044186d20700406a7a7b71b054507c90d5a79e7de4','discokey:30687e0c15fc480ef15f9d91011c9fa458c18370db11cdc8b72f36e814e9ece2','lt-01',1,'authkey',NULL,'2025-01-30 18:10:50.161868774+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[be53:e324:1587:4d86:d24c:8662:cd5c:a4c8]:58105","59.239.218.25:49807","[cfa4:ad2e:1410:3b78:ce03:b437:6749:ff3a]:39835"]','2022-03-21 15:52:20.739594362+01:00','2025-01-30 18:10:50.16216299+01:00',NULL,'node006',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(7,'mkey:45c951d703f782a16a6db8b4dc872952308f86883499d0613f03318d18f3e7fe','nodekey:70837c16d309644e71e6b251bdb66c4e6a5c9b9f6e23a3b803142b8f00d1017a','discokey:ebe6dd61b6b2bafccce9d01ba0d58ea2ee93a90ae6cafb4383453fb4a17441b4','desktop-61',4,'authkey',10,'2025-01-30 15:57:13.811124896+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e5e8:7d01:63fc:4220:3b4a:df5:ebe:748c]:47047","[7513:6321:b35:b633:b39e:41ed:10a1:3fdd]:462","[8dc0:10e:95b6:9954:2614:8dcc:6564:e167]:58499","[8e6d:95be:19a9:316a:d37e:bcb6:5e05:d7f0]:36162","[5bb2:705a:7f5c:3c9:db83:956a:1ce:5291]:9510"]','2022-04-01 22:43:27.318756043+02:00','2025-01-30 15:57:13.811810941+01:00',NULL,'node007',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(8,'mkey:3dff46782f13efbfe7b1a9d5d3275f48954a1abe29111b484fdb3c6edfb795bd','nodekey:080424852e9cbe3c2eaac52c1890cf485bbc2604615ec3c293b80322f17dbe63','discokey:2f6a05491ef99cafaf968c0c62b5c9d19083ef070991ee677d14b0ac9ce08377','db-70',7,'authkey',NULL,'2025-01-30 18:49:07.297878703+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["166.240.74.240:40259","[7311:ce3c:e8cf:c591:533:7132:4504:52ca]:48923","[4912:5cdb:3ed8:7c52:6b8b:2d37:59bf:cf98]:20693","[bad1:e653:831e:aa61:61e4:f824:996a:aac9]:11845","87.221.84.2:11620","71.36.112.35:10587"]','2022-04-03 09:38:46.178224968+02:00','2025-01-30 18:49:07.298161737+01:00',NULL,'node008',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(9,'mkey:90c42ae0cf8652f585ac27eb51f0890b9a101b20a834eefed6ea4bd503313550','nodekey:099ecaa8aae2e406befa1c6343b85d8e14ab4f3171835637762069ccda6065d5','discokey:de9ca6bbc281fca8ccffe16d3576385a1864854a0054e74c755c73c9e66d7610','lt-30',7,'cli',NULL,'2025-01-30 17:13:53.726978413+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["32.34.123.165:35870","[1daf:274c:55b2:7413:3c1:bd3d:acc5:4eb1]:33732","182.237.82.235:32290","6.93.152.196:16212","[a38c:efed:7c57:2d0f:4348:fbba:e351:9d7]:10415"]','2022-04-09 09:43:07.09027176+02:00','2025-01-30 17:13:53.72707237+01:00',NULL,'node009',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(10,'mkey:6df036352af9c6f03145a8a580466877042296ec2ce47f9cbb8d079baba8925e','nodekey:32934a036fc17e051dd08ca451cae3929e3636eb834771c350d2bffdda7e721c','discokey:0478a62f4092127fd4ca7f4fc35dcf40219bccc9ebf3a35ab77e3dc61269a55c','email-93',1,'authkey',NULL,'2025-01-26 10:25:51.849469454+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["70.180.67.60:48287","141.100.183.252:19523"]','2022-06-26 13:57:07.40762063+02:00','2025-01-26 10:25:51.849815197+01:00',NULL,'node010',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(11,'mkey:9d0a61f24aedbb4580224879acfb30b61cf10b3b293667ee110b1319ae4703ef','nodekey:d3b8ad82d1b771993c45ac10037fea8926693262b4f754b845545f3b9e6760d3','discokey:b5f97e790d1452ad4f7e27bcca9611e7d8bb080c4b2860e57c46a784b038f09f','web-33',1,'authkey',13,'2025-01-30 07:37:07.518404681+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["128.57.253.0:39500","25.178.136.37:18298","86.9.216.195:48221","[c131:2e8:80a6:4825:7e56:cc6f:9dcc:37d5]:18109"]','2022-06-26 15:19:50.566498735+02:00','2025-01-30 07:37:07.519108399+01:00',NULL,'node011',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(14,'mkey:a177d1fd989be953fd86bb5dc04c13feb917b019d5e0bfeda2715ea88abf7ff6','nodekey:8f6020fe3f16fb9da556b43079fb6885f53a8733318599b3b25706f6c7d99d9d','discokey:f2276c628270c0eaee429a55185611ebcb961bf07b02de854a0bc4382564eae4','email-37',1,'authkey',NULL,'2025-01-30 06:18:09.988928832+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ff2e:b9f0:9890:1aab:42e5:c2ac:a177:66d5]:11839","223.36.72.39:33254","[ec6b:fbd2:bbc3:162b:74ef:b955:514:2656]:46024","221.176.225.4:60304"]','2022-09-26 16:07:54.206927686+02:00','2025-01-30 06:18:09.989199262+01:00',NULL,'node014',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(23,'mkey:0bd4a2eac9b6f9b77ab9ee9ea42b36b74d73e0544a2c482526b2385e8bcb0c34','nodekey:1a5c66957c54314f72ea26fed12e48b9c4149c1f640300e39d6190226bc1aaf8','discokey:9f151fb1569ef5341c8f54eec62b82cb7e5f21540ebe9271ae6449a31250123a','laptop-22',1,'authkey',23,'2025-01-30 07:37:08.458181354+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["55.247.173.145:28477","197.123.99.18:53038","102.60.187.246:41096","155.239.169.182:41163"]','2023-05-05 10:08:17.301597525+02:00','2025-01-30 07:37:08.526403731+01:00',NULL,'node023','[]','100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(24,'mkey:972ef94d28e97680b5bb3ec45a8f7afff8d6988dc9685466fbba21ad96dd0d76','nodekey:a27328ce98ebfb68b59db23adcbd8f402f0ca88c656f8d8a37aafdd5226dd84a','discokey:2cec5f97c2c29ca3bafadbddddebdec872360cf725298c62bb824a6093c838df','db-54',1,'authkey',25,'2025-01-13 15:02:48.676721758+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["172.58.255.148:13691","31.145.94.155:5734","[e9c0:d5fd:b25c:8cc7:4c58:b666:3fc1:2814]:11543","30.125.129.134:36303","[213c:e72:d34:c59c:d4fa:8bb5:f6d3:d691]:24926","83.92.114.14:38013","223.127.253.143:5148"]','2023-08-14 18:15:34.292188686+02:00','2025-01-13 15:02:48.67679754+01:00',NULL,'node024','[]','100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(25,'mkey:7c84b8eea26e6d6a14e08ee933806ca4fb854bd0a168ee576efc58a69523ea0f','nodekey:00cb375ac5580c5718d7879942eba4378d73bf4026ae583a72c6d72f9a2f5958','discokey:69afa6724b1c46f7947a232489f51bd458db562c1144d41ba1b6075395e62529','db-61',1,'authkey',26,'2025-01-30 07:37:08.558409068+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9599:6347:eeed:7573:eb34:676:69d5:954]:17338","87.151.18.221:6598","110.245.60.227:50528","33.141.84.140:39332"]','2023-08-29 08:30:45.518580154+02:00','2025-01-30 07:37:08.559668856+01:00',NULL,'node025','[]','100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(26,'mkey:5a1b0920cafe0a8b54af7194baceac2029c4b12afc0e542423637f47cc4e53e7','nodekey:927c5ab7c0b8288ca36897c5f371487e9dc2200f28507029e1864086d95b5b1e','discokey:260c9a090d46eef056c0d411d4097b41aa0e9902f15cfa59906ee85f526f52b6','srv-51',1,'authkey',27,'2025-01-30 19:34:43.188756627+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6676:38fc:5af9:3b60:41b7:e46e:bbe1:c8bf]:30898","[4aba:d70:c25d:5d4d:1bc0:d119:4749:9efc]:37269","[9320:382a:5779:2fa7:b46f:c4d5:f889:3155]:46058","[3d31:7ec5:7635:7b6c:c7d0:cf70:bb45:6922]:16454","[80d6:f9fd:44f8:58b7:2049:70d4:721:139d]:31272"]','2023-11-03 18:53:48.108033118+01:00','2025-01-30 19:34:43.189464994+01:00',NULL,'node026','[]','100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(27,'mkey:9776d9e03b05d823cd49eae6194bd35af003ab124abcb8665e51befcbb97f7dd','nodekey:66e111175598e5b35832a9cd18ffdf2661caad4eb206a432cbb7a2916e64a3d9','discokey:0abf0367186a9e7b1fba741a8f4020db8e21fe9091aa0726ad5ebf7cb8e5634f','email-21',7,'authkey',NULL,'2025-01-30 00:13:32.682147532+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[60da:30ec:55bd:5ab3:3fe7:5492:1fc8:92f3]:36566","105.238.97.70:40193","[8c84:2d7e:5e1a:2f51:8754:aa54:b421:a19f]:60672","[5101:751a:5e00:cf46:8b50:8ba9:3c8e:4c7c]:33862","[b9fe:3630:1807:826:a4a6:e5d2:532c:bdc8]:43617","[25b5:5b72:2ecc:193c:b61e:329:81c6:5af6]:39854","214.128.115.35:43726","[436d:61b:9834:b0e0:b2ed:b452:6330:34ee]:59171","[13a0:b8ff:bebb:d48:e16e:869d:b542:531b]:17201","44.157.88.255:43418"]','2023-12-29 19:18:10.814399482+01:00','2025-01-30 00:13:32.682255545+01:00',NULL,'node027','[]','100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(29,'mkey:6e0a32694e0a2bddbcc71d9489cbb76439f43ceffa40ab8bf070a695be120390','nodekey:0c36c35d4cba9e0b70a945ab88622097fa8659da6c7a20b0e4cbee1dea649075','discokey:ce88ad8d792775af9639e6295818cb416fb0ad24bfa6550f00722ee8095399c7','db-48',1,'authkey',NULL,'2025-01-30 11:50:53.588423938+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[60b9:155d:3b4a:1ade:51ce:e1f3:a6b8:8e5e]:42022","[ce74:4042:3405:dbfb:8e1b:2f01:5a55:6f49]:20536","[37ed:24ee:1ca9:2cdf:be79:d10a:1247:263c]:27485","199.22.246.223:36955"]','2024-06-02 09:46:39.307697473+02:00','2025-01-30 11:50:53.588974887+01:00',NULL,'node029','[]','100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(30,'mkey:93318ff3d9920d6be01eb5166a608fd76c094851aa925e55a2725c6dc99bbb3f','nodekey:cab6cdb81dff8d8a9eccb84d2ff9561bea8840a090f3ea1ae27e94b02ccd6744','discokey:4b472fdd9a6ab4f56f46139d55d525e17dfedd61aa11a0c62a02ebd80aef354e','email-50',1,'authkey',30,'2025-01-30 07:37:11.127249774+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2f41:257d:dc1b:c709:ea6c:1ad2:ba8e:af48]:60708","[c7df:a6c9:ae51:6570:f6b6:7d2c:1803:50f0]:6218","62.26.91.22:45257","37.207.25.123:5981"]','2024-07-29 14:24:27.684620193+02:00','2025-01-30 07:37:11.129269195+01:00',NULL,'node030','[]','100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(31,'mkey:ac01d01cd1e709938d07f3585184eef337024d32e80ceeddcb943ff8ca54cdd4','nodekey:d5906ed493f8df3fddb09fed829736f1274cb8120d6bcd33846a90460215a40d','discokey:0d4fc211bccbaa9f89e9ac73a33f4f682afe9d6ba7f722f5373cb1254787f2ef','srv-37',1,'authkey',31,'2025-01-30 19:36:44.453423774+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["49.111.96.135:35528","[abc1:b7cd:f18:6ed2:4b5a:9dce:3f08:8c17]:333","206.118.184.48:48132","7.64.160.114:11101","44.192.177.204:34267","192.170.230.144:10199"]','2024-08-07 20:35:12.944541318+02:00','2025-01-30 19:36:44.454213203+01:00',NULL,'node031','[]','100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(32,'mkey:f4cccb12f91a1b6c5a6dc5af6d307a821f701d5de57a17bc08f5599be53adf5f','nodekey:ed136fe41759c3e7be39bf15fdd6754769ce4cbb675540ece6fbf4a87b4ecfaf','discokey:f5c1095eb1350ff6a44d708bfe56d311f444d0f8e634b123230e6ce3ba854477','desktop-95',1,'cli',NULL,'2025-01-30 18:56:16.654079824+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["183.48.47.238:43648","200.130.212.85:63469","216.16.62.70:35569","213.115.82.246:7596","195.216.27.246:54466","[c47f:35c9:41fe:6f5:a40d:3e8b:6679:411e]:12963","19.205.218.60:63516","116.228.193.194:44296","[ee98:8de3:1f5b:731c:751b:ba46:a4a7:8760]:23245","[6eb3:8c34:e6c9:4c6a:25c9:89ca:c165:354e]:65112","[7003:63bb:6429:d463:96a6:990:2bdc:217d]:4300","[d820:584e:2b46:6915:6420:3056:f76:9e33]:48885","25.167.184.15:1967","82.253.97.208:8684","[3a58:c14f:7b83:917b:d62:dbb9:7a9a:1e81]:49391","[b4c2:50f5:986b:a9e7:bc25:1cb2:ef17:3144]:38454","198.9.176.244:6032"]','2024-10-26 07:18:04.947942936+02:00','2025-01-30 18:56:16.654364791+01:00',NULL,'node032',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2022-02-26 18:00:56.104436744+01:00','2024-09-14 08:51:13.31135114+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2022-04-01 22:30:02.657653341+02:00','2024-09-14 08:55:27.877614108+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2024-05-05 07:08:47.915309504+02:00','2024-09-14 08:55:02.778476991+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2024-09-14 08:57:26.215082073+02:00','2024-09-14 08:57:26.215082073+02:00',NULL,'user008','','',NULL,NULL,'');
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(7,'2023-01-15 14:41:49.445054371+01:00','2023-01-29 10:12:11.959527554+01:00',NULL,14,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(8,'2023-01-15 14:41:49.452617331+01:00','2023-01-29 10:12:13.154311101+01:00',NULL,14,'::/0',1,1,0);
INSERT INTO routes VALUES(9,'2024-05-05 07:16:02.944084847+02:00','2024-05-05 13:25:02.977065366+02:00',NULL,3,'10.138.98.32/27',1,1,1);
INSERT INTO routes VALUES(10,'2024-05-05 07:16:02.95709561+02:00','2024-05-05 13:25:04.513930181+02:00',NULL,3,'192.168.208.0/20',1,1,1);
INSERT INTO routes VALUES(11,'2024-05-05 12:46:08.770263657+02:00','2024-05-05 12:46:39.012076195+02:00',NULL,27,'172.19.128.0/20',1,1,1);
INSERT INTO routes VALUES(12,'2024-05-05 12:46:08.779527998+02:00','2024-05-05 12:46:39.843489833+02:00',NULL,27,'10.68.0.0/14',1,1,1);
INSERT INTO routes VALUES(13,'2024-05-05 12:46:08.787239639+02:00','2024-05-05 12:46:40.983839193+02:00',NULL,27,'10.243.219.68/31',1,1,1);
INSERT INTO routes VALUES(14,'2024-05-05 12:46:08.794135892+02:00','2024-08-18 08:45:35.831813635+02:00',NULL,27,'10.30.155.128/25',1,1,1);
INSERT INTO routes VALUES(15,'2024-05-05 12:46:08.799975671+02:00','2024-05-05 12:46:44.333956126+02:00',NULL,27,'10.64.0.0/13',1,1,1);
INSERT INTO routes VALUES(16,'2024-05-05 12:46:08.806879988+02:00','2024-05-05 12:46:45.422824419+02:00',NULL,27,'192.168.0.0/16',1,1,1);
INSERT INTO routes VALUES(17,'2024-08-08 20:44:22.76306591+02:00','2024-12-21 12:10:07.339044415+01:00',NULL,31,'172.27.33.0/24',1,1,1);
INSERT INTO routes VALUES(18,'2024-08-08 20:47:33.469970726+02:00','2024-12-21 12:10:07.442783446+01:00',NULL,31,'10.151.196.0/23',1,1,1);
INSERT INTO routes VALUES(21,'2024-08-08 20:54:05.146666051+02:00','2024-12-21 12:10:07.538738125+01:00',NULL,31,'192.168.33.128/26',1,1,1);
INSERT INTO routes VALUES(23,'2024-08-08 20:54:05.162212208+02:00','2024-12-21 12:10:07.644714175+01:00',NULL,31,'10.69.87.96/27',1,1,1);
INSERT INTO routes VALUES(25,'2024-08-08 20:54:05.179419681+02:00','2024-12-21 12:10:07.753927883+01:00',NULL,31,'192.168.240.184/30',1,1,1);
INSERT INTO routes VALUES(26,'2024-08-08 20:54:05.186132539+02:00','2024-12-21 12:10:07.871905187+01:00',NULL,31,'172.19.162.160/27',1,1,1);
INSERT INTO routes VALUES(28,'2024-08-08 20:54:05.202442818+02:00','2024-12-21 12:10:07.972132539+01:00',NULL,31,'172.30.190.136/30',1,1,1);
INSERT INTO routes VALUES(31,'2024-08-08 20:54:05.246698925+02:00','2024-12-21 12:10:08.150358433+01:00',NULL,31,'10.241.118.90/31',1,1,1);
INSERT INTO routes VALUES(32,'2024-08-08 20:54:05.256984635+02:00','2024-12-21 12:10:08.349521909+01:00',NULL,31,'192.168.0.0/17',1,1,1);
INSERT INTO routes VALUES(37,'2024-08-08 20:54:05.300971626+02:00','2024-12-21 12:10:08.553265285+01:00',NULL,31,'192.168.192.0/19',1,1,1);
INSERT INTO routes VALUES(43,'2024-08-08 20:54:05.383430747+02:00','2024-12-21 12:10:08.66112581+01:00',NULL,31,'172.29.254.8/29',1,1,1);
INSERT INTO routes VALUES(47,'2024-08-08 20:54:05.443181025+02:00','2024-12-21 12:10:08.826993878+01:00',NULL,31,'172.18.8.0/22',1,1,1);
INSERT INTO routes VALUES(48,'2024-08-08 20:54:05.449778605+02:00','2024-12-21 12:10:09.237117302+01:00',NULL,31,'10.169.34.250/31',1,1,1);
INSERT INTO routes VALUES(49,'2024-09-03 06:43:34.875117755+02:00','2024-12-21 12:10:09.342259317+01:00',NULL,31,'172.24.0.0/16',1,1,1);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,95 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,"user_id" integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'c0e73b52c1706fcceea368ae07c19c0e91fbe1f78eff2f7b',1,0,1,0,'2022-02-26 17:02:32.568878371+00:00','2022-02-26 18:11:15.388354971+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'ad293159f9506a02d6de4730e5a2ddb74f9fd4033919ecc5',1,0,1,1,'2022-02-26 17:08:07.828690446+00:00','2022-02-26 18:11:18.890985216+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(3,'66c7e0fbf74010ea2e153d35ffa0f3c48380ef38960d1fd1',1,0,0,1,'2022-02-26 17:11:54.149663776+00:00','2022-02-26 17:16:54.147175388+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(4,'cdbb69c88fabdc2609050c7f99e8ebdea6fcf81a50d802fc',1,0,0,1,'2022-02-26 17:15:34.160746962+00:00','2022-02-26 17:20:34.15935255+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(6,'0a99889a217a2f9cdd20082faadd5c90e72c83a47093a63a',1,0,0,1,'2022-03-04 07:27:17.535172209+00:00','2022-03-04 07:32:17.531871524+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(10,'6e88409e3883c1a47249e428030afd4a46bdaf3adb3b74c1',4,0,0,1,'2022-04-01 20:43:21.757703546+00:00','2022-04-01 20:48:21.756458144+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(13,'9d3c2bde9fcef181a3141dfe59d449bf03f6779dad3580e0',1,0,0,1,'2022-06-26 13:19:48.533865696+00:00','2022-06-26 13:24:48.532164552+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(16,'00b123d52ea8f58379b740fdc5c898b02330ab9b366cb1b4',1,0,0,1,'2023-02-12 06:21:30.15120385+00:00','2023-02-12 06:26:30.140082454+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(17,'c471ce93392c0d3040af0cf6166f4f578c3c66dd180b6e0b',1,0,0,1,'2023-02-12 06:26:55.829311638+00:00','2023-02-12 06:31:55.824701077+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(18,'fe0a438e67687540efcbbbc28c8e6c1b8ac1216f99de33d4',1,0,0,1,'2023-02-12 06:31:13.245185592+00:00','2023-02-12 06:36:13.241695106+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(19,'5a469043f1fa43ff11e54ea242dd882a81aea68f168b9a34',1,0,0,1,'2023-02-12 06:31:13.622545545+00:00','2023-02-12 06:36:13.560890824+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(20,'8b31d9a38282dfe07ffcebdfbd40db6b9e49997c93bed570',1,0,0,1,'2023-02-28 12:45:48.518939706+00:00','2023-02-28 12:50:48.445951259+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(21,'47a4216f2b4e5885d4e53a3de2ffe95521d8a708ca26d31e',1,0,0,1,'2023-02-28 12:45:48.53865321+00:00','2023-02-28 12:50:48.439132728+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(22,'1b7be83871f396e4544c8445acfc8d308dbfe29c7f0197f0',1,0,0,1,'2023-02-28 12:45:48.538806791+00:00','2023-02-28 12:50:48.445073692+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(23,'c9f364adba95c6c46c162eaa3786702805595841c0150927',1,0,0,1,'2023-05-05 08:08:16.73107293+00:00','2023-05-05 08:13:16.722921676+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(24,'a90c87e30fa22ffee39e5ce157dd22c909f2026295e3bce4',1,0,0,1,'2023-08-14 14:36:52.042138928+00:00','2023-08-14 14:41:52.038644473+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(25,'bb059cde5663619a8918bde19b9f8236085725554d9d78c2',1,0,0,1,'2023-08-14 16:15:33.722630834+00:00','2023-08-14 16:20:33.719604033+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(26,'0733b8fc67adc82644c87a95947b24c5d368c633cff92eb4',1,0,0,1,'2023-08-29 06:30:44.934900329+00:00','2023-08-29 06:35:44.931280114+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(27,'567f3a39066fd99c567d14bcc374b25cee0ad71af08b9054',1,0,0,1,'2023-11-03 17:53:45.857200883+00:00','2023-11-03 17:58:45.853742836+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(30,'8aa13c93cbef46d36c8159da51fb41a469ae04f932980890',1,0,0,1,'2024-07-29 12:24:27.140614087+00:00','2024-07-29 12:29:27.136525982+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(31,'9314b171abc433d73b8db297c1c5c65dae0be53d39a71520',1,0,0,1,'2024-08-07 18:35:12.375119763+00:00','2024-08-07 18:40:12.371590392+00:00',NULL);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
INSERT INTO api_keys VALUES(1,'S2nn85NliD',X'243262243132247a447a433335436450323462305a332e77487845574f4837583374565134787030332f7046786e33726e69795a5336666762613569','2022-12-25 21:35:28.644697962+01:00','2023-03-22 06:22:18.724817647+01:00',NULL);
INSERT INTO api_keys VALUES(2,'1KZkpEyiMH',X'2432622431322438673039635a2f41376a6b6e444e69523531684e564f4d573665423056366179484b726c304565586f6851674373786d612e4c414b','2023-03-22 06:22:18.339101298+01:00','2023-04-13 09:32:24.318715268+02:00',NULL);
INSERT INTO api_keys VALUES(3,'6yBMrqvEDX',X'24326224313224764f6938636f6a677265624236424a33743559754e654742344d46674c427a4441314e38546166364578326151706b73305334544b','2023-04-13 09:32:23.864995051+02:00','2023-07-12 07:32:23.45+00:00',NULL);
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,"hostname" text,"user_id" integer,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`given_name` varchar(63),`forced_tags` text,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:6a9f06fccf0eff626075428e16c07c2e93464667a67c84dd0efadb1a74761d72','nodekey:d0d67c955181f1a9369a471496e1004678eebd93660394949848e61c7132ef9e','discokey:7667a90b1915f5cb3f725d159cd3f8bc3e46f6244df25f45d7fadc830a6d064e','web-05',1,'authKey',3,'2025-02-03 20:14:56.533547475+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["198.139.228.73:16016","[a5dd:542c:6998:997c:2d87:61b0:c760:ab6f]:56919","112.221.140.130:19743","[6520:763a:5fe2:8e88:5c8e:5b03:eeb1:5588]:20840","[7670:9084:a917:1173:70ce:2798:c805:66dc]:50297"]','2022-02-26 18:11:55.92837512+01:00','2025-02-03 20:14:56.533664987+01:00',NULL,'node001',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(3,'mkey:67287ef80f62664d68f3050e68ced4e8f78e173151801529551d42fd8e951b40','nodekey:6afc027970c1ddf9b3544b8c49223dcafe436a51384f80bb341a8f8322bef6d8','discokey:86693fc9f959f11015f3ff457b8d62381a6542e2eef097e2b6bdd679175c975b','srv-24',7,'authKey',NULL,'2025-01-29 12:28:39.61495602+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2cbd:607c:5e91:ea51:38ed:557:fd0:3405]:48307","[790b:6b18:8ac1:afa8:c2d3:f6b:37f6:623f]:41499"]','2022-03-01 19:26:46.242187887+01:00','2025-01-29 12:28:39.615036412+01:00',NULL,'node003',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:e0630dc6f407e6064c010dbef10b982c6e9d731706cc13b10993b542e81edf47','nodekey:44f96cda7202665271958eac8a3cfb120ea72209ee88d93fac3c23aeafa3a993','discokey:48b58784e2acdad30028ceed18bc9e7bd5fae3605dbef1a40f3f38a705adef9d','desktop-44',1,'authKey',6,'2025-02-03 15:13:03.806943975+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b53b:c286:a007:e851:dc6e:8152:82a5:22ca]:25604","[ff9b:6bbd:77bc:323d:12e4:22ba:b712:80c]:37729","[1e76:19af:e817:9a33:4f83:366e:b686:6362]:39521","57.71.157.166:9055","[c199:e8ca:c1bb:8364:dde8:bf3e:9467:c050]:61218"]','2022-03-04 08:27:19.383566031+01:00','2025-02-03 15:13:03.807014419+01:00',NULL,'node004',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(5,'mkey:4f7673e616b40b313ef69fd390e9c4bdb4c80f66840defb02c37d6f2fa152c5c','nodekey:91ee8b593bb0599e9583a692dabef9528423878f737f7bfdf339fc02bbe8ab47','discokey:fb3b2c151a0d277e77837dc2a5e96fe8f05bbefa770a84822689ec2c63dfe358','email-24',8,'authKey',NULL,'2025-02-03 11:10:38.911072801+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6add:4288:4372:c9ce:7cee:4852:e6d0:9d56]:44968","[884b:b2cc:e2f3:ab06:131b:e30c:69a2:363]:32943","49.81.27.127:23839"]','2022-03-05 13:54:23.660591381+01:00','2025-02-03 11:10:38.911239065+01:00',NULL,'node005',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(6,'mkey:e8a549e38c8301af3c044ff9ca1df86c814bc9c9a62bddd28ff47ebd9b113d07','nodekey:f0188064db0f31b49e1048044186d20700406a7a7b71b054507c90d5a79e7de4','discokey:30687e0c15fc480ef15f9d91011c9fa458c18370db11cdc8b72f36e814e9ece2','lt-01',1,'authkey',NULL,'2025-01-31 17:38:20.368668048+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[be53:e324:1587:4d86:d24c:8662:cd5c:a4c8]:58105","59.239.218.25:49807","[cfa4:ad2e:1410:3b78:ce03:b437:6749:ff3a]:39835"]','2022-03-21 15:52:20.739594362+01:00','2025-01-31 17:38:20.369001909+01:00',NULL,'node006',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(7,'mkey:45c951d703f782a16a6db8b4dc872952308f86883499d0613f03318d18f3e7fe','nodekey:70837c16d309644e71e6b251bdb66c4e6a5c9b9f6e23a3b803142b8f00d1017a','discokey:ebe6dd61b6b2bafccce9d01ba0d58ea2ee93a90ae6cafb4383453fb4a17441b4','desktop-61',4,'authkey',10,'2025-02-03 22:34:14.985433991+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e5e8:7d01:63fc:4220:3b4a:df5:ebe:748c]:47047","[7513:6321:b35:b633:b39e:41ed:10a1:3fdd]:462","[8dc0:10e:95b6:9954:2614:8dcc:6564:e167]:58499","[8e6d:95be:19a9:316a:d37e:bcb6:5e05:d7f0]:36162","[5bb2:705a:7f5c:3c9:db83:956a:1ce:5291]:9510"]','2022-04-01 22:43:27.318756043+02:00','2025-02-03 22:34:14.986222409+01:00',NULL,'node007',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(8,'mkey:3dff46782f13efbfe7b1a9d5d3275f48954a1abe29111b484fdb3c6edfb795bd','nodekey:080424852e9cbe3c2eaac52c1890cf485bbc2604615ec3c293b80322f17dbe63','discokey:2f6a05491ef99cafaf968c0c62b5c9d19083ef070991ee677d14b0ac9ce08377','db-70',7,'authkey',NULL,'2025-02-03 18:06:33.350444688+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["166.240.74.240:40259","[7311:ce3c:e8cf:c591:533:7132:4504:52ca]:48923","[4912:5cdb:3ed8:7c52:6b8b:2d37:59bf:cf98]:20693","[bad1:e653:831e:aa61:61e4:f824:996a:aac9]:11845"]','2022-04-03 09:38:46.178224968+02:00','2025-02-03 18:06:33.350771325+01:00',NULL,'node008',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(9,'mkey:05d3833026a1ecd188cc6d2b9b7f9c8a0c51baefabf20a167c85c0c6ef722669','nodekey:d281e1bea5bb2e5d2d01bf476a5ea0df5578a663211c2281dc757024f6233f90','discokey:010f415b1e41652b3eabcebdbaa1e2e62fb1412f817304c125776ecd45621fba','desktop-21',7,'cli',NULL,'2025-02-02 07:50:20.222960357+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6102:58dc:7ffb:200a:53e:b50d:38d5:45a8]:29126","32.34.123.165:35870","[1daf:274c:55b2:7413:3c1:bd3d:acc5:4eb1]:33732","182.237.82.235:32290","6.93.152.196:16212"]','2022-04-09 09:43:07.09027176+02:00','2025-02-02 07:50:20.223029247+01:00',NULL,'node009',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(10,'mkey:521fa99ee8b613be5da1bc0fa53e3a11806db23487572f13ce3a99b5750f47d8','nodekey:c2fd5b20a911b8193b7bc8e2dfe68598422759afb0cae2a1f6faf8a975133f68','discokey:99030d8be2cf14592175083adec1a15fdadb1181db721c9ce4f9e5ed485e8422','db-82',1,'authkey',NULL,'2025-02-01 10:52:14.603941206+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b12:6f03:406e:1855:3cf9:8eb6:e610:adbf]:18034","70.180.67.60:48287"]','2022-06-26 13:57:07.40762063+02:00','2025-02-01 10:52:14.604222347+01:00',NULL,'node010',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(11,'mkey:ad3363557d233776dee0fa50f7091eaa3b6b14b8d3b0243f0cc0f61662a01769','nodekey:f7a297c8b1bde8fea7e03e10a583e168a37a5c72d9ba3c39129536d4d80e9e6d','discokey:c4af50cd6bb472f0bc2bc3ded6336fb76708a902ba0032cdd6cb90eb819d9db1','laptop-60',1,'authkey',13,'2025-02-04 01:00:03.417141337+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[dba:4050:a7df:10:aa7c:ee6b:2610:5a14]:31519","128.57.253.0:39500","25.178.136.37:18298","86.9.216.195:48221"]','2022-06-26 15:19:50.566498735+02:00','2025-02-04 01:00:03.417910968+01:00',NULL,'node011',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(14,'mkey:224a190ba40d8ebf84ac065a47d4e370d127151dc5b608d2f062855e67951a5d','nodekey:a81c40b004ca1a472f2d2240ea3b86f55d5f52252254d5fab7643ba0e059b684','discokey:31644ea51b89d09e6568b6f78b604a62ee7f4a5e7c0a56f194717cdcc43a6384','email-58',1,'authkey',NULL,'2025-02-01 06:18:54.156166977+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["178.84.150.172:60924","[171f:b843:ff2e:b9f0:9890:1aac:42e5:c2ab]:47842","174.7.154.174:51720"]','2022-09-26 16:07:54.206927686+02:00','2025-02-01 06:18:54.156467144+01:00',NULL,'node014',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(23,'mkey:bafb298852c932db46635dc6ff11a41910936907bbc6bcc5dd2d8c485c2e5b0c','nodekey:bb4a7ef9aa1a821da2f76215bcb534c3a6a7658432dafaf88a1aecff0e75f782','discokey:f0e92a4c7368ee694d70928c8c4e14b207fd7f69dfead643ce4f616cdd7a1c13','web-96',1,'authkey',23,'2025-02-01 06:44:19.76979225+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["21.139.115.42:33169","211.231.253.41:1096","171.127.122.217:28477","197.123.99.18:53038"]','2023-05-05 10:08:17.301597525+02:00','2025-02-01 06:44:19.770530333+01:00',NULL,'node023','[]','100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(24,'mkey:7f865473ff4681875a1b31d7160ef2f4ba3c59cb9cfd815a6085dd266e1027a6','nodekey:86b906c4f3540ec63474279bf542136b24fe741f7944ca88c3bd3cea132906b7','discokey:c2f69d5e677759839a7761f43eb250d4faa1873ddbc53f3e4f1bc4ef98ab2041','db-96',1,'authkey',25,'2025-01-13 15:02:48.676721758+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f41f:b9e9:9205:210a:4ff9:ab34:57fd:3148]:21852","[3d49:412:9781:b399:f9a5:587e:bd2e:a579]:3775","[867:a7e:7e04:bfbb:6286:f95f:1abd:9b5a]:63765","147.22.45.153:11543","30.125.129.134:36303","[213c:e72:d34:c59c:d4fa:8bb5:f6d3:d691]:24926","83.92.114.14:38013"]','2023-08-14 18:15:34.292188686+02:00','2025-01-13 15:02:48.67679754+01:00',NULL,'node024','[]','100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(25,'mkey:1be02a7f57e51fa42c3af087a1464b33d33ad2802979d102c8b10ac146091537','nodekey:1fc37765c4fbcf068f0dd37f2b98d4d1fe35fc7c9e20ea8ed2be4b52b97481b4','discokey:9ea68ef044c00841bb6187dafedc8811caa4b12d123e00119eba0462b9dac6b2','db-52',1,'authkey',26,'2025-02-01 06:27:05.583933643+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f538:9546:a467:a160:1e3f:ad81:b5aa:f88d]:56031","14.178.248.81:54186","[dcb5:9eee:2075:acba:1a31:1669:21dd:744b]:48312","91.212.243.143:50528","33.141.84.140:39332"]','2023-08-29 08:30:45.518580154+02:00','2025-02-01 06:27:05.584696672+01:00',NULL,'node025','[]','100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(26,'mkey:5a1b0920cafe0a8b54af7194baceac2029c4b12afc0e542423637f47cc4e53e7','nodekey:927c5ab7c0b8288ca36897c5f371487e9dc2200f28507029e1864086d95b5b1e','discokey:260c9a090d46eef056c0d411d4097b41aa0e9902f15cfa59906ee85f526f52b6','srv-51',1,'authkey',27,'2025-02-03 23:37:12.671308191+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6676:38fc:5af9:3b60:41b7:e46e:bbe1:c8bf]:30898","[4aba:d70:c25d:5d4d:1bc0:d119:4749:9efc]:37269","[9320:382a:5779:2fa7:b46f:c4d5:f889:3155]:46058","[3d31:7ec5:7635:7b6c:c7d0:cf70:bb45:6922]:16454"]','2023-11-03 18:53:48.108033118+01:00','2025-02-03 23:37:12.672006599+01:00',NULL,'node026','[]','100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(27,'mkey:2ce8df9ae8623e48e779b951eab64134bf2806d747f1fb4d7669634fa48d9f22','nodekey:3e85d212d118f58a3a72de4d251ab9414dbe682ac3ebb36ff1283eb6fd438c7a','discokey:9e21249dc8a197f51dbd3916f74c977e222cb96639c4f17abb1856044c4593a1','srv-15',7,'authkey',NULL,'2025-02-02 21:00:46.231324685+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["169.217.181.115:16351","[60da:30ec:55bd:5ab3:3fe7:5492:1fc8:92f3]:36566","105.238.97.70:40193","[8c84:2d7e:5e1a:2f51:8754:aa54:b421:a19f]:60672","[5101:751a:5e00:cf46:8b50:8ba9:3c8e:4c7c]:33862","[b9fe:3630:1807:826:a4a6:e5d2:532c:bdc8]:43617","[25b5:5b72:2ecc:193c:b61e:329:81c6:5af6]:39854","214.128.115.35:43726","[436d:61b:9834:b0e0:b2ed:b452:6330:34ee]:59171"]','2023-12-29 19:18:10.814399482+01:00','2025-02-02 21:00:46.231636043+01:00',NULL,'node027','[]','100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(29,'mkey:2e4b2ebd78830b52e6d3bc2df58a4ae2e650aa2d45d05e556b6f412ec26797b3','nodekey:b12b04927b21983c33d4e6343dbc3ca854cdddea3d53f116c79d2029cb017a36','discokey:9cd971dee5320ec78268f1c672aeea1f7ab1e88d1d97a27d1f6fd08154f2dc9b','srv-55',1,'authkey',NULL,'2025-02-03 21:59:46.11595827+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c4c8:bd7a:122a:a5f6:664b:2744:fa5:2148]:38679","[1b3d:ef50:26cd:7cdc:d63b:eafd:a9d6:9432]:33036","[3b4a:1ade:51ce:e1f2:a6b8:8e5f:76d7:a0ac]:49522","141.1.118.254:20536"]','2024-06-02 09:46:39.307697473+02:00','2025-02-03 21:59:46.116259679+01:00',NULL,'node029','[]','100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(30,'mkey:a186e5e70f59e2fd804383e339a670ed2c312ec724ed0a389fe032921f697416','nodekey:2695f24b44d79bb02448dca69cd123fb5ff88dfccb27df9f9f57fb161ccb8697','discokey:726229d0e17c4a9253ae9c3fea0917aa2b5ace2d5b7bb6b17702502d9d22cae3','srv-45',1,'authkey',30,'2025-02-01 06:45:41.071375563+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[cec4:d571:6561:992:e89f:e420:6681:42b5]:43741","96.163.138.14:53535","[7692:18d5:2f41:257d:dc1b:c70a:ea6c:1ad1]:56437","203.8.194.84:16031","54.25.61.205:2000"]','2024-07-29 14:24:27.684620193+02:00','2025-02-01 06:45:41.072086485+01:00',NULL,'node030','[]','100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(31,'mkey:7b374d2331a08697dc07b40066b707444d63dc02ec83a683e3cfb75f507e7219','nodekey:972d7a74740a75e43160bfa760aebfc273f3cab325abf9fdaa05d188615af553','discokey:9eaa7700bbc80de6cf2a7e115ff486727bc0bf063ccb2df44350c1a3e360fe90','lt-91',1,'authkey',31,'2025-02-03 20:18:00.015726064+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c7b3:52c3:f5c3:87c:f5ed:213:85f4:44c5]:18304","49.111.96.135:35528","[abc1:b7cd:f18:6ed2:4b5a:9dce:3f08:8c17]:333","206.118.184.48:48132","7.64.160.114:11101"]','2024-08-07 20:35:12.944541318+02:00','2025-02-03 20:18:00.016420173+01:00',NULL,'node031','[]','100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(32,'mkey:8010732f3bbb0f58f3002b645258dbbc7d6c5cfebf8a485685a84da9b30dcf00','nodekey:d34dac3b348cd2d100ba36a85b42542cfe1dc74d51197caf50b138fea1401168','discokey:e28e9f435da77357942130f3923bb584773e6812d8d27fdc6dce20cc0cc0f752','lt-44',1,'cli',NULL,'2025-02-04 01:12:27.847003546+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["85.212.234.244:43593","161.5.250.27:14020","[cd55:bf01:5540:c30:3981:7f71:a471:4993]:25285","24.16.62.70:35569","213.115.82.246:7596","195.216.27.246:54466","[c47f:35c9:41fe:6f5:a40d:3e8b:6679:411e]:12963","19.205.218.60:63516","116.228.193.194:44296","[ee98:8de3:1f5b:731c:751b:ba46:a4a7:8760]:23245","[6eb3:8c34:e6c9:4c6a:25c9:89ca:c165:354e]:65112","[7003:63bb:6429:d463:96a6:990:2bdc:217d]:4300","[d820:584e:2b46:6915:6420:3056:f76:9e33]:48885"]','2024-10-26 07:18:04.947942936+02:00','2025-02-04 01:12:27.847267263+01:00',NULL,'node032',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2022-02-26 18:00:56.104436744+01:00','2024-09-14 08:51:13.31135114+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2022-04-01 22:30:02.657653341+02:00','2024-09-14 08:55:27.877614108+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2024-05-05 07:08:47.915309504+02:00','2024-09-14 08:55:02.778476991+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2024-09-14 08:57:26.215082073+02:00','2024-09-14 08:57:26.215082073+02:00',NULL,'user008','','',NULL,NULL,'');
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(7,'2023-01-15 14:41:49.445054371+01:00','2023-01-29 10:12:11.959527554+01:00',NULL,14,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(8,'2023-01-15 14:41:49.452617331+01:00','2023-01-29 10:12:13.154311101+01:00',NULL,14,'::/0',1,1,0);
INSERT INTO routes VALUES(9,'2024-05-05 07:16:02.944084847+02:00','2024-05-05 13:25:02.977065366+02:00',NULL,3,'10.138.98.32/27',1,1,1);
INSERT INTO routes VALUES(10,'2024-05-05 07:16:02.95709561+02:00','2024-05-05 13:25:04.513930181+02:00',NULL,3,'192.168.208.0/20',1,1,1);
INSERT INTO routes VALUES(11,'2024-05-05 12:46:08.770263657+02:00','2024-05-05 12:46:39.012076195+02:00',NULL,27,'172.19.128.0/20',1,1,1);
INSERT INTO routes VALUES(12,'2024-05-05 12:46:08.779527998+02:00','2024-05-05 12:46:39.843489833+02:00',NULL,27,'10.68.0.0/14',1,1,1);
INSERT INTO routes VALUES(13,'2024-05-05 12:46:08.787239639+02:00','2024-05-05 12:46:40.983839193+02:00',NULL,27,'10.243.219.68/31',1,1,1);
INSERT INTO routes VALUES(14,'2024-05-05 12:46:08.794135892+02:00','2024-08-18 08:45:35.831813635+02:00',NULL,27,'10.30.155.128/25',1,1,1);
INSERT INTO routes VALUES(15,'2024-05-05 12:46:08.799975671+02:00','2024-05-05 12:46:44.333956126+02:00',NULL,27,'10.64.0.0/13',1,1,1);
INSERT INTO routes VALUES(16,'2024-05-05 12:46:08.806879988+02:00','2024-05-05 12:46:45.422824419+02:00',NULL,27,'192.168.0.0/16',1,1,1);
INSERT INTO routes VALUES(17,'2024-08-08 20:44:22.76306591+02:00','2024-12-21 12:10:07.339044415+01:00',NULL,31,'172.27.33.0/24',1,1,1);
INSERT INTO routes VALUES(18,'2024-08-08 20:47:33.469970726+02:00','2024-12-21 12:10:07.442783446+01:00',NULL,31,'10.151.196.0/23',1,1,1);
INSERT INTO routes VALUES(21,'2024-08-08 20:54:05.146666051+02:00','2024-12-21 12:10:07.538738125+01:00',NULL,31,'192.168.33.128/26',1,1,1);
INSERT INTO routes VALUES(23,'2024-08-08 20:54:05.162212208+02:00','2024-12-21 12:10:07.644714175+01:00',NULL,31,'10.69.87.96/27',1,1,1);
INSERT INTO routes VALUES(25,'2024-08-08 20:54:05.179419681+02:00','2024-12-21 12:10:07.753927883+01:00',NULL,31,'192.168.240.184/30',1,1,1);
INSERT INTO routes VALUES(26,'2024-08-08 20:54:05.186132539+02:00','2024-12-21 12:10:07.871905187+01:00',NULL,31,'172.19.162.160/27',1,1,1);
INSERT INTO routes VALUES(28,'2024-08-08 20:54:05.202442818+02:00','2024-12-21 12:10:07.972132539+01:00',NULL,31,'172.30.190.136/30',1,1,1);
INSERT INTO routes VALUES(31,'2024-08-08 20:54:05.246698925+02:00','2024-12-21 12:10:08.150358433+01:00',NULL,31,'10.241.118.90/31',1,1,1);
INSERT INTO routes VALUES(32,'2024-08-08 20:54:05.256984635+02:00','2024-12-21 12:10:08.349521909+01:00',NULL,31,'192.168.0.0/17',1,1,1);
INSERT INTO routes VALUES(37,'2024-08-08 20:54:05.300971626+02:00','2024-12-21 12:10:08.553265285+01:00',NULL,31,'192.168.192.0/19',1,1,1);
INSERT INTO routes VALUES(43,'2024-08-08 20:54:05.383430747+02:00','2024-12-21 12:10:08.66112581+01:00',NULL,31,'172.29.254.8/29',1,1,1);
INSERT INTO routes VALUES(47,'2024-08-08 20:54:05.443181025+02:00','2024-12-21 12:10:08.826993878+01:00',NULL,31,'172.18.8.0/22',1,1,1);
INSERT INTO routes VALUES(48,'2024-08-08 20:54:05.449778605+02:00','2024-12-21 12:10:09.237117302+01:00',NULL,31,'10.169.34.250/31',1,1,1);
INSERT INTO routes VALUES(49,'2024-09-03 06:43:34.875117755+02:00','2024-12-21 12:10:09.342259317+01:00',NULL,31,'172.24.0.0/16',1,1,1);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,98 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
INSERT INTO migrations VALUES('202501311657');
INSERT INTO migrations VALUES('202502070949');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,"user_id" integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'c0e73b52c1706fcceea368ae07c19c0e91fbe1f78eff2f7b',1,0,1,0,'2022-02-26 17:02:32.568878371+00:00','2022-02-26 18:11:15.388354971+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'ad293159f9506a02d6de4730e5a2ddb74f9fd4033919ecc5',1,0,1,1,'2022-02-26 17:08:07.828690446+00:00','2022-02-26 18:11:18.890985216+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(3,'66c7e0fbf74010ea2e153d35ffa0f3c48380ef38960d1fd1',1,0,0,1,'2022-02-26 17:11:54.149663776+00:00','2022-02-26 17:16:54.147175388+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(4,'cdbb69c88fabdc2609050c7f99e8ebdea6fcf81a50d802fc',1,0,0,1,'2022-02-26 17:15:34.160746962+00:00','2022-02-26 17:20:34.15935255+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(6,'0a99889a217a2f9cdd20082faadd5c90e72c83a47093a63a',1,0,0,1,'2022-03-04 07:27:17.535172209+00:00','2022-03-04 07:32:17.531871524+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(10,'6e88409e3883c1a47249e428030afd4a46bdaf3adb3b74c1',4,0,0,1,'2022-04-01 20:43:21.757703546+00:00','2022-04-01 20:48:21.756458144+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(13,'9d3c2bde9fcef181a3141dfe59d449bf03f6779dad3580e0',1,0,0,1,'2022-06-26 13:19:48.533865696+00:00','2022-06-26 13:24:48.532164552+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(16,'00b123d52ea8f58379b740fdc5c898b02330ab9b366cb1b4',1,0,0,1,'2023-02-12 06:21:30.15120385+00:00','2023-02-12 06:26:30.140082454+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(17,'c471ce93392c0d3040af0cf6166f4f578c3c66dd180b6e0b',1,0,0,1,'2023-02-12 06:26:55.829311638+00:00','2023-02-12 06:31:55.824701077+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(18,'fe0a438e67687540efcbbbc28c8e6c1b8ac1216f99de33d4',1,0,0,1,'2023-02-12 06:31:13.245185592+00:00','2023-02-12 06:36:13.241695106+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(19,'5a469043f1fa43ff11e54ea242dd882a81aea68f168b9a34',1,0,0,1,'2023-02-12 06:31:13.622545545+00:00','2023-02-12 06:36:13.560890824+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(20,'8b31d9a38282dfe07ffcebdfbd40db6b9e49997c93bed570',1,0,0,1,'2023-02-28 12:45:48.518939706+00:00','2023-02-28 12:50:48.445951259+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(21,'47a4216f2b4e5885d4e53a3de2ffe95521d8a708ca26d31e',1,0,0,1,'2023-02-28 12:45:48.53865321+00:00','2023-02-28 12:50:48.439132728+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(22,'1b7be83871f396e4544c8445acfc8d308dbfe29c7f0197f0',1,0,0,1,'2023-02-28 12:45:48.538806791+00:00','2023-02-28 12:50:48.445073692+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(23,'c9f364adba95c6c46c162eaa3786702805595841c0150927',1,0,0,1,'2023-05-05 08:08:16.73107293+00:00','2023-05-05 08:13:16.722921676+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(24,'a90c87e30fa22ffee39e5ce157dd22c909f2026295e3bce4',1,0,0,1,'2023-08-14 14:36:52.042138928+00:00','2023-08-14 14:41:52.038644473+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(25,'bb059cde5663619a8918bde19b9f8236085725554d9d78c2',1,0,0,1,'2023-08-14 16:15:33.722630834+00:00','2023-08-14 16:20:33.719604033+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(26,'0733b8fc67adc82644c87a95947b24c5d368c633cff92eb4',1,0,0,1,'2023-08-29 06:30:44.934900329+00:00','2023-08-29 06:35:44.931280114+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(27,'567f3a39066fd99c567d14bcc374b25cee0ad71af08b9054',1,0,0,1,'2023-11-03 17:53:45.857200883+00:00','2023-11-03 17:58:45.853742836+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(30,'8aa13c93cbef46d36c8159da51fb41a469ae04f932980890',1,0,0,1,'2024-07-29 12:24:27.140614087+00:00','2024-07-29 12:29:27.136525982+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(31,'9314b171abc433d73b8db297c1c5c65dae0be53d39a71520',1,0,0,1,'2024-08-07 18:35:12.375119763+00:00','2024-08-07 18:40:12.371590392+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(32,'6a8fd483387734664f2a911545150a9bc0d9f12a744fe913',7,0,0,0,'2025-02-23 06:56:50.319087142+00:00','2025-02-23 07:56:50.31726796+00:00','[]');
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
INSERT INTO api_keys VALUES(1,'S2nn85NliD',X'2432622431322471797064584939764e3848783749615457324d53536534503451464b39573657556d417370354c396f38427037477538554d6d4d57','2022-12-25 21:35:28.644697962+01:00','2023-03-22 06:22:18.724817647+01:00',NULL);
INSERT INTO api_keys VALUES(2,'1KZkpEyiMH',X'243262243132247055452f5068466c77784e7a69596443565139666d75416d426a614978717230764d5253613459455254674c336556795051367669','2023-03-22 06:22:18.339101298+01:00','2023-04-13 09:32:24.318715268+02:00',NULL);
INSERT INTO api_keys VALUES(3,'6yBMrqvEDX',X'243262243132244838672e4c4b6330506c526266486e497868645779657737782f42334c433831335566634c4e627432497979556e4f76737179614f','2023-04-13 09:32:23.864995051+02:00','2023-07-12 07:32:23.45+00:00',NULL);
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,"hostname" text,"user_id" integer,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`given_name` varchar(63),`forced_tags` text,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:13adef46b653fc9d24415b242714d08a92605cb2d53355a03cda8bae483cc93d','nodekey:aca177c7ceeadf615c5d28bd894ddad5133fe0e99e6c5f2a4af5403daf74aac6','discokey:83f177b585a16eab54768d0284553d62d3f46ef8a21417834039525dfd9ac7dd','desktop-00',1,'authKey',3,'2025-02-25 11:05:11.775075937+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ce6f:3f5b:da2f:8382:f3a1:e2d4:1c47:fe5e]:25604","[ff9b:6bbd:77bc:323d:12e4:22ba:b712:80c]:37729","[1e76:19af:e817:9a33:4f83:366e:b686:6362]:39521","57.71.157.166:9055","[c199:e8ca:c1bb:8364:dde8:bf3e:9467:c050]:61218"]','2022-02-26 18:11:55.92837512+01:00','2025-02-25 11:05:11.775803871+01:00',NULL,'node001',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(3,'mkey:4f7673e616b40b313ef69fd390e9c4bdb4c80f66840defb02c37d6f2fa152c5c','nodekey:91ee8b593bb0599e9583a692dabef9528423878f737f7bfdf339fc02bbe8ab47','discokey:fb3b2c151a0d277e77837dc2a5e96fe8f05bbefa770a84822689ec2c63dfe358','email-24',7,'authKey',NULL,'2025-02-17 20:00:56.633030391+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6add:4288:4372:c9ce:7cee:4852:e6d0:9d56]:44968","[884b:b2cc:e2f3:ab06:131b:e30c:69a2:363]:32943"]','2022-03-01 19:26:46.242187887+01:00','2025-02-17 20:00:56.633298676+01:00',NULL,'node003',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:3a04f3ec6375cf82c44ce30f04f10f753e2785864c35af3838883ed175e220df','nodekey:8d53294925a1cfb59b2bb60ca7846119a841c4dec2bd4dd1f47750815f8ba332','discokey:98216fd248ca55f2b099d83c9ff8f85dd3005b64b5b52a283604ede6ea587ad2','email-39',1,'authKey',6,'2025-02-24 06:38:04.606923061+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f906:29af:dabc:6ef0:a2b3:64a1:c36c:ac7a]:24154","[be53:e324:1587:4d86:d24c:8662:cd5c:a4c8]:58105","59.239.218.25:49807","[cfa4:ad2e:1410:3b78:ce03:b437:6749:ff3a]:39835"]','2022-03-04 08:27:19.383566031+01:00','2025-02-24 06:38:04.607016538+01:00',NULL,'node004',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(5,'mkey:45c951d703f782a16a6db8b4dc872952308f86883499d0613f03318d18f3e7fe','nodekey:70837c16d309644e71e6b251bdb66c4e6a5c9b9f6e23a3b803142b8f00d1017a','discokey:ebe6dd61b6b2bafccce9d01ba0d58ea2ee93a90ae6cafb4383453fb4a17441b4','desktop-61',8,'authKey',NULL,'2025-02-23 12:50:07.992065346+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e5e8:7d01:63fc:4220:3b4a:df5:ebe:748c]:47047","[7513:6321:b35:b633:b39e:41ed:10a1:3fdd]:462","[8dc0:10e:95b6:9954:2614:8dcc:6564:e167]:58499","[8e6d:95be:19a9:316a:d37e:bcb6:5e05:d7f0]:36162","[5bb2:705a:7f5c:3c9:db83:956a:1ce:5291]:9510","37.24.123.232:17607"]','2022-03-05 13:54:23.660591381+01:00','2025-02-23 12:50:07.99213101+01:00',NULL,'node005',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(6,'mkey:41996a93d33f8d668b8138c76f7f6ade6a105ea47d72342a14d470da88afd9f7','nodekey:3d3bd1e69adec0d7fa68d8a835bc25d381cf6b371077941e98362efd62aa38cd','discokey:70213a9865b98fb97c6dc05dff42b6260ecfb1b0b38e9de3fcf1199f36ea2ea0','laptop-78',1,'authkey',NULL,'2025-02-23 08:38:50.091332342+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[533:7131:4504:52ca:972e:c82:4ea1:ace2]:58915","58.226.203.77:32176","110.30.79.130:11845"]','2022-03-21 15:52:20.739594362+01:00','2025-02-23 08:38:50.091690948+01:00',NULL,'node006',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(7,'mkey:05d3833026a1ecd188cc6d2b9b7f9c8a0c51baefabf20a167c85c0c6ef722669','nodekey:d281e1bea5bb2e5d2d01bf476a5ea0df5578a663211c2281dc757024f6233f90','discokey:010f415b1e41652b3eabcebdbaa1e2e62fb1412f817304c125776ecd45621fba','desktop-21',4,'authkey',10,'2025-02-25 10:09:14.062758838+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6102:58dc:7ffb:200a:53e:b50d:38d5:45a8]:29126","32.34.123.165:35870","[1daf:274c:55b2:7413:3c1:bd3d:acc5:4eb1]:33732","182.237.82.235:32290","6.93.152.196:16212"]','2022-04-01 22:43:27.318756043+02:00','2025-02-25 10:09:14.063518972+01:00',NULL,'node007',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(8,'mkey:521fa99ee8b613be5da1bc0fa53e3a11806db23487572f13ce3a99b5750f47d8','nodekey:c2fd5b20a911b8193b7bc8e2dfe68598422759afb0cae2a1f6faf8a975133f68','discokey:99030d8be2cf14592175083adec1a15fdadb1181db721c9ce4f9e5ed485e8422','db-82',7,'authkey',NULL,'2025-02-24 18:51:08.679119377+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b12:6f03:406e:1855:3cf9:8eb6:e610:adbf]:18034","70.180.67.60:48287","141.100.183.252:19523","[e416:9931:8e9:6fcb:6d36:2e45:fe82:5ffe]:30261","215.10.187.249:19488","[bfe7:ebf6:e338:79a6:dba:4051:a7df:10]:31519","128.57.253.0:39500"]','2022-04-03 09:38:46.178224968+02:00','2025-02-24 18:51:08.679420095+01:00',NULL,'node008',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(9,'mkey:74ffa28c2f79c597df6d2584dc81317a09559002ef1c124d79c0961739f04628','nodekey:5df40a5c1b1c89b50f9c3a49445012ab5fe70691a639f09405cfabb7c4e57f62','discokey:40c0492a46b45647cec73ec454d030beb08e2efa406a1505937abc3cf3aa4886','web-41',7,'cli',NULL,'2025-02-24 19:06:53.63097265+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[235e:a50d:c131:2e8:80a6:4826:7e56:cc6e]:43129","[3486:5bc7:ada8:8da1:9df9:3cc6:d018:ee8b]:65112","43.182.159.11:27315","[12a4:b567:a06e:b675:a878:2f42:e5e1:429f]:60924","[171f:b843:ff2e:b9f0:9890:1aac:42e5:c2ab]:47842"]','2022-04-09 09:43:07.09027176+02:00','2025-02-24 19:06:53.631097606+01:00',NULL,'node009',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(10,'mkey:381acb630a8426dc0e69e99cb0fc8994f8df14864459adafb8c33c856481277c','nodekey:8ce541404b26c374b025803ff060a5752800114358b0520bb5370cfe4b7b7ab9','discokey:c531655c46cf50d2c752e28c7d52f1e20795936863cc4c9074f1c1eb7230cc75','laptop-07',1,'authkey',NULL,'2025-02-23 08:14:09.262507807+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[571:ac10:e700:fdbd:6084:e1ec:7273:7f9f]:46051","21.139.115.42:33169"]','2022-06-26 13:57:07.40762063+02:00','2025-02-23 08:14:09.26323988+01:00',NULL,'node010',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(11,'mkey:ec475b374671562006704de6f1be902a3d75079e8c9a3b52e6c3d6dc37d3086a','nodekey:655232f4f4205ddc98661144bd7a05a975f44a3f01ed22e18927e6265329104a','discokey:b30f00fbda4b3a7ed66ff30ac8c41c0c1c04a775756543f27155e1b93f947eca','db-05',1,'authkey',13,'2025-02-24 23:14:30.021124861+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f2e:fd97:b513:b737:33f3:dd2b:df4:a90e]:41096","155.239.169.182:41163","[c908:b81c:b4c8:38d3:e311:b3f6:3067:227c]:11541","[f41f:b9e9:9205:210a:4ff9:ab34:57fd:3148]:21852","[3d49:412:9781:b399:f9a5:587e:bd2e:a579]:3775"]','2022-06-26 15:19:50.566498735+02:00','2025-02-24 23:14:30.021972171+01:00',NULL,'node011',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(14,'mkey:624da83bf38200687af1e4771f9392a903d156e9b9495bafb84adb021e0fac4d','nodekey:13984780af686ba7da0433dd5c0dd04157b929f923291b809cca20e0fcf9de14','discokey:f9ebece3311c35c7efd854261a8505261d347db67e3bcb0f38bdb0631dca6d89','laptop-03',1,'authkey',NULL,'2025-02-23 08:19:10.390225858+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["30.125.129.134:36303","[213c:e72:d34:c59c:d4fa:8bb5:f6d3:d691]:24926","83.92.114.14:38013"]','2022-09-26 16:07:54.206927686+02:00','2025-02-23 08:19:10.39053916+01:00',NULL,'node014',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(23,'mkey:1be02a7f57e51fa42c3af087a1464b33d33ad2802979d102c8b10ac146091537','nodekey:1fc37765c4fbcf068f0dd37f2b98d4d1fe35fc7c9e20ea8ed2be4b52b97481b4','discokey:9ea68ef044c00841bb6187dafedc8811caa4b12d123e00119eba0462b9dac6b2','db-52',1,'authkey',23,'2025-02-10 07:17:23.651226796+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f538:9546:a467:a160:1e3f:ad81:b5aa:f88d]:56031","14.178.248.81:54186","[dcb5:9eee:2075:acba:1a31:1669:21dd:744b]:48312","91.212.243.143:50528"]','2023-05-05 10:08:17.301597525+02:00','2025-02-10 07:17:23.651369947+01:00',NULL,'node023','[]','100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(24,'mkey:a0099c574ba14cdf6db0a2591d2874960f00cb106129315d4e406b605c288353','nodekey:9cef74269ce1f9ee2648676a8298a169da6f5e2ef84ce0699559e4627279338c','discokey:dd188ff283fcda7d3e0fe5fd611b6e959fde88c50ecea39e06ba3b907e6fc39b','lt-44',1,'authkey',25,'2025-01-13 15:02:48.676721758+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[48f9:df69:4387:ae57:b06c:1439:7821:792]:45333","12.27.126.70:46578","[8b32:e301:3c59:346b:8ee6:c646:97a6:99ec]:36499","185.25.84.152:44786","[c7d0:cf6f:bb45:6922:7fd7:adb7:59f5:499e]:60522","65.200.68.231:16530","11.209.67.55:8308"]','2023-08-14 18:15:34.292188686+02:00','2025-01-13 15:02:48.67679754+01:00',NULL,'node024','[]','100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(25,'mkey:54219375ce0ab01cd59b56ad984df668ae7cbe49b7b91e44877ae0d7012d6106','nodekey:2b0c163bc497f6214b25d6a333a37d273c260630dcc91782897f19a579f92a5b','discokey:4cf24a025241ad9a69c20d40513dfee5626f934d738e18f4a64fd9a1ace2cb24','srv-15',1,'authkey',26,'2025-02-15 09:38:06.967090699+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[60da:30ec:55bd:5ab3:3fe7:5492:1fc8:92f3]:36566","105.238.97.70:40193","[8c84:2d7e:5e1a:2f51:8754:aa54:b421:a19f]:60672","[5101:751a:5e00:cf46:8b50:8ba9:3c8e:4c7c]:33862"]','2023-08-29 08:30:45.518580154+02:00','2025-02-15 09:38:06.967816068+01:00',NULL,'node025','[]','100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(26,'mkey:96e8e0e986089fe5d0f5418f7ccb0a701401def77b8c5e1c337e7c5b865aa20c','nodekey:0e01df602ea65f549245772540b04373a8f2ab64a781251598226e99a6fc341f','discokey:444d74201443318337b9c8118b6d62ab087049cd1258b1b670dd3d8b8b883bd0','lt-82',1,'authkey',27,'2025-02-25 11:26:22.780339791+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["12.54.208.97:59171","[13a0:b8ff:bebb:d48:e16e:869d:b542:531b]:17201","44.157.88.255:43418","8.250.82.20:52374"]','2023-11-03 18:53:48.108033118+01:00','2025-02-25 11:26:22.781062875+01:00',NULL,'node026','[]','100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(29,'mkey:8ba830e2027bf650dfb541fcecc1f2cd5e20da44d6b333434e06cc9b17b9d4d4','nodekey:c0f946e33505da4340c838ca01cd3c0c1dda4d73f42a5609709f48727841e316','discokey:d380435e5b89c56938fb4a1c71ce024df4a01e8d5cfeb95e21c4c5d2b9e3a395','web-21',1,'authkey',NULL,'2025-02-25 10:54:54.677120077+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["54.149.91.210:26635","210.72.228.199:14674","101.172.44.176:5878","[c018:a17d:2177:f7b8:482d:b68b:9b7a:c3f4]:52482"]','2024-06-02 09:46:39.307697473+02:00','2025-02-25 10:54:54.677452704+01:00',NULL,'node029','[]','100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(30,'mkey:bba58c946e9f67a39d4a8f0f36b64169c0baf421e280fb4ace27827385444ff8','nodekey:f1e7106cf01ac4b975fc1176b9ca93e8ed17b4f406a5e4c7dffa4d7f003b2ced','discokey:98979075a00ac5b3b0b193011ceca8608729166168eecbe99cb9bb8ff59df080','srv-98',1,'authkey',30,'2025-02-15 09:20:40.349716088+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c7df:a6c9:ae51:6570:f6b6:7d2c:1803:50f0]:6218","62.26.91.22:45257","37.207.25.123:5981","[5b20:30d9:10ce:eafd:90f2:bf34:b3e8:fedb]:18638"]','2024-07-29 14:24:27.684620193+02:00','2025-02-15 09:20:40.350483576+01:00',NULL,'node030','[]','100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(31,'mkey:8de33b4e277715f445a3530365044c55cc63c9b1abf4b586d017fbfdfa8a5b0e','nodekey:519bbb0b96ac86e86baf7dc5b9c92dd59eb3907c6e45f242aa0f3989b87f6c3e','discokey:65ff26a4a3d846c72e104d7cf5c22372c435f781ad1c0aeb99b40f046c3dfb67','lt-92',1,'authkey',31,'2025-02-25 10:56:26.138523564+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["183.225.17.130:38581","128.41.168.9:19215","39.206.106.178:64472","[a3b:5db7:67ad:9dfa:1b70:91c6:15ae:e5ad]:26117"]','2024-08-07 20:35:12.944541318+02:00','2025-02-25 10:56:26.139732495+01:00',NULL,'node031','[]','100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(32,'mkey:41c6942d339502595b451a83099f62811b65eb38dab6332b80dc801ee24a2b3e','nodekey:bfa1d578b0f89f1bf88249ef93aeaebd64e434ab28376e0f312694f979438ad7','discokey:f86c45ad30b7c20300756d34059a6e025ef9f7f477614544f2e433d36d546fd9','desktop-10',1,'cli',NULL,'2025-02-25 11:30:05.852369159+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9b41:6262:cbeb:cfa9:3f72:a287:5524:c052]:8383","[3981:7f70:a471:4993:c3a4:3173:1b62:544e]:43648","200.130.212.85:63469","216.16.62.70:35569","213.115.82.246:7596","195.216.27.246:54466","[c47f:35c9:41fe:6f5:a40d:3e8b:6679:411e]:12963","19.205.218.60:63516","116.228.193.194:44296","[ee98:8de3:1f5b:731c:751b:ba46:a4a7:8760]:23245","[6eb3:8c34:e6c9:4c6a:25c9:89ca:c165:354e]:65112","[7003:63bb:6429:d463:96a6:990:2bdc:217d]:4300","[d820:584e:2b46:6915:6420:3056:f76:9e33]:48885"]','2024-10-26 07:18:04.947942936+02:00','2025-02-25 11:30:05.852688962+01:00',NULL,'node032',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
INSERT INTO nodes VALUES(33,'mkey:448ecfac13b4affb86e121ffbff9da87acabac6c21dee28de2eb3371ea8276b5','nodekey:dd35ae383e1ae1af878c3c16cbd53f09e9ebaafc8787cb3d632954ed7ac9e277','discokey:beeb96403422394aa40bb619a3b582d50453e851815173c5b30d7163f4ed6ce0','lt-02',7,'cli',NULL,'2025-02-24 20:01:06.886972101+01:00',NULL,'{"fake":"data"}','["131.88.182.238:63239","146.198.220.228:37962","[bc8:3c85:dde1:8c19:4d87:a3ca:f9f4:3c6f]:20142","[785b:eebc:c3a6:bde6:f89:927:da7f:190b]:3639","68.183.1.227:6112","[9fd7:101c:db80:8423:7697:70:2c52:cbbc]:17162","67.6.72.132:32571","[524:9a03:6a60:cc60:d594:b98e:e32f:d883]:8390","86.91.139.227:63567"]','2025-02-23 07:59:15.141530181+01:00','2025-02-24 20:01:06.88755488+01:00',NULL,'node033',NULL,'100.64.0.11','fd7a:115c:a1e0::b');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(7,'2023-01-15 14:41:49.445054371+01:00','2023-01-29 10:12:11.959527554+01:00',NULL,14,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(8,'2023-01-15 14:41:49.452617331+01:00','2023-01-29 10:12:13.154311101+01:00',NULL,14,'::/0',1,1,0);
INSERT INTO routes VALUES(9,'2024-05-05 07:16:02.944084847+02:00','2024-05-05 13:25:02.977065366+02:00',NULL,3,'172.30.190.136/30',1,1,1);
INSERT INTO routes VALUES(10,'2024-05-05 07:16:02.95709561+02:00','2024-05-05 13:25:04.513930181+02:00',NULL,3,'10.241.118.90/31',1,1,1);
INSERT INTO routes VALUES(17,'2024-08-08 20:44:22.76306591+02:00','2024-12-21 12:10:07.339044415+01:00',NULL,31,'192.168.0.0/17',1,1,1);
INSERT INTO routes VALUES(18,'2024-08-08 20:47:33.469970726+02:00','2024-12-21 12:10:07.442783446+01:00',NULL,31,'192.168.192.0/19',1,1,1);
INSERT INTO routes VALUES(21,'2024-08-08 20:54:05.146666051+02:00','2024-12-21 12:10:07.538738125+01:00',NULL,31,'172.29.254.8/29',1,1,1);
INSERT INTO routes VALUES(23,'2024-08-08 20:54:05.162212208+02:00','2024-12-21 12:10:07.644714175+01:00',NULL,31,'172.18.8.0/22',1,1,1);
INSERT INTO routes VALUES(25,'2024-08-08 20:54:05.179419681+02:00','2024-12-21 12:10:07.753927883+01:00',NULL,31,'10.169.34.250/31',1,1,1);
INSERT INTO routes VALUES(26,'2024-08-08 20:54:05.186132539+02:00','2024-12-21 12:10:07.871905187+01:00',NULL,31,'172.24.0.0/16',1,1,1);
INSERT INTO routes VALUES(28,'2024-08-08 20:54:05.202442818+02:00','2024-12-21 12:10:07.972132539+01:00',NULL,31,'10.149.80.0/20',1,1,1);
INSERT INTO routes VALUES(31,'2024-08-08 20:54:05.246698925+02:00','2024-12-21 12:10:08.150358433+01:00',NULL,31,'10.232.0.0/13',1,1,1);
INSERT INTO routes VALUES(32,'2024-08-08 20:54:05.256984635+02:00','2024-12-21 12:10:08.349521909+01:00',NULL,31,'172.23.0.0/21',1,1,1);
INSERT INTO routes VALUES(37,'2024-08-08 20:54:05.300971626+02:00','2024-12-21 12:10:08.553265285+01:00',NULL,31,'172.17.124.137/32',1,1,1);
INSERT INTO routes VALUES(43,'2024-08-08 20:54:05.383430747+02:00','2024-12-21 12:10:08.66112581+01:00',NULL,31,'10.91.8.0/21',1,1,1);
INSERT INTO routes VALUES(47,'2024-08-08 20:54:05.443181025+02:00','2024-12-21 12:10:08.826993878+01:00',NULL,31,'192.168.222.64/27',1,1,1);
INSERT INTO routes VALUES(48,'2024-08-08 20:54:05.449778605+02:00','2024-12-21 12:10:09.237117302+01:00',NULL,31,'10.16.0.0/12',1,1,1);
INSERT INTO routes VALUES(49,'2024-09-03 06:43:34.875117755+02:00','2024-12-21 12:10:09.342259317+01:00',NULL,31,'192.168.191.192/28',1,1,1);
INSERT INTO routes VALUES(50,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'10.225.156.72/29',1,1,1);
INSERT INTO routes VALUES(51,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'172.28.71.145/32',1,1,1);
INSERT INTO routes VALUES(52,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'10.104.0.0/13',1,1,1);
INSERT INTO routes VALUES(53,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'172.16.0.0/13',1,1,1);
INSERT INTO routes VALUES(54,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'10.60.104.0/24',1,1,1);
INSERT INTO routes VALUES(55,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'10.89.96.0/19',1,1,1);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2022-02-26 18:00:56.104436744+01:00','2024-09-14 08:51:13.31135114+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2022-04-01 22:30:02.657653341+02:00','2024-09-14 08:55:27.877614108+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2024-05-05 07:08:47.915309504+02:00','2024-09-14 08:55:02.778476991+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2024-09-14 08:57:26.215082073+02:00','2024-09-14 08:57:26.215082073+02:00',NULL,'user008','','',NULL,NULL,'');
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,101 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
INSERT INTO migrations VALUES('202501311657');
INSERT INTO migrations VALUES('202502070949');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,"user_id" integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'c0e73b52c1706fcceea368ae07c19c0e91fbe1f78eff2f7b',1,0,1,0,'2022-02-26 17:02:32.568878371+00:00','2022-02-26 18:11:15.388354971+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'ad293159f9506a02d6de4730e5a2ddb74f9fd4033919ecc5',1,0,1,1,'2022-02-26 17:08:07.828690446+00:00','2022-02-26 18:11:18.890985216+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(3,'66c7e0fbf74010ea2e153d35ffa0f3c48380ef38960d1fd1',1,0,0,1,'2022-02-26 17:11:54.149663776+00:00','2022-02-26 17:16:54.147175388+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(4,'cdbb69c88fabdc2609050c7f99e8ebdea6fcf81a50d802fc',1,0,0,1,'2022-02-26 17:15:34.160746962+00:00','2022-02-26 17:20:34.15935255+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(6,'0a99889a217a2f9cdd20082faadd5c90e72c83a47093a63a',1,0,0,1,'2022-03-04 07:27:17.535172209+00:00','2022-03-04 07:32:17.531871524+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(10,'6e88409e3883c1a47249e428030afd4a46bdaf3adb3b74c1',4,0,0,1,'2022-04-01 20:43:21.757703546+00:00','2022-04-01 20:48:21.756458144+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(13,'9d3c2bde9fcef181a3141dfe59d449bf03f6779dad3580e0',1,0,0,1,'2022-06-26 13:19:48.533865696+00:00','2022-06-26 13:24:48.532164552+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(16,'00b123d52ea8f58379b740fdc5c898b02330ab9b366cb1b4',1,0,0,1,'2023-02-12 06:21:30.15120385+00:00','2023-02-12 06:26:30.140082454+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(17,'c471ce93392c0d3040af0cf6166f4f578c3c66dd180b6e0b',1,0,0,1,'2023-02-12 06:26:55.829311638+00:00','2023-02-12 06:31:55.824701077+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(18,'fe0a438e67687540efcbbbc28c8e6c1b8ac1216f99de33d4',1,0,0,1,'2023-02-12 06:31:13.245185592+00:00','2023-02-12 06:36:13.241695106+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(19,'5a469043f1fa43ff11e54ea242dd882a81aea68f168b9a34',1,0,0,1,'2023-02-12 06:31:13.622545545+00:00','2023-02-12 06:36:13.560890824+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(20,'8b31d9a38282dfe07ffcebdfbd40db6b9e49997c93bed570',1,0,0,1,'2023-02-28 12:45:48.518939706+00:00','2023-02-28 12:50:48.445951259+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(21,'47a4216f2b4e5885d4e53a3de2ffe95521d8a708ca26d31e',1,0,0,1,'2023-02-28 12:45:48.53865321+00:00','2023-02-28 12:50:48.439132728+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(22,'1b7be83871f396e4544c8445acfc8d308dbfe29c7f0197f0',1,0,0,1,'2023-02-28 12:45:48.538806791+00:00','2023-02-28 12:50:48.445073692+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(23,'c9f364adba95c6c46c162eaa3786702805595841c0150927',1,0,0,1,'2023-05-05 08:08:16.73107293+00:00','2023-05-05 08:13:16.722921676+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(24,'a90c87e30fa22ffee39e5ce157dd22c909f2026295e3bce4',1,0,0,1,'2023-08-14 14:36:52.042138928+00:00','2023-08-14 14:41:52.038644473+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(25,'bb059cde5663619a8918bde19b9f8236085725554d9d78c2',1,0,0,1,'2023-08-14 16:15:33.722630834+00:00','2023-08-14 16:20:33.719604033+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(26,'0733b8fc67adc82644c87a95947b24c5d368c633cff92eb4',1,0,0,1,'2023-08-29 06:30:44.934900329+00:00','2023-08-29 06:35:44.931280114+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(27,'567f3a39066fd99c567d14bcc374b25cee0ad71af08b9054',1,0,0,1,'2023-11-03 17:53:45.857200883+00:00','2023-11-03 17:58:45.853742836+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(30,'8aa13c93cbef46d36c8159da51fb41a469ae04f932980890',1,0,0,1,'2024-07-29 12:24:27.140614087+00:00','2024-07-29 12:29:27.136525982+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(31,'9314b171abc433d73b8db297c1c5c65dae0be53d39a71520',1,0,0,1,'2024-08-07 18:35:12.375119763+00:00','2024-08-07 18:40:12.371590392+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(32,'6a8fd483387734664f2a911545150a9bc0d9f12a744fe913',7,0,0,0,'2025-02-23 06:56:50.319087142+00:00','2025-02-23 07:56:50.31726796+00:00','[]');
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
INSERT INTO api_keys VALUES(1,'S2nn85NliD',X'2432622431322457713675666f5379396247466672516155317132374f58734e5033627671436470436c447073757979456f4a4a71626b6a434e6236','2022-12-25 21:35:28.644697962+01:00','2023-03-22 06:22:18.724817647+01:00',NULL);
INSERT INTO api_keys VALUES(2,'1KZkpEyiMH',X'2432622431322435797935525374656e525a4e67735365316837455965376872366e4e6563445a4e45666d72334d5273612e4b5151334f675a302e71','2023-03-22 06:22:18.339101298+01:00','2023-04-13 09:32:24.318715268+02:00',NULL);
INSERT INTO api_keys VALUES(3,'6yBMrqvEDX',X'24326224313224737956314430636d615a6e546531705370346a7a72654566327565367a587a737264694c336c7147644977424f7348794644624e79','2023-04-13 09:32:23.864995051+02:00','2023-07-12 07:32:23.45+00:00',NULL);
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,"hostname" text,"user_id" integer,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`given_name` varchar(63),`forced_tags` text,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:13adef46b653fc9d24415b242714d08a92605cb2d53355a03cda8bae483cc93d','nodekey:aca177c7ceeadf615c5d28bd894ddad5133fe0e99e6c5f2a4af5403daf74aac6','discokey:83f177b585a16eab54768d0284553d62d3f46ef8a21417834039525dfd9ac7dd','desktop-00',1,'authKey',3,'2025-04-04 16:01:46.440493034+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ce6f:3f5b:da2f:8382:f3a1:e2d4:1c47:fe5e]:25604","[ff9b:6bbd:77bc:323d:12e4:22ba:b712:80c]:37729","[1e76:19af:e817:9a33:4f83:366e:b686:6362]:39521"]','2022-02-26 18:11:55.92837512+01:00','2025-04-04 16:01:46.441299466+02:00',NULL,'node001',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(3,'mkey:202076169f1eee6bcbaebd7d5c314341b9aca69fadda7286fe49f45ed81b6de0','nodekey:b02b4522c79164bb4dc5ba6ff8115cc7dac03417a9385fa9b3fe12e4c3d14ccc','discokey:e5b11353b9ee94a90963eb4318514b17ad8304b4b80d4e178b3e3485376f3c88','email-16',7,'authKey',NULL,'2025-04-03 21:00:54.6832508+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b886:a57b:2070:84fd:6618:6c8:3c70:5077]:17679","117.184.57.124:25930"]','2022-03-01 19:26:46.242187887+01:00','2025-04-03 21:00:54.683607994+02:00',NULL,'node003',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:56ad8dcc120738372c03052898bcdaf06a4b7e92adfa4e260f3ab33bbec7d560','nodekey:b197bf018c11a550972b6fe5841e99660bd70eb64faa26f334466181c6a0c23b','discokey:af3613f6dc6ef1559bb6a35ef0c74ebb42b49e75a7a07d6385a9d5e0acacaf17','web-61',1,'authKey',6,'2025-04-03 18:23:56.187297547+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["76.70.66.173:4330","164.82.63.27:24154","[be53:e324:1587:4d86:d24c:8662:cd5c:a4c8]:58105","59.239.218.25:49807","[cfa4:ad2e:1410:3b78:ce03:b437:6749:ff3a]:39835","179.46.219.166:38167","166.111.217.41:13979"]','2022-03-04 08:27:19.383566031+01:00','2025-04-03 18:23:56.1873891+02:00',NULL,'node004',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(5,'mkey:e87e820508bd86c183ebe4ffb80637130b6d7480c3db5b94fbe4be097ca31d6b','nodekey:36d6615362a2367b323e53348e7b300b5d3180954f6c73d619738b6b416f8b29','discokey:31bde1fc825d42faaefc6baeb19205176d325a0c385b3d5c42020fac5828baf7','srv-79',8,'authKey',NULL,'2025-02-23 12:50:07.992065346+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["157.68.216.200:462","[8dc0:10e:95b6:9954:2614:8dcc:6564:e167]:58499","[8e6d:95be:19a9:316a:d37e:bcb6:5e05:d7f0]:36162","[5bb2:705a:7f5c:3c9:db83:956a:1ce:5291]:9510","37.24.123.232:17607","17.23.6.93:59855"]','2022-03-05 13:54:23.660591381+01:00','2025-02-23 12:50:07.99213101+01:00',NULL,'node005',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(6,'mkey:afca3664dd99d4f692e6188b11e356803b3b88af6aea8c64f44c691c5ef0dd75','nodekey:56c0b70b513c1332dc6e96e23f9b31ce5e7d2f67bf2ce913788f6f8f4309a286','discokey:84388aee7f9b67ca6f494710d339cebe2570c109bffd46b866a3ce6bdfab0a7e','desktop-69',1,'authkey',NULL,'2025-04-04 06:54:04.865503636+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["58.226.203.77:32176","110.30.79.130:11845","87.221.84.2:11620"]','2022-03-21 15:52:20.739594362+01:00','2025-04-04 06:54:04.865830042+02:00',NULL,'node006',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(7,'mkey:cf245d2ed1c596c90501a51b0a7bb2bf72a77bd8aaa25be1798ba88ca4840de1','nodekey:b48c4f58b478be290e6f1fbdd74b54487f66e3efd00f1c90a46c413ccec88b3b','discokey:2df61e4dd58f94db5f7e51caacbb30da03e1efa2892c18ea63d00b9a0b59bd09','db-01',4,'authkey',10,'2025-04-04 11:27:17.576257983+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2c84:7686:38e3:1aa5:db0c:29e4:c685:6059]:38764","4.4.79.116:35870","[1daf:274c:55b2:7413:3c1:bd3d:acc5:4eb1]:33732","182.237.82.235:32290"]','2022-04-01 22:43:27.318756043+02:00','2025-04-04 11:27:17.576974245+02:00',NULL,'node007',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(8,'mkey:cedaee7ced43e8b6eab7807f2e0b6a65351950be008d086dda73ca1176dcb4b0','nodekey:97377594f32ffa436df6cb935fe998011700cbd94d0b7b9f1878e796e47595eb','discokey:7abe7a09338db86ecffe306c78b69a84b7a3615922a6dd580f87e25ac5065843','email-41',7,'authkey',NULL,'2025-04-04 09:43:37.714947898+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["79.62.99.173:32988","136.206.88.82:20612","151.147.230.32:10729","[2621:a1d2:a66d:a6cf:3592:dff2:93dc:5b32]:62817","[e1e8:e93f:ab91:4027:e416:9932:8e9:6fcb]:30261"]','2022-04-03 09:38:46.178224968+02:00','2025-04-04 09:43:37.715260959+02:00',NULL,'node008',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(9,'mkey:94d71f734657c61ac8dd2f7d1ed06787361c1b43bdc3a3c9a541890afa676ddb','nodekey:7bb55439c507f6a11d866f44fdea7912cc4ad8791528438b5d598f001971936e','discokey:1b0a846e57e2ebb966bae5507a41991dde493eb17c61161146056f1d4065817c','lt-20',7,'cli',NULL,'2025-04-04 16:02:13.701628939+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[45cc:7c5b:4d26:7aa1:ae7e:d9bb:ea07:456]:65311","48.237.159.121:13531","55.139.180.4:64685","[bae8:1f82:ff78:e8a8:235e:a50e:c131:2e8]:43129","[3486:5bc7:ada8:8da1:9df9:3cc6:d018:ee8b]:65112","43.182.159.11:27315"]','2022-04-09 09:43:07.09027176+02:00','2025-04-04 16:02:13.701896564+02:00',NULL,'node009',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(10,'mkey:4edbeff705459e7e5d0df80d42abce8d3db49137e013cbe38416aa2d0e77e4de','nodekey:149c771cccddad67f62a6cdf8ebc282692d3f8138e6749e3bcb8044209f30ea8','discokey:7773ea1a30faff0ef3d64186b00fc7f0d584c68eea4e3d75ad6dab5cfb54bee4','email-49',1,'authkey',NULL,'2025-03-22 18:28:09.173419272+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["61.59.238.85:46024","221.176.225.4:60304"]','2022-06-26 13:57:07.40762063+02:00','2025-03-22 18:28:09.173773792+01:00',NULL,'node010',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(11,'mkey:0bd4a2eac9b6f9b77ab9ee9ea42b36b74d73e0544a2c482526b2385e8bcb0c34','nodekey:1a5c66957c54314f72ea26fed12e48b9c4149c1f640300e39d6190226bc1aaf8','discokey:9f151fb1569ef5341c8f54eec62b82cb7e5f21540ebe9271ae6449a31250123a','laptop-22',1,'authkey',13,'2025-04-03 22:06:46.872430113+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["55.247.173.145:28477","197.123.99.18:53038","102.60.187.246:41096","155.239.169.182:41163","[c908:b81c:b4c8:38d3:e311:b3f6:3067:227c]:11541"]','2022-06-26 15:19:50.566498735+02:00','2025-04-03 22:06:46.873132509+02:00',NULL,'node011',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(14,'mkey:c7d3e8e40cafce614b65f150e345fefab60dd5b8108bc47e5159e8d3464496f8','nodekey:06d9c1b8455e39baee27729233638fd793e38376a0caafd76cfb3f1fe929b331','discokey:93ec10f68b6950a9a842c6e2cf186d86334705cf174d50985a3f4c8561246e9f','lt-29',1,'authkey',NULL,'2025-03-30 11:38:07.287941738+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["34.25.194.159:63765","147.22.45.153:11543","30.125.129.134:36303"]','2022-09-26 16:07:54.206927686+02:00','2025-03-30 11:38:07.288217849+02:00',NULL,'node014',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(23,'mkey:2cc72bee6bf01caeb26a1d00ad6653d7a2f06252afe9f7e9cbb4e1701d3d7da4','nodekey:7edccf09f05dd46626c2981cc69c74c593d314aced7de30423142ba090521d72','discokey:98629534198740b432a58b75cee1c37bd3bdc0d85e85d7fe514af16881fc420b','srv-12',1,'authkey',23,'2025-04-03 21:18:57.701368882+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ec95:2e1e:2d50:967c:c90f:9d1e:4a3e:cac6]:63487","[57e5:faa8:aee0:9b66:a0e:6a4f:f715:631]:23151","209.114.161.143:52706","[6d6f:fcc8:f538:9546:a467:a161:1e3f:ad80]:45335","[d8b4:ed81:6b2f:8517:c171:871:7319:6abb]:54186","[dcb5:9eee:2075:acba:1a31:1669:21dd:744b]:48312"]','2023-05-05 10:08:17.301597525+02:00','2025-04-03 21:18:57.701435228+02:00',NULL,'node023','[]','100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(24,'mkey:cdd2725a2eec500da5a278444f3f3f82351e3df4b38c73781a8c04bdcdf469f3','nodekey:badffb3b36094dcff5902db9b857c436f2aa91b3a0fc2fc8f0b7e0a6cfce842d','discokey:68d8447103b317e2a41dccf0dc60017b8554f55639de9b13ffc9f07366e0dffa','desktop-58',1,'authkey',25,'2025-01-13 15:02:48.676721758+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["62.8.65.228:34575","58.211.127.215:33647","47.22.77.26:36499","185.25.84.152:44786","[c7d0:cf6f:bb45:6922:7fd7:adb7:59f5:499e]:60522","65.200.68.231:16530","11.209.67.55:8308"]','2023-08-14 18:15:34.292188686+02:00','2025-01-13 15:02:48.67679754+01:00',NULL,'node024','[]','100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(25,'mkey:54219375ce0ab01cd59b56ad984df668ae7cbe49b7b91e44877ae0d7012d6106','nodekey:2b0c163bc497f6214b25d6a333a37d273c260630dcc91782897f19a579f92a5b','discokey:4cf24a025241ad9a69c20d40513dfee5626f934d738e18f4a64fd9a1ace2cb24','srv-15',1,'authkey',26,'2025-03-31 23:15:14.255680838+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[60da:30ec:55bd:5ab3:3fe7:5492:1fc8:92f3]:36566","105.238.97.70:40193","[8c84:2d7e:5e1a:2f51:8754:aa54:b421:a19f]:60672","[5101:751a:5e00:cf46:8b50:8ba9:3c8e:4c7c]:33862"]','2023-08-29 08:30:45.518580154+02:00','2025-03-31 23:15:14.25655063+02:00',NULL,'node025','[]','100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(26,'mkey:96e8e0e986089fe5d0f5418f7ccb0a701401def77b8c5e1c337e7c5b865aa20c','nodekey:0e01df602ea65f549245772540b04373a8f2ab64a781251598226e99a6fc341f','discokey:444d74201443318337b9c8118b6d62ab087049cd1258b1b670dd3d8b8b883bd0','lt-82',1,'authkey',27,'2025-04-04 15:59:56.081157956+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["12.54.208.97:59171","[13a0:b8ff:bebb:d48:e16e:869d:b542:531b]:17201","44.157.88.255:43418","8.250.82.20:52374","180.217.175.155:13947","[76d7:a0ac:7cf2:9237:df96:42d2:4086:5b93]:41885"]','2023-11-03 18:53:48.108033118+01:00','2025-04-04 15:59:56.081857808+02:00',NULL,'node026','[]','100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(29,'mkey:ef670d35dba3168a251ce7230dfd073594f7e8454c55d2eea392b11b7eb2c58d','nodekey:c4fe657c9168dd2d798452d1c411faa57d7f2866808cf7fee5e5251eba58cfed','discokey:f47bc0695fd2db95519a8fc51ecc628c4b869dea953b34b88095c765ac4c8b2e','srv-21',1,'authkey',NULL,'2025-04-04 10:13:54.951364016+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c018:a17d:2177:f7b8:482d:b68b:9b7a:c3f4]:52482","[99d:8ae6:556e:9e4a:b721:e12f:cec4:d571]:25093","[688f:e843:1471:41c0:868f:f77c:e787:8d13]:24194","[ae51:6570:f6b6:7d2b:1803:50f1:6e3a:faa4]:6218","62.26.91.22:45257"]','2024-06-02 09:46:39.307697473+02:00','2025-04-04 10:13:54.951675714+02:00',NULL,'node029','[]','100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(30,'mkey:a50ccd27d81ae5fa4e8cf617b9a923d18b818d5903d1aa008044cf4a2145f5b4','nodekey:eb0607968c785075216b01d5e11a67124f7ab9bd8d11498aa29cd68ca7355d8b','discokey:beffe8994e5a4baf7553267e7df7da7460552b3ec1b8b0b2d12f467a07810dea','db-89',1,'authkey',30,'2025-03-31 23:15:17.070924864+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c7b3:52c3:f5c3:87c:f5ed:213:85f4:44c5]:18304","49.111.96.135:35528","[abc1:b7cd:f18:6ed2:4b5a:9dce:3f08:8c17]:333","206.118.184.48:48132"]','2024-07-29 14:24:27.684620193+02:00','2025-03-31 23:15:17.071471786+02:00',NULL,'node030','[]','100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(31,'mkey:e76b247ac8acd857970abf462c8c954f670d78fe190ca537ef68983de00806e0','nodekey:bf2c0b7e9271cb7addf94f7ee4b5c2bfab9f279fb124c76f0d1fed4b4125e422','discokey:af105f27a8a9c750ba54da2defc49dbf001891b96e6a1bb1b96ee39056e1ff5f','laptop-03',1,'authkey',31,'2025-04-04 15:57:02.028544413+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["187.133.234.227:17532","143.220.168.161:8383","[3981:7f70:a471:4993:c3a4:3173:1b62:544e]:43648","200.130.212.85:63469"]','2024-08-07 20:35:12.944541318+02:00','2025-04-04 15:57:02.03016371+02:00',NULL,'node031','[]','100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(32,'mkey:e66714b599a0fcd24e7e87019cfbfc3b9d6d1c9c3b0bb70912d6e7bc7398f8fa','nodekey:0dba1091e5ff8fbf639f490eabaa0fa5188cc076cb8922eb6889b023fc4384bc','discokey:a05e361212ffc667037a9997a178a9d0a50453bded8dfe3772fed2b711092c58','db-20',1,'cli',NULL,'2025-04-04 15:55:20.925507947+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c47f:35c9:41fe:6f5:a40d:3e8b:6679:411e]:12963","19.205.218.60:63516","116.228.193.194:44296","[ee98:8de3:1f5b:731c:751b:ba46:a4a7:8760]:23245","[6eb3:8c34:e6c9:4c6a:25c9:89ca:c165:354e]:65112","[7003:63bb:6429:d463:96a6:990:2bdc:217d]:4300","[d820:584e:2b46:6915:6420:3056:f76:9e33]:48885","25.167.184.15:1967","82.253.97.208:8684"]','2024-10-26 07:18:04.947942936+02:00','2025-04-04 15:55:20.925847076+02:00',NULL,'node032',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
INSERT INTO nodes VALUES(33,'mkey:e885828fffb844493b9ac09514500e4832d588586274d7ab134def4758aec8b4','nodekey:69ecbf0eda9c36c6a5a3a5bbdaebcbe87843112ccb5004acdaa3273557cca09e','discokey:3076854f388bce0a53ce84c6a01f0ce677f641bc2429b10206c6c2de7ac75a7f','laptop-99',7,'cli',NULL,'2025-04-03 22:00:57.883174604+02:00',NULL,'{"fake":"data"}','["104.248.144.146:61623","[a05:c6f9:3d44:8c37:71b:94bc:c915:47aa]:9656","15.105.112.6:17162","67.6.72.132:32571","[524:9a03:6a60:cc60:d594:b98e:e32f:d883]:8390","86.91.139.227:63567","206.126.50.249:22311","[a1f9:9745:a2ed:1bb7:9405:91f9:1c52:8c28]:14465","155.71.33.111:62332","[fd76:427:7ce5:c2b2:183a:1281:d6bb:8633]:47777","[2133:a7d0:99d5:fcce:44dd:8de3:dffe:61f5]:30756"]','2025-02-23 07:59:15.141530181+01:00','2025-04-03 22:00:57.883491572+02:00',NULL,'node033',NULL,'100.64.0.11','fd7a:115c:a1e0::b');
INSERT INTO nodes VALUES(34,'mkey:bc9632988599109f50c950f4069c6a38f9e04d22f81f5bbd4edfdf271ea3b772','nodekey:a9be3965ba99bf7ef5ca7eee6f1ea50043fab7e40a2da3b8ea45e5c5c859d0e7','discokey:f9c9d5de5033f54236970fa4c12fe4f475be4c2a00f57418f396057142aea9f3','srv-85',9,'cli',NULL,'2025-04-04 00:05:39.390959034+02:00',NULL,'{"fake":"data"}','["[1b72:b6ce:5ad1:81e3:bc01:6516:f696:e19e]:15160","[fc:3ed4:df18:5664:71f1:6c7b:652a:7fcd]:27806","[417a:9260:6c16:5a4c:911d:eaec:7e3b:cf47]:58735","190.241.43.139:19489","[9b36:5bd4:a077:9b75:65ac:ccd0:170f:69b9]:41358"]','2025-03-09 11:42:30.627548688+01:00','2025-04-04 00:05:39.391044635+02:00',NULL,'node034',NULL,'100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(35,'mkey:0a58d0ca3bac65adeddc621d1355a3801b088c393a93bc83a55c198e7ef1858e','nodekey:f25a54c9ec984566a1a245aee7f85f92ffccc090be0d4d9fdab081e23a5bd2c5','discokey:2d95fd862eb2087d1345f2825e8b3013ca9037cc44f595fc1374850ecce93c9f','desktop-75',9,'cli',NULL,'2025-04-04 12:24:50.896091765+02:00',NULL,'{"fake":"data"}','["115.214.18.115:26087","209.46.195.111:48055","[2030:c7ae:bde5:536c:7748:3ac:9eea:2468]:45768","[1ec6:10e:5a64:942e:cb28:7d65:97cc:8e89]:14623"]','2025-03-09 12:06:19.756893731+01:00','2025-04-04 12:24:50.896434652+02:00',NULL,'node035',NULL,'100.64.0.22','fd7a:115c:a1e0::16');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(7,'2023-01-15 14:41:49.445054371+01:00','2023-01-29 10:12:11.959527554+01:00',NULL,14,'0.0.0.0/0',1,1,0);
INSERT INTO routes VALUES(8,'2023-01-15 14:41:49.452617331+01:00','2023-01-29 10:12:13.154311101+01:00',NULL,14,'::/0',1,1,0);
INSERT INTO routes VALUES(9,'2024-05-05 07:16:02.944084847+02:00','2024-05-05 13:25:02.977065366+02:00',NULL,3,'172.30.190.136/30',1,1,1);
INSERT INTO routes VALUES(10,'2024-05-05 07:16:02.95709561+02:00','2024-05-05 13:25:04.513930181+02:00',NULL,3,'10.241.118.90/31',1,1,1);
INSERT INTO routes VALUES(17,'2024-08-08 20:44:22.76306591+02:00','2024-12-21 12:10:07.339044415+01:00',NULL,31,'192.168.0.0/17',1,1,1);
INSERT INTO routes VALUES(18,'2024-08-08 20:47:33.469970726+02:00','2024-12-21 12:10:07.442783446+01:00',NULL,31,'192.168.192.0/19',1,1,1);
INSERT INTO routes VALUES(21,'2024-08-08 20:54:05.146666051+02:00','2024-12-21 12:10:07.538738125+01:00',NULL,31,'172.29.254.8/29',1,1,1);
INSERT INTO routes VALUES(23,'2024-08-08 20:54:05.162212208+02:00','2024-12-21 12:10:07.644714175+01:00',NULL,31,'172.18.8.0/22',1,1,1);
INSERT INTO routes VALUES(25,'2024-08-08 20:54:05.179419681+02:00','2024-12-21 12:10:07.753927883+01:00',NULL,31,'10.169.34.250/31',1,1,1);
INSERT INTO routes VALUES(26,'2024-08-08 20:54:05.186132539+02:00','2024-12-21 12:10:07.871905187+01:00',NULL,31,'172.24.0.0/16',1,1,1);
INSERT INTO routes VALUES(28,'2024-08-08 20:54:05.202442818+02:00','2024-12-21 12:10:07.972132539+01:00',NULL,31,'10.149.80.0/20',1,1,1);
INSERT INTO routes VALUES(31,'2024-08-08 20:54:05.246698925+02:00','2024-12-21 12:10:08.150358433+01:00',NULL,31,'10.232.0.0/13',1,1,1);
INSERT INTO routes VALUES(32,'2024-08-08 20:54:05.256984635+02:00','2024-12-21 12:10:08.349521909+01:00',NULL,31,'172.23.0.0/21',1,1,1);
INSERT INTO routes VALUES(37,'2024-08-08 20:54:05.300971626+02:00','2024-12-21 12:10:08.553265285+01:00',NULL,31,'172.17.124.137/32',1,1,1);
INSERT INTO routes VALUES(43,'2024-08-08 20:54:05.383430747+02:00','2024-12-21 12:10:08.66112581+01:00',NULL,31,'10.91.8.0/21',1,1,1);
INSERT INTO routes VALUES(47,'2024-08-08 20:54:05.443181025+02:00','2024-12-21 12:10:08.826993878+01:00',NULL,31,'192.168.222.64/27',1,1,1);
INSERT INTO routes VALUES(48,'2024-08-08 20:54:05.449778605+02:00','2024-12-21 12:10:09.237117302+01:00',NULL,31,'10.16.0.0/12',1,1,1);
INSERT INTO routes VALUES(49,'2024-09-03 06:43:34.875117755+02:00','2024-12-21 12:10:09.342259317+01:00',NULL,31,'192.168.191.192/28',1,1,1);
INSERT INTO routes VALUES(50,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'10.225.156.72/29',1,1,1);
INSERT INTO routes VALUES(51,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'172.28.71.145/32',1,1,1);
INSERT INTO routes VALUES(52,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'10.104.0.0/13',1,1,1);
INSERT INTO routes VALUES(53,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'172.16.0.0/13',1,1,1);
INSERT INTO routes VALUES(54,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'10.60.104.0/24',1,1,1);
INSERT INTO routes VALUES(55,'2025-02-23 06:43:34.875117755+02:00','2025-02-23 06:43:34.875117755+02:00',NULL,33,'10.89.96.0/19',1,1,1);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2022-02-26 18:00:56.104436744+01:00','2024-09-14 08:51:13.31135114+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2022-04-01 22:30:02.657653341+02:00','2024-09-14 08:55:27.877614108+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2024-05-05 07:08:47.915309504+02:00','2024-09-14 08:55:02.778476991+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2024-09-14 08:57:26.215082073+02:00','2024-09-14 08:57:26.215082073+02:00',NULL,'user008','','',NULL,NULL,'');
INSERT INTO users VALUES(9,'2025-03-09 11:22:20.790371056+01:00','2025-03-09 11:22:20.790371056+01:00',NULL,'user009','','',NULL,'','');
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,81 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
INSERT INTO migrations VALUES('202501311657');
INSERT INTO migrations VALUES('202502070949');
INSERT INTO migrations VALUES('202502131714');
INSERT INTO migrations VALUES('202502171819');
INSERT INTO migrations VALUES('202505091439');
INSERT INTO migrations VALUES('202505141324');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,"user_id" integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'c0e73b52c1706fcceea368ae07c19c0e91fbe1f78eff2f7b',1,0,1,0,'2022-02-26 17:02:32.568878371+00:00','2022-02-26 18:11:15.388354971+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'ad293159f9506a02d6de4730e5a2ddb74f9fd4033919ecc5',1,0,1,1,'2022-02-26 17:08:07.828690446+00:00','2022-02-26 18:11:18.890985216+01:00',NULL);
INSERT INTO pre_auth_keys VALUES(3,'66c7e0fbf74010ea2e153d35ffa0f3c48380ef38960d1fd1',1,0,0,1,'2022-02-26 17:11:54.149663776+00:00','2022-02-26 17:16:54.147175388+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(4,'cdbb69c88fabdc2609050c7f99e8ebdea6fcf81a50d802fc',1,0,0,1,'2022-02-26 17:15:34.160746962+00:00','2022-02-26 17:20:34.15935255+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(6,'0a99889a217a2f9cdd20082faadd5c90e72c83a47093a63a',1,0,0,1,'2022-03-04 07:27:17.535172209+00:00','2022-03-04 07:32:17.531871524+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(10,'6e88409e3883c1a47249e428030afd4a46bdaf3adb3b74c1',4,0,0,1,'2022-04-01 20:43:21.757703546+00:00','2022-04-01 20:48:21.756458144+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(13,'9d3c2bde9fcef181a3141dfe59d449bf03f6779dad3580e0',1,0,0,1,'2022-06-26 13:19:48.533865696+00:00','2022-06-26 13:24:48.532164552+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(16,'00b123d52ea8f58379b740fdc5c898b02330ab9b366cb1b4',1,0,0,1,'2023-02-12 06:21:30.15120385+00:00','2023-02-12 06:26:30.140082454+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(17,'c471ce93392c0d3040af0cf6166f4f578c3c66dd180b6e0b',1,0,0,1,'2023-02-12 06:26:55.829311638+00:00','2023-02-12 06:31:55.824701077+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(18,'fe0a438e67687540efcbbbc28c8e6c1b8ac1216f99de33d4',1,0,0,1,'2023-02-12 06:31:13.245185592+00:00','2023-02-12 06:36:13.241695106+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(19,'5a469043f1fa43ff11e54ea242dd882a81aea68f168b9a34',1,0,0,1,'2023-02-12 06:31:13.622545545+00:00','2023-02-12 06:36:13.560890824+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(20,'8b31d9a38282dfe07ffcebdfbd40db6b9e49997c93bed570',1,0,0,1,'2023-02-28 12:45:48.518939706+00:00','2023-02-28 12:50:48.445951259+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(21,'47a4216f2b4e5885d4e53a3de2ffe95521d8a708ca26d31e',1,0,0,1,'2023-02-28 12:45:48.53865321+00:00','2023-02-28 12:50:48.439132728+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(22,'1b7be83871f396e4544c8445acfc8d308dbfe29c7f0197f0',1,0,0,1,'2023-02-28 12:45:48.538806791+00:00','2023-02-28 12:50:48.445073692+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(23,'c9f364adba95c6c46c162eaa3786702805595841c0150927',1,0,0,1,'2023-05-05 08:08:16.73107293+00:00','2023-05-05 08:13:16.722921676+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(24,'a90c87e30fa22ffee39e5ce157dd22c909f2026295e3bce4',1,0,0,1,'2023-08-14 14:36:52.042138928+00:00','2023-08-14 14:41:52.038644473+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(25,'bb059cde5663619a8918bde19b9f8236085725554d9d78c2',1,0,0,1,'2023-08-14 16:15:33.722630834+00:00','2023-08-14 16:20:33.719604033+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(26,'0733b8fc67adc82644c87a95947b24c5d368c633cff92eb4',1,0,0,1,'2023-08-29 06:30:44.934900329+00:00','2023-08-29 06:35:44.931280114+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(27,'567f3a39066fd99c567d14bcc374b25cee0ad71af08b9054',1,0,0,1,'2023-11-03 17:53:45.857200883+00:00','2023-11-03 17:58:45.853742836+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(30,'8aa13c93cbef46d36c8159da51fb41a469ae04f932980890',1,0,0,1,'2024-07-29 12:24:27.140614087+00:00','2024-07-29 12:29:27.136525982+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(31,'9314b171abc433d73b8db297c1c5c65dae0be53d39a71520',1,0,0,1,'2024-08-07 18:35:12.375119763+00:00','2024-08-07 18:40:12.371590392+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(32,'6a8fd483387734664f2a911545150a9bc0d9f12a744fe913',7,0,0,0,'2025-02-23 06:56:50.319087142+00:00','2025-02-23 07:56:50.31726796+00:00','[]');
INSERT INTO pre_auth_keys VALUES(33,'f9e6f7c415c3dada62a7ddaaa84089c1ae5a79799135ddb7',1,0,0,0,'2025-05-20 12:42:38.359223624+00:00','2025-05-20 12:47:38.357400723+00:00','[]');
INSERT INTO pre_auth_keys VALUES(34,'14bbc5eec5d659e311d1317b5b6fa100989d362e9c9391ca',1,0,0,1,'2025-05-20 12:45:13.242066722+00:00','2025-05-20 12:50:13.240121832+00:00','[]');
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
INSERT INTO api_keys VALUES(1,'S2nn85NliD',X'24326224313224454b717078586e6e7a35566461394c6a744b435a454f6c3539636351513630693035355052625772664b2f776f37467a586d592f57','2022-12-25 21:35:28.644697962+01:00','2023-03-22 06:22:18.724817647+01:00',NULL);
INSERT INTO api_keys VALUES(2,'1KZkpEyiMH',X'243262243132244854744d444b68744567707a2f4b4c4468316658742e6679415a445651546e3270787032334243315547366f4a2f3758326f30422e','2023-03-22 06:22:18.339101298+01:00','2023-04-13 09:32:24.318715268+02:00',NULL);
INSERT INTO api_keys VALUES(3,'6yBMrqvEDX',X'24326224313224714d6e6b52514a773661742f546f69356b45795a744f5077726c76393467713741442f7a344d726e59457032542e5a797162345043','2023-04-13 09:32:23.864995051+02:00','2023-07-12 07:32:23.45+00:00',NULL);
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2022-02-26 18:00:56.104436744+01:00','2025-05-14 18:46:33.171927603+02:00',NULL,'user001','','',NULL,'','');
INSERT INTO users VALUES(4,'2022-04-01 22:30:02.657653341+02:00','2025-05-14 18:46:33.172257847+02:00',NULL,'user004','','',NULL,'','');
INSERT INTO users VALUES(7,'2024-05-05 07:08:47.915309504+02:00','2025-05-14 18:46:33.17253525+02:00',NULL,'user007','','',NULL,'','');
INSERT INTO users VALUES(8,'2024-09-14 08:57:26.215082073+02:00','2025-05-14 18:46:33.172790221+02:00',NULL,'user008','','',NULL,'','');
INSERT INTO users VALUES(9,'2025-03-09 11:22:20.790371056+01:00','2025-05-14 18:46:33.173008092+02:00',NULL,'user009','','',NULL,'','');
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,"hostname" text,"user_id" integer,`register_method` text,`auth_key_id` integer,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`given_name` varchar(63),`forced_tags` text,`ipv4` text,`ipv6` text,`approved_routes` text, `last_seen` datetime,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:474325234da7eb017709065b11310982f2d27f555982cd1d244eed609b8915f8','nodekey:39346ddf789f4b8e0b75640ddb6c68345d9558a05da328ff7aba3f32e0d532ac','discokey:a3339402132a7e9270202a62006a6bf2c7bb878ba42b3d32dd041f48c4106756','laptop-97',1,'authKey',3,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["184.61.212.248:29690","[32a5:51:afc3:d256:5b83:97cd:bb34:13c1]:63964","58.104.128.216:9783","[2893:715c:4057:d56b:ec9b:b0b1:f551:dda2]:53876","124.44.86.49:25138"]','2022-02-26 18:11:55.92837512+01:00','2025-06-28 12:31:23.433667354+02:00',NULL,'node001',NULL,'100.64.0.1','fd7a:115c:a1e0::1',NULL,'2025-06-28 12:31:23.433017377+02:00');
INSERT INTO nodes VALUES(3,'mkey:5b5f43f22e7a71c5fd565e80430c0e6dac71a5cdb6ba74b1bb54baa0c9ffdc03','nodekey:db60b0b5f7fad865e516f069068d809f23b89b787824398150083f8a556841f9','discokey:456266be182c7d6e5da46744ed79fd2478a8680682b9e4994f88a58fb8977b64','web-42',7,'authKey',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["59.239.218.25:49807","[cfa4:ad2e:1410:3b78:ce03:b437:6749:ff3a]:39835"]','2022-03-01 19:26:46.242187887+01:00','2025-05-05 10:20:11.253224494+02:00',NULL,'node003',NULL,'100.64.0.3','fd7a:115c:a1e0::3','["172.19.40.0/21","172.28.0.0/15"]',NULL);
INSERT INTO nodes VALUES(4,'mkey:e87e820508bd86c183ebe4ffb80637130b6d7480c3db5b94fbe4be097ca31d6b','nodekey:36d6615362a2367b323e53348e7b300b5d3180954f6c73d619738b6b416f8b29','discokey:31bde1fc825d42faaefc6baeb19205176d325a0c385b3d5c42020fac5828baf7','srv-79',1,'authKey',6,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["157.68.216.200:462","[8dc0:10e:95b6:9954:2614:8dcc:6564:e167]:58499","[8e6d:95be:19a9:316a:d37e:bcb6:5e05:d7f0]:36162","[5bb2:705a:7f5c:3c9:db83:956a:1ce:5291]:9510","37.24.123.232:17607","17.23.6.93:59855","[43da:7790:faf4:7da1:8df9:7bd2:7edd:86cb]:32916"]','2022-03-04 08:27:19.383566031+01:00','2025-06-28 09:41:55.764039354+02:00',NULL,'node004',NULL,'100.64.0.2','fd7a:115c:a1e0::2',NULL,'2025-06-28 09:41:55.763896815+02:00');
INSERT INTO nodes VALUES(5,'mkey:1390cccca2383b00ee50269c3f66a3282d6ac74d510da12d0ff6d06dfa585d6d','nodekey:10bc9579231e8407d16e1145240057b151187c0f713751369fee9d784a0396f1','discokey:bbaae038137272e4ffe36cfa61b5754de21be50116ac18ba68993ac3fef0bc86','desktop-07',8,'authKey',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["7.15.39.193:11845","87.221.84.2:11620","71.36.112.35:10587","68.226.133.92:29098","11.142.49.170:22792","32.34.123.165:35870"]','2022-03-05 13:54:23.660591381+01:00','2025-02-23 12:50:07.99213101+01:00',NULL,'node005',NULL,'100.64.0.4','fd7a:115c:a1e0::4',NULL,NULL);
INSERT INTO nodes VALUES(6,'mkey:bbc0e9d7c02e59a66359201518e7c194d0767a35c8ebf01160df46c99e2a4fb4','nodekey:c03fe802222407ea830f88ac6bffc3b151402e6a9bf51329f252a6235c3e9edb','discokey:f8a7aa10dc7ca161f31103ea4f240f04e4f1eabaecd4cef7ca7e8c06cdf8f7f8','desktop-29',1,'authkey',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["146.236.198.32:16212","[a38c:efed:7c57:2d0f:4348:fbba:e351:9d7]:10415","[8c73:5e49:de7d:6494:c1e:7525:20c1:4e51]:31219"]','2022-03-21 15:52:20.739594362+01:00','2025-06-27 06:44:54.03512388+02:00',NULL,'node006',NULL,'100.64.0.5','fd7a:115c:a1e0::5',NULL,'2025-06-27 06:44:53.041866553+02:00');
INSERT INTO nodes VALUES(7,'mkey:273845dc25d0db5a03a825317314a99e4ba47c754b48e864032dd9dbdd780069','nodekey:db16750752e4236f2db3adb3dc87b779a99dbca4454d680e80b1db68485de119','discokey:c9739f2584f4f04352e167e14b9b2a7f849a7e174cf7ed057988de85284ff98b','srv-19',4,'authkey',10,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2621:a1d2:a66d:a6cf:3592:dff2:93dc:5b32]:62817","[e1e8:e93f:ab91:4027:e416:9932:8e9:6fcb]:30261","215.10.187.249:19488","[bfe7:ebf6:e338:79a6:dba:4051:a7df:10]:31519","128.57.253.0:39500","25.178.136.37:18298"]','2022-04-01 22:43:27.318756043+02:00','2025-06-28 03:32:29.065962525+02:00',NULL,'node007',NULL,'100.64.0.6','fd7a:115c:a1e0::6',NULL,'2025-06-28 03:32:29.065314923+02:00');
INSERT INTO nodes VALUES(8,'mkey:de3d486a2491db953838ba8645073e4bd830d5a73d3cc4d2de21f5c89440acaa','nodekey:e90305687f5829ee9dd005d56dda139f7821635a8cc78f9632ee95c2e9a77a1f','discokey:a6aef9c5cc375914e419eb3d1d20d0a7c22829589dd831ae3fb389b6928d84de','desktop-58',7,'authkey',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["[3486:5bc7:ada8:8da1:9df9:3cc6:d018:ee8b]:65112","43.182.159.11:27315","[12a4:b567:a06e:b675:a878:2f42:e5e1:429f]:60924","[171f:b843:ff2e:b9f0:9890:1aac:42e5:c2ab]:47842","174.7.154.174:51720","27.60.143.54:24292","[75c8:63d5:d781:ffb6:6d87:822:dc90:8e21]:58598","219.62.61.186:43774"]','2022-04-03 09:38:46.178224968+02:00','2025-06-28 08:41:48.401988354+02:00',NULL,'node008',NULL,'100.64.0.7','fd7a:115c:a1e0::7',NULL,'2025-06-28 08:41:48.401718826+02:00');
INSERT INTO nodes VALUES(9,'mkey:b611d5e2fc1ab1d3170a28fc8b95533488d8b60037899c23b3a92c90df0a4184','nodekey:365a5cd793fb1bebd177654e622112f431f472d89d3f4c410c8dfad67da69b67','discokey:d5963ebed732aa08dbef53f02a882074fec07b6dd734ea960879ff3a277d2b22','web-21',7,'cli',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["83.54.151.81:48561","[b513:b737:33f3:dd2a:df4:a90f:6797:6b1e]:7773","166.251.234.109:41163","[c908:b81c:b4c8:38d3:e311:b3f6:3067:227c]:11541","[f41f:b9e9:9205:210a:4ff9:ab34:57fd:3148]:21852","[3d49:412:9781:b399:f9a5:587e:bd2e:a579]:3775","[867:a7e:7e04:bfbb:6286:f95f:1abd:9b5a]:63765","147.22.45.153:11543"]','2022-04-09 09:43:07.09027176+02:00','2025-06-27 18:34:44.020047301+02:00',NULL,'node009',NULL,'100.64.0.8','fd7a:115c:a1e0::8',NULL,'2025-06-27 18:34:44.019955758+02:00');
INSERT INTO nodes VALUES(10,'mkey:6741c4c82ad84e841fcfbf08ef6f04eff5d2f9b0ba84d5ee461fb33b2ca5cd29','nodekey:e25cf4bd0f6a2b4b124de9ceb3ee35b9dd7c5fea804de904d3654d662f4d17ee','discokey:ac9ede38c3ba09f2a29106a1e7d51fffb8254a291094f959417f172d3d59714f','web-40',1,'authkey',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["147.92.114.14:38013","223.127.253.143:5148"]','2022-06-26 13:57:07.40762063+02:00','2025-06-27 14:19:25.551023302+02:00',NULL,'node010',NULL,'100.64.0.9','fd7a:115c:a1e0::9',NULL,'2025-06-27 14:19:25.550738565+02:00');
INSERT INTO nodes VALUES(11,'mkey:7c84b8eea26e6d6a14e08ee933806ca4fb854bd0a168ee576efc58a69523ea0f','nodekey:00cb375ac5580c5718d7879942eba4378d73bf4026ae583a72c6d72f9a2f5958','discokey:69afa6724b1c46f7947a232489f51bd458db562c1144d41ba1b6075395e62529','db-61',1,'authkey',13,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9599:6347:eeed:7573:eb34:676:69d5:954]:17338","87.151.18.221:6598","110.245.60.227:50528","33.141.84.140:39332","141.199.13.112:28607"]','2022-06-26 15:19:50.566498735+02:00','2025-06-27 22:13:31.905300414+02:00',NULL,'node011',NULL,'100.64.0.10','fd7a:115c:a1e0::a',NULL,'2025-06-27 22:13:31.904659225+02:00');
INSERT INTO nodes VALUES(14,'mkey:4924fd3356d306df5387fd14994f605fefb34228482555a798ac35fa7a62c5f0','nodekey:541fea598d1b043201c43a983820265ec347c42c2716733737ff7c2e7be9398e','discokey:d6cccc631dc105d670b2533c3de0bd6f22eb54cc0a6ccea85d891d5ff2b2c81e','desktop-54',1,'authkey',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["4.222.6.136:38260","[b46f:c4d4:f889:3155:aafc:d69a:48ca:a4c1]:44786","[c7d0:cf6f:bb45:6922:7fd7:adb7:59f5:499e]:60522"]','2022-09-26 16:07:54.206927686+02:00','2025-06-27 06:44:53.567922585+02:00',NULL,'node014',NULL,'100.64.0.13','fd7a:115c:a1e0::d','["10.0.0.0/12","172.20.0.0/14"]','2025-06-27 06:44:53.042608133+02:00');
INSERT INTO nodes VALUES(23,'mkey:54219375ce0ab01cd59b56ad984df668ae7cbe49b7b91e44877ae0d7012d6106','nodekey:2b0c163bc497f6214b25d6a333a37d273c260630dcc91782897f19a579f92a5b','discokey:4cf24a025241ad9a69c20d40513dfee5626f934d738e18f4a64fd9a1ace2cb24','srv-15',1,'authkey',23,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["[60da:30ec:55bd:5ab3:3fe7:5492:1fc8:92f3]:36566","105.238.97.70:40193","[8c84:2d7e:5e1a:2f51:8754:aa54:b421:a19f]:60672","[5101:751a:5e00:cf46:8b50:8ba9:3c8e:4c7c]:33862","[b9fe:3630:1807:826:a4a6:e5d2:532c:bdc8]:43617","[25b5:5b72:2ecc:193c:b61e:329:81c6:5af6]:39854"]','2023-05-05 10:08:17.301597525+02:00','2025-04-03 21:18:57.701435228+02:00',NULL,'node023','[]','100.64.0.14','fd7a:115c:a1e0::e',NULL,NULL);
INSERT INTO nodes VALUES(24,'mkey:1109db54ebd9d9434856deacc7bd48e4b6398bc20bee5848a03961570d0612c3','nodekey:091f831b4c85c72746639611f5048ea7c522cd65a8e8babb00b8d67914a1db0c','discokey:29c076af146813259e9dd97c1771cf6d47e6e4968d92b521fcc9305790025084','laptop-94',1,'authkey',25,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["219.227.129.151:59871","44.14.163.233:8010","[dc07:21d7:4b8b:9784:c4c8:bd7b:122a:a5f6]:19866"]','2023-08-14 18:15:34.292188686+02:00','2025-05-13 13:12:57.458459972+02:00',NULL,'node024','[]','100.64.0.15','fd7a:115c:a1e0::f',NULL,'2025-05-13 13:12:57.458382646+02:00');
INSERT INTO nodes VALUES(25,'mkey:8d6fa35951ea76da6a6d85bb63eebf72dbf8e803aecb33a7cc8fada2206ba28c','nodekey:1606dda0995e7b12da0367027e8e1af41c2bc9a086151de09ada9ac833540022','discokey:5d66a541c0458f9178ed892cc57435f8e456722ab5c5b387887c7b3dbffde867','email-53',1,'authkey',26,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["210.72.228.199:14674","101.172.44.176:5878","[c018:a17d:2177:f7b8:482d:b68b:9b7a:c3f4]:52482","[99d:8ae6:556e:9e4a:b721:e12f:cec4:d571]:25093"]','2023-08-29 08:30:45.518580154+02:00','2025-06-27 06:44:54.325931948+02:00',NULL,'node025','[]','100.64.0.16','fd7a:115c:a1e0::10',NULL,'2025-06-27 06:44:53.144614504+02:00');
INSERT INTO nodes VALUES(26,'mkey:94b81dd1a9a0e1d42764099b075c4efa024bd0fbc0a9fc0c3cde7025c4d5a9a5','nodekey:b357796714da554353fc1db9d93898f6767d1f90908c3010c1743f15459d008f','discokey:c03304b111c7a01896bf3a8726a618d33981f8accf52b92d18b5e45f5896fadc','web-27',1,'authkey',27,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["62.26.91.22:45257","37.207.25.123:5981","[5b20:30d9:10ce:eafd:90f2:bf34:b3e8:fedb]:18638","20.120.13.221:18287"]','2023-11-03 18:53:48.108033118+01:00','2025-06-28 12:21:15.876418767+02:00',NULL,'node026','[]','100.64.0.17','fd7a:115c:a1e0::11',NULL,'2025-06-28 12:21:15.875770984+02:00');
INSERT INTO nodes VALUES(29,'mkey:5a805e2dceef2becc9d1fa1f2ae9854fd6e773570d808956b7eb8df88acf2795','nodekey:9eabd54bb541ec1ed45c2baa516d0a15011636079d750f3d36f6e570d9f0f6b3','discokey:132c6950659404dc4c4583ef60d6a5809486b0d47a2828c093a6d12c7ea61b1d','web-93',1,'authkey',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["39.206.106.178:64472","[a3b:5db7:67ad:9dfa:1b70:91c6:15ae:e5ad]:26117","[fac8:c08b:4b48:8273:42ed:d152:8301:66c4]:15174","67.172.102.32:57252","85.212.234.244:43593"]','2024-06-02 09:46:39.307697473+02:00','2025-06-28 05:47:36.860000326+02:00',NULL,'node029','[]','100.64.0.19','fd7a:115c:a1e0::13',NULL,'2025-06-28 05:47:36.859751546+02:00');
INSERT INTO nodes VALUES(30,'mkey:1e4d9c9b335bc18582f57648b44139b4c263b22ca46e4bb7b6d95745e17d9c4d','nodekey:334930dbc0b41f2ad56ffaaa7fb320379f97deddd1b6395fce9033b64446eb63','discokey:d28e8e4fda1139832bb9203d623ab9accab1bb64690a495c1cdf96b6fe822f62','web-35',1,'authkey',30,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["216.16.62.70:35569","213.115.82.246:7596","195.216.27.246:54466","[c47f:35c9:41fe:6f5:a40d:3e8b:6679:411e]:12963"]','2024-07-29 14:24:27.684620193+02:00','2025-06-27 06:44:54.03534083+02:00',NULL,'node030','[]','100.64.0.12','fd7a:115c:a1e0::c',NULL,'2025-06-27 06:44:53.247773264+02:00');
INSERT INTO nodes VALUES(31,'mkey:6ddb2155e63e4641d21add6e086675e22c209566578f70866c7de59006859ece','nodekey:85fe5b9f1f6cac554c527a85dad9a490a2962eaec8e4727537769433a5a01c14','discokey:d3bb4ec681d8d0230a71e2e01cf871c67c814a8125a4c6247ad6885de3980ee8','db-75',1,'authkey',31,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ee98:8de3:1f5b:731c:751b:ba46:a4a7:8760]:23245","[6eb3:8c34:e6c9:4c6a:25c9:89ca:c165:354e]:65112","[7003:63bb:6429:d463:96a6:990:2bdc:217d]:4300","[d820:584e:2b46:6915:6420:3056:f76:9e33]:48885"]','2024-08-07 20:35:12.944541318+02:00','2025-06-28 12:22:15.988053559+02:00',NULL,'node031','[]','100.64.0.20','fd7a:115c:a1e0::14','["10.154.123.128/25","10.128.0.0/10","192.168.246.0/23","192.168.150.0/25","172.16.0.0/13","172.16.224.0/19","10.23.224.0/24","10.0.0.0/8","10.127.59.140/30","172.24.0.0/13","172.31.132.0/22","192.168.64.0/19","192.168.56.0/24","192.168.224.0/19"]','2025-06-28 12:22:15.98744456+02:00');
INSERT INTO nodes VALUES(32,'mkey:ce4d4da08c077577b78b78a4e914507d2026e96b8584921850ea3e7dd8c0084f','nodekey:9a20472651960cee39c0f528022860269ef1cd53eab071f4aecce54f80fa874a','discokey:91cca1b79300d8ffe78e37aa02e31673d08cccdeb52aab242207efa3d75d6af0','web-49',1,'cli',NULL,'0001-01-01 00:00:00+00:00','{"fake":"data"}','["[aa0f:320b:3c12:4808:b5c7:510:c4d9:2009]:16605","[f87a:6765:f859:7291:198d:f454:4d4:8f6e]:23352","[5ddf:114:328:db55:fa05:4192:5d30:acc]:9087","86.180.96.120:14053","156.124.91.30:504","189.130.203.73:33525","[9470:53d:a212:874c:c627:32d9:5f15:39a]:61202","188.181.153.153:41358","208.6.130.2:5757","[a47e:177b:a793:d8c4:7191:f01a:4819:fe98]:47998","[9561:5615:b7c5:b2bc:4f65:b1f:a9da:5e0a]:2120"]','2024-10-26 07:18:04.947942936+02:00','2025-06-28 12:27:59.883807194+02:00',NULL,'node032',NULL,'100.64.0.21','fd7a:115c:a1e0::15',NULL,'2025-06-28 12:27:59.883542043+02:00');
INSERT INTO nodes VALUES(33,'mkey:307000af9e5b5c7efee75c3ed7d23090866a9e43955e23aac2dae50b46073c1e','nodekey:b18bd32bbd3bd77d274dea94361272cf171f407989ea6553b40acbd1fb571706','discokey:73e11d3631b882516e5fcd41d6a95f44e15c7322c8428215bc19aff366574a35','desktop-05',7,'cli',NULL,NULL,'{"fake":"data"}','["81.68.14.120:23633","39.210.11.46:40333","96.70.183.102:16729","[b2ef:7817:aea4:73a1:6391:d75b:b4ce:f0b3]:36420","[747d:f46b:96f0:f467:e625:3462:a216:ad48]:4718","124.57.193.30:26578","[e11c:edd3:59b3:c56b:a8b8:ccb9:1716:ceda]:61482","[ef1b:9f1d:9db1:6734:ba55:756d:3d3b:80a6]:30155"]','2025-02-23 07:59:15.141530181+01:00','2025-06-27 22:01:05.602056574+02:00',NULL,'node033',NULL,'100.64.0.11','fd7a:115c:a1e0::b','["172.19.0.0/16","192.168.18.48/31","10.192.0.0/13","172.20.0.0/16","172.28.162.48/29","10.175.189.32/27"]','2025-06-27 22:01:05.601785141+02:00');
INSERT INTO nodes VALUES(34,'mkey:bdd5a76f6d7f946c4bb9454abe28e7d2d212df3c451c9d068c2985649d193f83','nodekey:f8ed0148a1314428adef803acb6eaf864d1513e3388eaaeb92b7e6a2cd7bdc12','discokey:634d6b49a81f9443ce9a97b04b64c962c6707c182d85c9cdc59abd4a16c6de19','db-92',9,'cli',NULL,NULL,'{"fake":"data"}','["111.62.89.28:35728","150.196.197.67:64757","114.51.87.168:47070","[a4ce:7387:d7b4:514e:c1be:706c:1812:f866]:48356","[167f:1873:3939:734:49cc:5627:6f93:e1c7]:31097","192.35.174.224:36261","137.15.122.25:55742","[c9cc:ff0f:fbb6:e583:c69:78fa:a307:4bd2]:3181","185.20.86.11:20604","[e220:9785:d01f:28d5:1e97:4df0:2443:cc0e]:46902","[6152:ea90:3c89:e905:5201:32df:a4d3:b4bc]:41319","[20e3:1e48:26a7:5c2a:8eaf:1f7c:f36d:6a38]:22275","[73a6:792f:7678:4806:c617:d54e:2e74:862e]:25300","[f626:b8e5:f3c8:9d1d:3f91:a752:5cd5:57c4]:35608"]','2025-03-09 11:42:30.627548688+01:00','2025-05-05 10:22:29.0194247+02:00',NULL,'node034',NULL,'100.64.0.18','fd7a:115c:a1e0::12',NULL,NULL);
INSERT INTO nodes VALUES(35,'mkey:bee84dff5b07ea34d3ca9d7bc3824a4226f725e7f7fe33f879f11af907e73670','nodekey:f022dec5a44c0f09e359106d9f7ffebcfa21bb74103f16c7072e994e8a3094a8','discokey:b24e98fb8f6951bb8c4c081bb7fa326b8bf7f43181b160c0b8555deeeb55924f','lt-42',9,'cli',NULL,NULL,'{"fake":"data"}','["150.171.114.186:31321","147.156.202.29:42507","[b262:bff9:607:762e:cf05:3029:1988:9095]:14244","[8083:6d41:4186:7a48:2933:1fb1:3285:8dcf]:42595"]','2025-03-09 12:06:19.756893731+01:00','2025-04-07 13:08:46.652035521+02:00',NULL,'node035',NULL,'100.64.0.22','fd7a:115c:a1e0::16',NULL,NULL);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,98 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'463a8b372963aeaca12400faa0c7ea29e9bfa3b4c59e9622',3,0,0,1,'2023-05-19 05:09:19.66636462+00:00','2023-05-19 05:14:19.664224869+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'77a019cb12c0d0b9347a17ab23fa4c87983814fe36bb2fbb',14,0,0,0,'2024-05-03 08:13:55.8614948+00:00','2024-05-04 08:13:55.85782156+00:00',NULL);
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,"node_id" integer,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(1,'2023-05-19 07:09:23.387641743+02:00','2023-05-22 09:48:18.908103256+02:00',NULL,3,'192.168.224.0/21',1,0,0);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:0ea01e8cd608548a171ebcedc16da73b25ec18d58861be7a6b4274eb17baf6ba','nodekey:0fcf591dc1997c1d7388a3835bd24dae48240e5b03b6a7f5f33b2e813d222bcf','discokey:ed27f0b3c04222f0d05bfbc6fb5787338275ed0e32fd42fe68c669aca0f3d7a4','desktop-54','node001',2,'cli','null',NULL,'2025-01-16 10:47:40.213920406+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b8f0:cf44:22c8:82d1:f79:c3eb:9144:c24f]:6142","[8e25:af1:e31a:8fcc:7dcf:be1:a3c9:ed6a]:38766","[37a1:215f:bf3d:3fb1:6399:f7cb:4048:3ca8]:51666","137.242.125.72:25376","86.84.184.63:26062","[c187:a8:1181:8321:28ab:fe72:b0b8:8ec6]:41236","[9089:461f:ad5b:68d4:f7a8:618a:a52a:56ac]:63162"]','2023-05-17 19:38:13.531518257+02:00','2025-01-16 10:47:40.214263246+01:00',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(2,'mkey:348464565f0009e9205c9a78f381e12b9cf63ee2006b8e95d720a274347c4847','nodekey:bff28b3734e3343ded434f23bbffe562bab527165158c992e1126c94f39ea877','discokey:9c077cf7719204300ecc1ab64fb6bd3cc0cd398a4a208e37ed79e4500db3f86c','db-91','node002',1,'cli',NULL,NULL,'2025-01-26 08:14:11.090449666+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["165.5.239.20:48876","44.184.117.89:36643","90.223.136.253:7056","[e43c:be7:7f4e:8217:a009:7f9d:a510:1af6]:18872","[3a86:865b:2f4c:f3b7:88a0:4aa2:f05d:c3fd]:47680"]','2023-05-18 10:09:21.757289398+02:00','2025-01-26 08:14:11.091108158+01:00',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(3,'mkey:e44e45bd1656b97e8b328dc927ccab6cbce6c869992f70fb9c6031b980a1bf2b','nodekey:1497e461383f07b4f7cd7c76036b6fcabf23f46ac9f3651e22fd1f67eee22804','discokey:d84cef5408f6a40a7d789abbfdabd99edcd794e066894632f3cbb20d0e90a100','lt-24','node003',3,'authkey','[]',1,'2025-01-22 11:01:10.431892865+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["219.238.10.240:64443","[5e3d:ce1d:284e:9f89:155c:bff2:a65:d667]:51808"]','2023-05-19 07:09:21.399903526+02:00','2025-01-22 11:01:10.432002736+01:00',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:a2be538ff79403d577686c0ff675e1ec1b0da10902211d25ccf8adb58deaa6be','nodekey:69977d7f034a8ca09f0f08dc2d6410eb2b6f5fd343b6c88124ec37d6bcddb4d9','discokey:2a3fadbffba90bd0d74d432626a92d1ce1cf0297d4ad51cfd2011c4de7e198fa','db-36','node004',4,'cli',NULL,NULL,'2025-01-26 08:13:58.345329896+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8a81:30b8:5d50:73d7:9039:f2ce:c1be:a099]:43373","76.78.238.163:55069"]','2023-06-10 09:31:51.940506933+02:00','2025-01-26 08:13:58.345780429+01:00',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(5,'mkey:d1533206380a3d91fe09ba9aca808b8caada2cb469e9065acdebab13f22a215f','nodekey:961c8e15bdb7e261c0d359f72256c218447c9c007032f102a418d07b0b829b1b','discokey:d6e4dec2b26039771350ddf132dadf1a5d8615608bd99461d267271e7b53269c','srv-09','node005',4,'cli',NULL,NULL,'2025-01-26 08:13:52.985209632+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b12e:af88:3c55:41f8:5fba:2aa3:3248:15c1]:23643","186.84.191.82:2621","[c9d0:4e15:513a:171b:9911:f9a0:cccf:cd83]:24151","66.84.158.199:63451","47.94.115.240:6677"]','2023-06-11 13:56:42.694329408+02:00','2025-01-26 08:13:52.985552336+01:00',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(6,'mkey:4cf09b5d948c6492d0706b7972a9f46f03261dc73244cbd098653461c1426dab','nodekey:dd207345a8cdda46d50803658ab26c0fc7f28283217c6aa616a945885e92fca3','discokey:a0e6dfe46d6380aa0d131816dc0ea3287aad89196690b9bd91224f904816aa06','email-01','node006',4,'cli',NULL,NULL,'2025-01-26 08:14:07.254903549+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f739:43a6:4363:817e:34d9:3cc:1272:dba1]:26597","220.204.45.94:59135","187.96.173.136:34092","[fece:76ed:4c23:1e89:f225:97a1:94be:b5c4]:33472","[e1e6:a14:535a:668b:698:f125:543f:b5b7]:31740"]','2023-06-11 13:57:44.975695604+02:00','2025-01-26 08:14:07.255223389+01:00',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(7,'mkey:5bbbd75488079eda04771e44ddf21c5866640024a947e66cfd3c3bafb19d3e11','nodekey:022306df92cac976efdd1dd5d4454d0e20eb46ac6f7b847dbcc382a399d1c97e','discokey:4980d19a6814405d26c40dee31a93a5f43e18b41f6f6f4908ee59066e04f8179','lt-67','node007',4,'cli',NULL,NULL,'2025-01-26 08:12:22.511406544+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8ddd:4aae:2b94:4c1a:d05f:65d2:2bdb:b400]:42839","[c493:a941:58b6:7634:6221:70ba:20e6:40c4]:35486","[9b54:61a6:c678:edac:956f:741e:5e2c:9ec9]:17930","[cd3f:af1c:fcb4:bcb3:806e:adf4:3f3f:ab36]:58513","[7a83:6a84:9f15:ba1a:9671:3d54:2e31:d5e9]:64893","167.223.65.194:6907"]','2023-06-11 14:16:56.951313537+02:00','2025-01-26 08:12:22.511838306+01:00',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(8,'mkey:1abadbff7c8bdbe7a3104396c70068fa0a7aa30e405ef7d088738a8510877b39','nodekey:1251afbe69b3212ef1137c4bf2ef842409b8440d9ce32470ce4e8fb245480ccb','discokey:4a7b4155015d4cc2418ccb4005d3408b610c37b9f7bffdc625e2823f3e44514b','srv-71','node008',5,'cli',NULL,NULL,'2025-01-26 08:14:08.383652695+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["107.117.104.69:47662","[adea:86d3:b312:f445:d835:6023:f1f:f928]:27483","124.104.237.237:47957"]','2023-06-11 19:59:30.401970393+02:00','2025-01-26 08:14:08.384047921+01:00',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(9,'mkey:9ced3abf3a281d71b6f361a75769c571c4aff9e4cbab5b317f6cf18918f66bbc','nodekey:e533ead6c5b810764db07631d7b9b14434bf66549837d33a6187daac1ab1d7a9','discokey:571a7ba01a8a0fff2af21d0f135caf8ae2ee0e15fd5ab996d2e490cf968d7217','email-22','node009',6,'cli',NULL,NULL,'2025-01-22 11:01:12.033798488+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5b29:3bfe:7aa9:2767:900a:8142:1ae:eb94]:59942","165.200.68.0:39862"]','2023-06-17 19:40:45.468789461+02:00','2025-01-22 11:01:12.034166898+01:00',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(10,'mkey:6cb022f8457bd430cd8ca6e88f1d4e3678965fd0af659ef29c956fbaa81c870c','nodekey:b4dc05758407f598a2cb77f98d5c4fca9dc3820e31976887942b54a4d44e43bf','discokey:fb9dba09bf8b64d2ef3b35d917d41d5208aafb2b013a53da0d2196a152a3cf9f','desktop-07','node010',6,'cli',NULL,NULL,'2025-01-25 22:09:32.216704757+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["2.116.83.236:33635","41.172.94.101:32111","223.204.123.230:38090","[9394:b33d:67e:fde5:21f8:77e8:97a8:bbb7]:47884","14.155.207.231:4806"]','2023-06-20 11:18:35.905417341+02:00','2025-01-25 22:09:32.216953236+01:00',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(11,'mkey:e76a4d43284c0d19fbcf84b38d4bbdc5f978f8922f2ef6dcbe15170a3860a7d8','nodekey:85652faac3a65cb620073e7402506930daa194a7a3555c335741ee65a920530b','discokey:3a6aac7afdc916c9bc84b77b90c521c0e08f3fbf06ce89cfb2281271ec070b1a','lt-86','node011',7,'cli',NULL,NULL,'2025-01-25 21:58:31.767301396+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["22.207.212.228:27547","[2c3e:2260:8c34:275:2287:b721:1bdb:d462]:59540","70.115.64.117:6906","147.25.71.84:48460","[7137:65e3:83f9:ae56:6e7e:cc0c:9d64:64fd]:52919"]','2023-06-20 11:35:15.063855316+02:00','2025-01-25 21:58:31.767562461+01:00',NULL,'100.64.0.11','fd7a:115c:a1e0::b');
INSERT INTO nodes VALUES(12,'mkey:80b6649b616453e50d516e4890706ec7327a137f8051a4e17fa0f50e69408e84','nodekey:ead1339d471cd9067122e4f39e0e0f4655c1bffce99f7edfcba80812fc7a2db2','discokey:f05ebdaf81717f2a41c4985b47698a319c787056efb5412600ebd8a793147687','web-89','node012',5,'cli',NULL,NULL,'2025-01-26 08:14:25.345334172+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e758:c726:ced4:43ea:60fd:3ad8:1b8b:b514]:15200","[314c:5aba:d6ac:63d3:4de3:2c46:5e60:903b]:30789","[6883:e8c2:287f:71c8:9417:824b:b3cd:29d4]:51083"]','2023-06-20 18:22:35.061914624+02:00','2025-01-26 08:14:25.345710569+01:00',NULL,'100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(18,'mkey:70c9e841ef7964d5d754bad3f78d29b99f19f84475ac2bb72c3b38110978a195','nodekey:046c467dfce392942dbd84c1346611d3bf8634ffd51e4de6a8249d6555d28a03','discokey:38e293f7476b6c04489ff6a8e8664b8b5cdd4e93f4c39b8f065ba8e251744af4','web-67','node018',9,'cli',NULL,NULL,'2025-01-26 01:15:31.831355377+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["33.51.84.119:46756","[c844:704e:c3c0:e709:8f94:3564:1b4d:d2d9]:8357","[169:f098:49e9:99af:27bb:802f:fc22:bd59]:63749","[2acf:3f32:1763:5d21:88a:4af:8779:1b1d]:36283"]','2023-06-22 08:30:54.08720463+02:00','2025-01-26 01:15:31.831742232+01:00',NULL,'100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(19,'mkey:338d7e5ca6c5a8c65d7174eb1af312107408a16b7769b7088c8acf64134d9722','nodekey:440bd6fd6eea65489be99a6a95f4b6315ea55fa31fa1d6905a53ba4c046e0817','discokey:80890f521819e60c3778df342a98a9adfe2f46c15b0f55aa14f17df002aaa398','desktop-48','node019',10,'cli','null',NULL,'2024-08-07 09:35:12.220368767+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["191.156.96.176:5489","[166e:c30:4d73:440f:456a:22be:71e1:142b]:33036"]','2023-07-03 15:18:03.829428454+02:00','2024-09-18 16:15:14.037990869+02:00',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(20,'mkey:99e6d97451e391c261c72abf2e5d452754d7526a1d4563307259c88343c8a2cf','nodekey:581017de468a3dab721afad32b6d549e031026e4ff4a43a80ef50b035c5f60b6','discokey:af34366f05ce93952843ebba11ad2ede1fc68ca4016f5cd8569a4d057bfe3a59','srv-39','node020',11,'cli',NULL,NULL,'2025-01-24 21:43:10.483328442+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["17.32.175.58:63234","81.17.18.155:10091","171.238.29.81:53035","[cfa5:e342:a85f:891c:cff3:24ef:4692:f8a0]:31064","207.187.74.99:12216"]','2023-07-10 12:40:34.838579199+02:00','2025-01-24 21:43:10.483531762+01:00',NULL,'100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(21,'mkey:0d7504dc98ef6995e1f14cb39cd28a340b08b05debe9ec639658e6849aa3c1ca','nodekey:811ced3ca0a2ecf6076f7fc549402e4021300609338990634e648bc620a3914d','discokey:542283ed990035a314aeb44a01d428aeb9baff09786dc18463f085d98900f762','laptop-07','node021',11,'cli','null',NULL,'2023-11-20 07:19:19.447470862+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["1.118.111.70:57112","9.144.234.157:13194","[86df:346:dfa1:bd79:e59e:3d3f:b98a:63d6]:59098","[4b06:6a05:94bd:4bca:676:93a4:2e20:b923]:23713"]','2023-07-10 12:42:43.290469734+02:00','2024-09-18 16:15:14.03886353+02:00',NULL,'100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(22,'mkey:3bc73d052a1fc1b031e300db9022a617c04a055225bca5a3f3efb931b2a216ce','nodekey:3527fc46bb993bf23c7866696d860b29b5a54314c62e4d35ab44213278bc821e','discokey:db9ba442b211d4cb5b4db8f96d8f71c8bdd7e3501310d3cf5685ff821af58ca6','web-70','node022',6,'cli',NULL,NULL,'2025-01-19 14:04:19.025822598+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["218.87.248.142:13273","222.154.224.82:48446","9.237.225.227:64622","[46a1:e1e6:6b82:6599:acc7:2273:afea:f09f]:38018"]','2023-08-05 12:08:48.132161695+02:00','2025-01-19 14:04:19.032514264+01:00',NULL,'100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(23,'mkey:0799589ca5f3434d831c8401f52a58017a21139fd1bffe1ea482df70f4490a5c','nodekey:56ae1d35eb872ad470997fb776347e21ad052fd0715c7a5e8b80d9502ec71a40','discokey:23fe8efc052f59d556a6d8314a2757b07df13305d74143f7171de11aafcea455','email-11','node023',12,'cli','null',NULL,'2024-12-07 19:25:56.935152754+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4c65:a6f:293f:8d48:f136:8b6a:185a:7ec7]:43854","43.114.58.145:47143","[758f:df49:401f:abcb:57ff:c04b:79e6:8519]:62313","[2458:76c5:7d48:c26f:34e:1663:6911:ff6e]:22202","66.66.46.14:16686"]','2023-12-15 08:05:56.592241745+01:00','2024-12-07 19:25:56.935317645+01:00',NULL,'100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(24,'mkey:4c4c4036f9b8b19936757b1a5c582a4d5fd016de083063aac974d6a487775946','nodekey:e524384415f37298c43007df3c13da08a5b1156441f62e606378a5eb96a80f0a','discokey:7b9dfad48b0225f02fd0b196b2ef964b538c43795539c30fbd08e5f930bccd6e','desktop-97','node024',12,'cli',NULL,NULL,'2025-01-26 00:04:55.348199222+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e79c:8c65:bff5:d873:2599:3f53:d49b:617a]:59079","137.167.193.123:34677","159.52.2.200:7205","[5b7b:e424:ea77:aa8a:f835:d6bb:2e1f:52ea]:19152"]','2023-12-15 11:14:36.765183054+01:00','2025-01-26 00:04:55.34833514+01:00',NULL,'100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(25,'mkey:da46f6615ae2ebf0b10dd6941ea821cb7e2c64a3e46427013351d19fa9281e33','nodekey:e3a9a5473a28bc56917aa154d2bf3198bd5a226ea85693422d74a235ebc09192','discokey:2d7124caaadcf3ae57163efed0cb5e9d04ef0525e8e9d7d8e436f24ace9217b2','email-08','node025',6,'cli',NULL,NULL,'2025-01-26 08:14:57.87480236+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[74f:3ce5:744d:cd4c:eba2:4e83:2f25:8e32]:35248","[769:97e6:7060:f428:ee55:f77:43a7:8d18]:61446","[630f:7c1f:d48b:ea66:23d7:1ab9:8bd1:10f3]:25600","160.27.109.39:47606"]','2024-01-05 17:32:40.940566279+01:00','2025-01-26 08:14:57.875128359+01:00',NULL,'100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(26,'mkey:26740462ad2cf89190b15cfee7c25600065050b832b780cd845359ec0c715d71','nodekey:6d55d55e354e8a983a485dc1fbac690b5386d97b9ce3d373c89e92a68a1bc411','discokey:3fb9d7bf3b7588b6882a1c4442dd7ad2447ad3f5ae8a6e9974f3f7cabca00ee2','desktop-87','node026',6,'cli',NULL,NULL,'2025-01-26 08:11:54.580017267+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[1e45:fbc:2c6d:d1c2:a4dc:9086:f55b:6e96]:54073","[be93:4c8a:facf:a4fa:29d:ed91:91f1:12b2]:57075","[2c67:a9f3:3163:c675:3386:2447:1cc:ed3a]:42590","64.137.67.1:56198","163.42.128.241:47535","49.160.22.202:42427","[1526:e34a:8857:394e:bbe0:c043:4b37:68d4]:5245","32.31.195.128:7039","[c50a:ec:e2e:e109:3a08:f56b:2928:4921]:61265","221.147.144.138:44737","136.208.142.64:41091"]','2024-01-05 17:34:19.811670479+01:00','2025-01-26 08:11:54.58066838+01:00',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
INSERT INTO nodes VALUES(27,'mkey:73868242348c7d709b77f52963c32eb4b95c8b6f89abb5db76bd95cdaaa538b7','nodekey:2de3f421f78de3f5cfd824ffaa80cf3fde3060bc42f51c2ee2f55b49fd5fbe20','discokey:5ff3b0ad430ee5530c972ecf0d3e69f25eecdadf6ef8a309b3841d7aaa6f70d4','web-56','node027',6,'cli','null',NULL,'2024-01-16 14:32:21.570104175+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a2b8:ea55:f9e3:2c00:f423:8c56:7fec:c617]:53793","[ed88:2277:3c9a:4f64:a25e:5b41:a3ca:e904]:27852","[d203:40a2:5efc:4a42:8910:81f8:59c6:4d8d]:23389","187.126.162.12:25054","[5d8b:9391:47f1:1bbc:e01:92de:4a90:7614]:42410","172.81.188.131:23453"]','2024-01-05 17:48:25.466030859+01:00','2024-09-18 16:15:14.040766068+02:00',NULL,'100.64.0.22','fd7a:115c:a1e0::16');
INSERT INTO nodes VALUES(28,'mkey:300a566a21fcaab2665dc091300e2c5110dcaee25e2fcc4cc23b011fdae471e6','nodekey:8e36531b406e0b7b9c1b9abadc00626ccc8c6e7a0c37f70f42ccf06cd2dd03fa','discokey:a4134738054f6fc0c57b6eb47913e68a3f47ffb81af8a3496754921c2fcb02f8','laptop-98','node028',7,'cli',NULL,NULL,'2025-01-24 15:11:59.137108429+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["113.143.9.36:55432","[e266:66fe:4929:3831:7830:6f10:1572:20df]:9977","[afe5:7d57:fac5:a1c5:78d4:ee33:d474:1e56]:52223","7.208.95.117:299"]','2024-01-15 09:34:54.847632697+01:00','2025-01-24 15:11:59.137302845+01:00',NULL,'100.64.0.23','fd7a:115c:a1e0::17');
INSERT INTO nodes VALUES(29,'mkey:6d3edcfd40971c25174fa55eeddf76d05447d7d28f216c6118d8d6e35aa1ae89','nodekey:4b7d7ef564535f114a410c384aa3eb95103b5895cfd74962c7d37d3a8b0bb6ed','discokey:569e08cefcaec4d1312b70c41c12d82b26712965cbab41ac3ca5db857274ba46','web-76','node029',7,'cli',NULL,NULL,'2025-01-24 14:00:44.067705144+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[24c5:f1ec:38a5:5a2d:7224:b76b:cd04:e6d2]:63943","162.176.178.140:46577","[4f52:1708:c0a:7991:9c16:bd7d:4045:195d]:50362"]','2024-01-15 15:18:12.2871978+01:00','2025-01-24 14:00:44.067944989+01:00',NULL,'100.64.0.24','fd7a:115c:a1e0::18');
INSERT INTO nodes VALUES(30,'mkey:a81a1bea534e858e4f2f78cc1b6ebbbb1c15f6045ed63d403bdcfe2f0ebe9c6f','nodekey:bccf984b4408b961eb80fa63a1d5dff73c46bfe0bdf5e903b9d1e90d6cdc037f','discokey:7fc2f8726fc62046cc8ac9cc78d91a53b4baab2874981807e038ca1161c5addd','laptop-86','node030',7,'cli','null',NULL,'2024-02-05 12:14:40.065688294+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[acfe:eccd:ac4c:8d39:dc9b:840c:c97a:dbc5]:56981","[c204:d59b:29a8:ac18:75bc:1a4a:755e:a8f2]:26579","35.41.214.64:38835","143.202.189.84:43171","[8679:8c46:1c66:cd1e:95f8:2b0a:503c:819b]:57389"]','2024-01-15 15:21:43.217136004+01:00','2024-09-18 16:15:14.041757308+02:00',NULL,'100.64.0.25','fd7a:115c:a1e0::19');
INSERT INTO nodes VALUES(31,'mkey:b5ef2204ec90b7f3c80be32de06bc6008c678e060e21d802de3c4d6b6ab3175b','nodekey:3a5706b432df2c448b307981345f4586433fde926401c667aabc84666e77e0b5','discokey:31b8429f3d4c130f05b42f36699bc3c6ba8018d48fac1ffb98eaea9b5e77a0a7','srv-51','node031',7,'cli','null',NULL,'2024-02-22 08:35:27.098819037+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7f3b:f876:2230:c8ee:99c0:d76a:2f38:10e9]:33365","[c7af:10d6:9f3d:9dd2:3423:afc0:aa2:e156]:5125","11.55.50.90:25074","[c7aa:b53:8762:dc6e:5d4a:a2f3:16c7:3d3a]:5279"]','2024-01-29 16:05:35.338524634+01:00','2024-09-18 16:15:14.042191514+02:00',NULL,'100.64.0.26','fd7a:115c:a1e0::1a');
INSERT INTO nodes VALUES(32,'mkey:805d05918a94047740c914235c3c614042b05d18458f331ba0a46ee22d2187e6','nodekey:ebc009009bc015bc45f6499b04b7af9ff2ceff22c0f9676749b10c92f422a8ad','discokey:b6d83e1f6f0e86c3808cffb227cb6649bffcf5d4ba1596f6fd58f41b8b727133','db-70','node032',7,'cli','null',NULL,'2024-04-09 13:59:43.37062537+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a1ed:3568:9b48:6735:e553:a273:ea02:7271]:46613","90.225.231.207:5490"]','2024-01-30 10:41:58.31917869+01:00','2024-09-18 16:15:14.042506082+02:00',NULL,'100.64.0.27','fd7a:115c:a1e0::1b');
INSERT INTO nodes VALUES(33,'mkey:d5d48a3961081cf65a57a8593db00b32779c3fe44e5c410a3b763a24153543aa','nodekey:b6b5f4dc6ec205b068bbbbd3d72632d9c9bcf48812c6f444b31c4165573f9a78','discokey:3a3b06d462ae33b40900eb11fa7b58e0e16a66dab9921534fa3f77e77b28f7ce','web-02','node033',13,'cli',NULL,NULL,'2025-01-23 21:19:25.034740145+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[fc74:9d:e278:2d3d:8d46:7e4f:ce11:39b5]:6716","[bc29:715c:cdce:f1f6:8630:4929:ea1e:5c03]:10918","[af8:f5e8:32f0:75ee:d351:c0e9:78e:93d9]:12624","71.151.27.31:51063"]','2024-02-03 16:33:26.706408143+01:00','2025-01-23 21:19:25.035093942+01:00',NULL,'100.64.0.28','fd7a:115c:a1e0::1c');
INSERT INTO nodes VALUES(34,'mkey:88bd1bb4cbdbe175ea0e76e22d7a03fdedf1e1b53584f8d71861afba431765fd','nodekey:584aa8327097f88b7236e4d9b7594de8a971302ad5569a2b73ba28192d7d81ff','discokey:699c13c9c5277f160fea25002df68205cebc7dde6cec4e5e6bc2a20702a4f774','laptop-79','node034',13,'cli',NULL,NULL,'2025-01-26 08:11:55.430892992+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["14.172.203.164:46293","[c:e6fc:18ea:2e45:6bef:c1c1:f84e:b1e2]:62296","71.155.69.236:8707"]','2024-02-03 16:42:32.683785672+01:00','2025-01-26 08:11:55.431204644+01:00',NULL,'100.64.0.29','fd7a:115c:a1e0::1d');
INSERT INTO nodes VALUES(35,'mkey:627bb55986f4c5331926e5cf3db2aa5aff2cc66d63665e114f7b3d7185772264','nodekey:e52da64771618b76ec6ec975cc00d96d8da9dddeff5d91797c70fcf8d5dd0788','discokey:9380df456003f1dbff764e8f2819e914a7b0ae285b53dbf5db34a7be37b849b6','srv-65','node035',5,'cli',NULL,NULL,'2025-01-21 17:41:56.706838249+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["139.180.210.231:32286","171.29.58.211:2336","200.47.65.115:32030"]','2024-02-03 16:51:52.010016072+01:00','2025-01-21 17:41:56.707118547+01:00',NULL,'100.64.0.30','fd7a:115c:a1e0::1e');
INSERT INTO nodes VALUES(36,'mkey:291af9833f3d5afbdff138bc4dd1b6c2fd418c12362d1daf8eb65f2d59ae290c','nodekey:f4a5894e008543c73d42c157efef4a3afb66e4247ba2876c245a498e54b43563','discokey:2ff5debb97003182af5b76792c5061d232e755bb9e22fc36a60ee01905319f5c','srv-75','node036',13,'cli','null',NULL,'2025-01-19 14:01:48.956567669+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["122.50.5.12:7674","[a641:3f06:63bf:b716:4658:1e5b:ac6f:e14]:13490","197.206.147.31:58506","[b1e8:68a0:4017:a243:61d0:b303:7860:18e]:28633","[e5b8:6c78:ce2f:cf6f:13fb:401f:8223:3f04]:54121","38.137.88.247:35801","[eec2:61c0:e20a:2fa0:5e4d:56a4:5071:881b]:36628"]','2024-02-09 12:34:57.879970954+01:00','2025-01-19 14:01:48.956830267+01:00',NULL,'100.64.0.31','fd7a:115c:a1e0::1f');
INSERT INTO nodes VALUES(37,'mkey:a414d52df11b0409ce8f8160ee3390e346b511398c40e9def61fee76c0ba2edd','nodekey:1d023daf8f56db9c71b9e075a63c9cce5b74bb94dc77df6f98542ec85b2f6ec6','discokey:21c22f87ee8f10643c49baf10db4833c6a975d5122762bbd693ee70488e6766a','db-61','node037',5,'cli',NULL,NULL,'2025-01-26 08:12:35.773797291+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[3a31:6dd2:cc04:d20:e5d1:8664:3ec9:71d2]:21117","27.214.20.185:57647","[8c40:dd59:c31d:dd18:321:58a:11fa:d85a]:43064","168.4.78.117:48474","90.45.218.0:29326","90.233.46.138:29846","8.137.133.59:22781","[cb5c:f8d4:ccb0:8333:8ec:170c:a2b0:941d]:26248","[5802:df5c:8853:4851:6dcf:cb83:8208:d143]:24568"]','2024-02-27 12:14:40.452601042+01:00','2025-01-26 08:12:35.774174083+01:00',NULL,'100.64.0.32','fd7a:115c:a1e0::20');
INSERT INTO nodes VALUES(38,'mkey:465de79eadf29db3136d0b230c481876edbe7e05a803281a523618c586fd3c01','nodekey:01614d4aa1bb0be1f6b41e10aa9ea1c7af206ef9a2571bb68c24e85bea697216','discokey:d3eea5725d8408db2ffc560d74c70da0a70c3f3dc40a0d6a6fad9afaaadee9f2','srv-59','node038',6,'cli',NULL,NULL,'2025-01-25 21:52:13.380610729+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8125:ebe4:83e1:4806:f061:5bd9:a08a:8ccc]:6467","114.199.17.195:52817","[de36:fc02:8cf4:c60d:824a:9963:2440:5b5d]:39343"]','2024-05-22 08:08:16.045350656+02:00','2025-01-25 21:52:13.381028865+01:00',NULL,'100.64.0.33','fd7a:115c:a1e0::21');
INSERT INTO nodes VALUES(42,'mkey:ff2ce8eb04d99e45d7babacacc758ec8e031474fcf494b4c0349c7084cc62365','nodekey:660bae997d6da1efccc0135ed712176a379f59ec9ca7a02eddea607a8855cebe','discokey:66ca4169c6be68079a1244ec506d8c922af4133187e0117a1800ed4791ed9a67','web-21','node042',14,'cli',NULL,NULL,'2025-01-22 12:09:19.893938069+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[3a3f:717c:1ea3:7c82:81e4:5d9d:765f:7da4]:6540","[bc95:459c:aab:499d:4354:d239:ef14:dcb]:14429","[f673:7912:6d5e:7244:62ca:9500:78f5:31c0]:27677"]','2024-07-03 11:12:29.418355657+02:00','2025-01-22 12:09:19.89470831+01:00',NULL,'100.64.0.37','fd7a:115c:a1e0::25');
INSERT INTO nodes VALUES(43,'mkey:df2afe1643d44e7b5d2b4fe1b78e8b0c8c7871b50b1b580048cf6b184cc99143','nodekey:4512e240f89db2671db1ad974c151afad41491d7d11486b644aa2cf66bc3410e','discokey:f4b10325d44499f510cf0bd61d7c9d116b10c14434b8fab4559f0797f033936a','lt-12','node043',14,'cli',NULL,NULL,'2025-01-22 04:20:37.032313126+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c91c:4366:d3bd:a993:b5e:75c7:ef8e:8166]:46974","191.185.253.85:37427","17.31.200.70:26794","[183d:f2d6:b80:36c5:318e:64e9:7f4a:b389]:12440"]','2024-07-03 14:48:50.263910778+02:00','2025-01-22 04:20:37.032585258+01:00',NULL,'100.64.0.34','fd7a:115c:a1e0::22');
INSERT INTO nodes VALUES(44,'mkey:38b6d221092d1ca7bc7a6bded2156ea0cad76eeb937d2fbf8b5c519a6e655096','nodekey:68d1f2817719a56a0a6d482869a443e60b317da298d6e07940c3475a6ce76ff3','discokey:1027b93e5031cec5525f02ff625e869e89a050796b2d19ed3a3574f3817bd4e7','web-74','node044',14,'cli',NULL,NULL,'2025-01-22 12:43:56.696054645+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9e5b:f6da:727b:9014:ca72:1f2c:87a8:8e81]:62466","39.179.118.209:64932","[cc06:5e56:fb0d:b760:b501:efab:c73b:b492]:26172","162.210.141.106:52036","[84ef:a164:d1c:d20d:797c:753e:f8fb:3108]:5767"]','2024-07-03 15:23:48.066044194+02:00','2025-01-22 12:43:56.732053672+01:00',NULL,'100.64.0.35','fd7a:115c:a1e0::23');
INSERT INTO nodes VALUES(45,'mkey:877372ef6f845443379ee2d2c9d0538937dd1b3d4e13fc6c204b04a86b4daff9','nodekey:97c037de3c80309adc59c894999d4993a451c2762b936748a34025cb26e5e3f8','discokey:aee8faedda0c97f6483e11ed745a1e387605e09132b2c55170dbad0696d5f126','web-77','node045',14,'cli',NULL,NULL,'2025-01-22 04:20:27.07284339+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4c0c:1e2f:95d7:9d1f:b068:c776:ee11:ea3b]:46940","[7526:4960:73a9:911a:1fbf:92bf:1219:a6bf]:25440","[360:d312:e59c:79e0:a7e4:2295:caa0:946e]:17493","26.61.8.198:45861"]','2024-07-03 15:54:01.706018896+02:00','2025-01-22 04:20:27.073044637+01:00',NULL,'100.64.0.36','fd7a:115c:a1e0::24');
INSERT INTO nodes VALUES(46,'mkey:39dc02019f24bdb0b2b66f9d32d44fb95a3a71de52fccf6aebeed5fec709bb12','nodekey:041c60aa08b42defc979d1a4606096540df4a4dd10191818d54ddbfab89816b8','discokey:5b1253f35e01f1e97ebb34884ede4d1bcb46446c1c5eed456dfc6638e08a8dad','laptop-06','node046',14,'cli',NULL,NULL,'2025-01-22 04:20:43.53444835+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["98.122.93.117:34230","[2077:6b7:927e:5e5c:a0f0:3352:1490:e1e1]:47997"]','2024-07-03 19:38:07.783745318+02:00','2025-01-22 04:20:43.534962909+01:00',NULL,'100.64.0.38','fd7a:115c:a1e0::26');
INSERT INTO nodes VALUES(47,'mkey:fcbeeeafcfa6f96917f0beefe78ede5a3ec327664fed68dee26757dc6e6896af','nodekey:216b84282abd69521955b0a8df7136a33b496a0152bea4928ed426893594f569','discokey:0fdf92e9def6d70c2161eaa1cea4d6a032bd6bddc47ecfce29cb962c2c6ad2d2','srv-99','node047',14,'cli',NULL,NULL,'2025-01-22 04:20:25.918857828+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["125.19.14.225:12660","[d722:f972:c192:4cff:3916:e1e7:6d02:236b]:55695"]','2024-07-04 10:38:08.344092869+02:00','2025-01-22 04:20:25.919209254+01:00',NULL,'100.64.0.39','fd7a:115c:a1e0::27');
INSERT INTO nodes VALUES(48,'mkey:570c6df03e928e23665040f909113b7f753ced52db4050f3f918562c930c4ea5','nodekey:7becf5cc7f3471e35f59f844ff8d2c41a580b9f548dba24f5e98896403b0da30','discokey:3ea933912fe815a3a4d6c69aba1da031d24d78003b4bad7cad131c8e599a300a','lt-30','node048',15,'cli','null',NULL,'2024-10-20 13:53:33.831192385+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["97.124.255.12:40587","166.176.60.55:23674","[33c0:859c:4a78:8bdb:359e:31e4:1e71:7e39]:50383","[3aab:52a2:b9d3:1816:5627:336:6c60:57d7]:13486","22.83.180.41:14147","26.126.135.206:7777"]','2024-07-26 08:09:56.608302315+02:00','2024-10-20 13:53:33.831387627+02:00',NULL,'100.64.0.40','fd7a:115c:a1e0::28');
INSERT INTO nodes VALUES(49,'mkey:4d5f9a38fce205b2dfb62f42464172a1408e00221317b01332714a4db55e6ebb','nodekey:415009b46e40247f7a60d9e0f53c938b6a032fd4c11ae70d824e2d95cf170957','discokey:280e5896d458bd63044265484d38ad711ef52a68981f83281ff693e837421a13','web-11','node049',16,'cli','null',NULL,'2024-09-19 09:07:18.28136023+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[475b:3641:5abe:b0a8:8a68:dd51:8e80:3efa]:574","153.151.233.195:41734","[19b0:8be2:708:d27f:4d3d:3c93:9979:e9e8]:50438"]','2024-08-05 17:32:41.937626584+02:00','2024-09-19 09:07:18.281618912+02:00',NULL,'100.64.0.41','fd7a:115c:a1e0::29');
INSERT INTO nodes VALUES(50,'mkey:a35a00c69e2fa10d442ae03a4d9312ee61e56caaa030d1303a4ebab2b26c27eb','nodekey:39bf208ba118345630aecd3c6ed042d40b1e6b4897c9548a21a473c28352ba95','discokey:437f4dda6cfd2d269543f32dfaac1333b8660cec03b279728e296f6cbc67ca69','db-28','node050',10,'cli','null',NULL,'2024-08-07 10:10:06.595550455+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["150.170.146.70:3311","139.117.239.209:33788","[2eac:ffa0:99fd:d109:c120:a35d:ed48:eea3]:51544","[7644:c348:2969:b90:e84f:94d4:b629:f266]:49336","169.247.3.239:36225","[5b4c:bb2:d43f:6ff4:d494:8616:a66a:d059]:50360","203.180.122.83:13344","63.162.234.32:11653"]','2024-08-07 11:50:54.144157179+02:00','2024-09-18 16:15:14.050033969+02:00',NULL,'100.64.0.42','fd7a:115c:a1e0::2a');
INSERT INTO nodes VALUES(51,'mkey:38d8adcfb8f6217b6dce62c89e816da260f1b0747a9a980e0ede5de9412aab4b','nodekey:98cb6a87bfa7cd614051008583e5f0904552b44d98854a0fb5d8e0e3c3115949','discokey:104eda6ea8f8fbeae20617662e601bd0acf102511d17ffc829c08db6a7f78872','laptop-32','node051',14,'cli',NULL,NULL,'2025-01-22 04:20:18.310186164+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["33.182.22.166:13283","181.10.243.176:14596"]','2024-08-07 14:19:31.156780417+02:00','2025-01-22 04:20:18.312102891+01:00',NULL,'100.64.0.43','fd7a:115c:a1e0::2b');
INSERT INTO nodes VALUES(52,'mkey:3a83699597e3bee8b15df3733dfb54b1d7af3ff9ccc7a4b65df4b0feb4a3f25c','nodekey:86cf80f0bd8bef4888116f2bab1b5ac4b11bd6fa637f7ef0886cd0aa265b2bec','discokey:28e2d745a5216bdaaeb83b4483b19d1c2ae0c149b97c08c06a4b90ca2c742a00','srv-53','node052',17,'cli','null',NULL,'2024-12-25 17:27:58.515851096+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["72.183.239.155:49891","167.46.143.131:51781","[9e9f:93d:a8cf:c86f:17e3:9e2b:dc42:efa6]:3616"]','2024-09-22 15:48:41.385301399+02:00','2024-12-25 17:27:58.517153789+01:00',NULL,'100.64.0.45','fd7a:115c:a1e0::2d');
INSERT INTO nodes VALUES(53,'mkey:d1fda0c437a79b121817c1c24e88bce18fdab566d5e74678b8730cb48c1dd574','nodekey:1463eab453b78867448baaae38b88547334df5070c30e77a08cd3410bd721d8a','discokey:4688405d194600e9c1a783e71e274c3e42976a5021d81db4ba4a0506a768cbca','srv-86','node053',17,'cli',NULL,NULL,'2025-01-26 08:11:05.595652839+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["69.219.0.37:43476","[6084:ee60:1697:864e:4a61:cf6e:e9b6:4c05]:63961","[fad7:2601:d286:4772:3cce:6e89:f66e:9eeb]:5430","216.60.124.11:45041","[d513:c472:d7a:f316:f610:10d0:9851:4feb]:3955","156.228.105.157:61542","102.126.185.0:50694","[156b:e934:d171:2693:8db4:f193:a58c:17b6]:24190","79.255.179.99:56057","[6369:4412:8cfc:2a5e:7cfb:8b45:e2ac:f98a]:16090","23.0.29.75:24889","[ab0:1193:7bb7:4a4a:c036:b911:994f:3aa4]:5116","[9491:7bd5:3979:414a:d198:a8b:f2e7:29b4]:62795","140.73.225.124:1710"]','2024-10-28 10:04:50.084492941+01:00','2025-01-26 08:11:05.596582615+01:00',NULL,'100.64.0.44','fd7a:115c:a1e0::2c');
INSERT INTO nodes VALUES(54,'mkey:e47e8ca8e89ebf89a399a8206916ac7a55f855b449acf80c7d27b6b225aac678','nodekey:377793cdc9eb6f2279806b2b70d0fea24c4f4c1dfdf92771eecd9199f67d80e9','discokey:299a45d53358f6a43234df87ceff28e642433aa06e8341862e8557d1d499ddae','email-83','node054',14,'cli',NULL,NULL,'2025-01-22 12:00:41.056079317+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7d2a:9d5:1fbb:54a7:fe7a:bc40:5ea2:ca20]:3534","[f630:8bb5:a4ff:95b1:6d95:decb:a5d2:373b]:42456","[6cc8:4fca:c46e:ed25:e9ef:43e:f0ea:121a]:60965","122.41.198.69:28824"]','2024-12-09 17:10:55.363593066+01:00','2025-01-22 12:00:41.056216357+01:00',NULL,'100.64.0.46','fd7a:115c:a1e0::2e');
INSERT INTO nodes VALUES(55,'mkey:59c5aaa1eca0e9109bf2b9ec602e9d844936dd3d632543489fe5e66f4cc31e8a','nodekey:815c97157312040cb667db75315dfe58933335496ab31a98f351728872da07ab','discokey:bf3097a60b972dc98275e07c31df2ac05dc540280d7ff9006ee5c70ee8d5962d','laptop-61','node055',18,'cli',NULL,NULL,'2025-01-19 14:04:25.389314117+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["182.195.110.58:14598","155.200.222.111:64410","[b554:3604:41e8:60a4:229:a09c:efd3:c73e]:39533"]','2024-12-10 13:56:39.287449662+01:00','2025-01-19 14:04:25.410288998+01:00',NULL,'100.64.0.47','fd7a:115c:a1e0::2f');
INSERT INTO nodes VALUES(56,'mkey:1025548b29dc9733e1099fbb6516778e9d8f07eeaa214cd1ef33438e731333eb','nodekey:3f21adc328130ab468ac28ee25b4002974610ddd7b11f586752dec5a151114b2','discokey:605115f1238609b148dff010ca6e04d7b337df4e2b88de7a1f900a2f1de7db42','laptop-79','node056',19,'cli',NULL,NULL,'2025-01-26 08:09:46.709773709+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a329:52fe:45d1:996e:4767:d50c:6513:92ac]:54604","80.29.45.84:8223"]','2024-12-17 14:58:39.429211911+01:00','2025-01-26 08:09:46.710363543+01:00',NULL,'100.64.0.48','fd7a:115c:a1e0::30');
INSERT INTO nodes VALUES(57,'mkey:f8394e6be895b3c2261fab8cd62d1f28124d377df6b4b17dac4b9f18c54a3e00','nodekey:a8302c7783050d61484d3d6e4abbf256b7062303e01bdfcc6371046a468fdfb0','discokey:3e9447d6b8e10da3215899328df484415e4fc8e6e301e232ca51721f93a50b53','email-71','node057',20,'cli',NULL,NULL,'2025-01-25 14:06:07.21327404+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["158.184.132.83:56087","[1129:e066:9c34:190d:7bf0:c941:18d6:f96b]:48892","7.227.92.62:26101","[86a5:23f7:afd9:863e:e7f5:63bb:ed61:9d51]:17106","110.235.245.179:61572","[57a6:fde1:814:36cd:f8de:668c:f5fb:4f60]:39714","[f08d:aeaa:107:fc17:5c30:ab9a:e31e:3147]:55879"]','2024-12-17 15:17:14.26936913+01:00','2025-01-25 14:06:07.213397766+01:00',NULL,'100.64.0.49','fd7a:115c:a1e0::31');
INSERT INTO nodes VALUES(58,'mkey:13565579616a60409e411d5406b743f5dcf878da4aa82031350537d41038e09f','nodekey:788fe7ffbb2b564852b1b9ec170a4267449c98b17ed51dcdce65942de712918b','discokey:8027b59df9ab90efb6d63898d60362cc3583c20b52aa4694083ef2201404fb27','lt-15','node058',12,'cli',NULL,NULL,'2025-01-25 18:41:03.881898904+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c493:2a8f:6625:98c3:4f4a:db04:19cb:c7df]:41081","96.25.93.176:21890","219.197.124.83:46550"]','2025-01-17 10:17:23.455895657+01:00','2025-01-25 18:41:03.882180987+01:00',NULL,'100.64.0.50','fd7a:115c:a1e0::32');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-05-17 19:36:55.859473496+02:00','2023-05-17 19:36:55.859473496+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(2,'2023-05-17 19:36:57.059073465+02:00','2023-05-17 19:36:57.059073465+02:00',NULL,'user002','','',NULL,NULL,'');
INSERT INTO users VALUES(3,'2023-05-18 10:10:36.248939077+02:00','2023-05-18 10:10:36.248939077+02:00',NULL,'user003','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2023-06-10 09:06:13.920718561+02:00','2023-06-10 09:06:13.920718561+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(5,'2023-06-11 19:58:32.371218434+02:00','2023-06-11 19:58:32.371218434+02:00',NULL,'user005','','',NULL,NULL,'');
INSERT INTO users VALUES(6,'2023-06-17 19:39:53.031565686+02:00','2023-06-17 19:39:53.031565686+02:00',NULL,'user006','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2023-06-20 11:35:09.325846831+02:00','2023-06-20 11:35:09.325846831+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2023-06-21 22:47:48.196234382+02:00','2023-06-21 22:47:48.196234382+02:00',NULL,'user008','','',NULL,NULL,'');
INSERT INTO users VALUES(9,'2023-06-22 08:30:35.068995572+02:00','2023-06-22 08:30:35.068995572+02:00',NULL,'user009','','',NULL,NULL,'');
INSERT INTO users VALUES(10,'2023-07-03 10:18:32.123226+02:00','2023-07-03 10:18:32.123226+02:00',NULL,'user010','','',NULL,NULL,'');
INSERT INTO users VALUES(11,'2023-07-03 10:18:37.130387602+02:00','2023-07-03 10:18:37.130387602+02:00',NULL,'user011','','',NULL,NULL,'');
INSERT INTO users VALUES(12,'2023-12-15 08:05:06.013615212+01:00','2023-12-15 08:05:06.013615212+01:00',NULL,'user012','','',NULL,NULL,'');
INSERT INTO users VALUES(13,'2024-02-03 16:32:42.224977233+01:00','2024-02-03 16:32:42.224977233+01:00',NULL,'user013','','',NULL,NULL,'');
INSERT INTO users VALUES(14,'2024-05-03 10:12:38.220973042+02:00','2024-05-03 10:12:38.220973042+02:00',NULL,'user014','','',NULL,NULL,'');
INSERT INTO users VALUES(15,'2024-07-26 08:08:40.979783263+02:00','2024-07-26 08:08:40.979783263+02:00',NULL,'user015','','',NULL,NULL,'');
INSERT INTO users VALUES(16,'2024-08-05 17:32:02.878091894+02:00','2024-08-05 17:32:02.878091894+02:00',NULL,'user016','','',NULL,NULL,'');
INSERT INTO users VALUES(17,'2024-09-22 15:48:00.287392203+02:00','2024-09-22 15:48:00.287392203+02:00',NULL,'user017','','',NULL,NULL,'');
INSERT INTO users VALUES(18,'2024-12-10 13:55:11.256977421+01:00','2024-12-10 13:55:11.256977421+01:00',NULL,'user018','','',NULL,NULL,'');
INSERT INTO users VALUES(19,'2024-12-17 14:57:58.550971236+01:00','2024-12-17 14:57:58.550971236+01:00',NULL,'user019','','',NULL,NULL,'');
INSERT INTO users VALUES(20,'2024-12-17 15:02:08.053169491+01:00','2024-12-17 15:02:08.053169491+01:00',NULL,'user020','','',NULL,NULL,'');
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE UNIQUE INDEX idx_provider_identifier ON users (provider_identifier) WHERE provider_identifier IS NOT NULL;
CREATE UNIQUE INDEX idx_name_provider_identifier ON users (name,provider_identifier);
CREATE UNIQUE INDEX idx_name_no_provider_identifier ON users (name) WHERE provider_identifier IS NULL;
COMMIT;

View File

@@ -0,0 +1,104 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'463a8b372963aeaca12400faa0c7ea29e9bfa3b4c59e9622',3,0,0,1,'2023-05-19 05:09:19.66636462+00:00','2023-05-19 05:14:19.664224869+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'77a019cb12c0d0b9347a17ab23fa4c87983814fe36bb2fbb',14,0,0,0,'2024-05-03 08:13:55.8614948+00:00','2024-05-04 08:13:55.85782156+00:00',NULL);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:0ea01e8cd608548a171ebcedc16da73b25ec18d58861be7a6b4274eb17baf6ba','nodekey:0fcf591dc1997c1d7388a3835bd24dae48240e5b03b6a7f5f33b2e813d222bcf','discokey:ed27f0b3c04222f0d05bfbc6fb5787338275ed0e32fd42fe68c669aca0f3d7a4','desktop-54','node001',2,'cli','null',NULL,'2025-01-16 10:47:40.213920406+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b8f0:cf44:22c8:82d1:f79:c3eb:9144:c24f]:6142","[8e25:af1:e31a:8fcc:7dcf:be1:a3c9:ed6a]:38766","[37a1:215f:bf3d:3fb1:6399:f7cb:4048:3ca8]:51666","137.242.125.72:25376","86.84.184.63:26062","[c187:a8:1181:8321:28ab:fe72:b0b8:8ec6]:41236","[9089:461f:ad5b:68d4:f7a8:618a:a52a:56ac]:63162"]','2023-05-17 19:38:13.531518257+02:00','2025-01-16 10:47:40.214263246+01:00',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(2,'mkey:348464565f0009e9205c9a78f381e12b9cf63ee2006b8e95d720a274347c4847','nodekey:bff28b3734e3343ded434f23bbffe562bab527165158c992e1126c94f39ea877','discokey:9c077cf7719204300ecc1ab64fb6bd3cc0cd398a4a208e37ed79e4500db3f86c','db-91','node002',1,'cli',NULL,NULL,'2025-01-30 19:01:13.901141508+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["165.5.239.20:48876","44.184.117.89:36643","90.223.136.253:7056","[e43c:be7:7f4e:8217:a009:7f9d:a510:1af6]:18872","[3a86:865b:2f4c:f3b7:88a0:4aa2:f05d:c3fd]:47680","86.50.30.30:18216","[fdbe:7908:805e:6c8f:47c2:2c87:b1c4:44]:48470","188.237.187.170:7622","[c032:e70d:dbd3:27de:85a3:28b4:8a64:155a]:48864"]','2023-05-18 10:09:21.757289398+02:00','2025-01-30 19:01:13.901463969+01:00',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(3,'mkey:cd435d043e3dba7c0cd2f089c57c46abd59f84c1d05d5b9ea03d344a6dd7e61c','nodekey:5a558233f8e076e1f3a78e95e274265332c984372e8bfa91c62e748707e3d9c8','discokey:d2dbd001168ca99d38dd2b56270201056955f5d05a97934278b7a8311d809e37','laptop-91','node003',3,'authkey','[]',1,'2025-01-26 12:49:44.580858758+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d40d:59d:b450:8ad7:bc04:9836:f16d:d538]:10080","87.84.28.245:43373"]','2023-05-19 07:09:21.399903526+02:00','2025-01-26 12:49:44.582326495+01:00',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:4b507fc1f103042642d3c619b0cdc77a6dadb4415ccd78b5b3880f4fcacacef6','nodekey:259a4b5de585a90421714fe40040c339a26a660b1fa0511f6323e51926b88c5c','discokey:36b7d0cbd65c02c741958c3e793960fcf2b93f7d907fc4483f548043864bdbae','laptop-59','node004',4,'cli',NULL,NULL,'2025-01-30 19:08:13.209119931+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["1.79.159.39:34092","[b12e:af88:3c55:41f8:5fba:2aa3:3248:15c1]:23643"]','2023-06-10 09:31:51.940506933+02:00','2025-01-30 19:08:13.209865565+01:00',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(5,'mkey:4937d77921b93317ae3fb1fb406ffd3fa2d9154afa78c3ed00a5a685ede9aaae','nodekey:3c38f956817733cb7dfb474be1a8289f90ae0cb4df5dfd42ad8fc57e3a35b702','discokey:9abee320c0000a4f325c4aaf75173a715bbd1dc88f93699df10e7bf06ba0097f','email-95','node005',4,'cli',NULL,NULL,'2025-01-30 19:08:24.678660839+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[cd19:68e0:693d:5e6:659d:9f7e:277e:21cf]:31475","86.42.90.60:13473","[14af:1283:fc98:5791:282:5e8:a450:315f]:22243","201.199.139.78:9445","121.159.150.133:23963"]','2023-06-11 13:56:42.694329408+02:00','2025-01-30 19:08:24.679099806+01:00',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(6,'mkey:33535c582e158d27acdafdda3edd3777fd581ddc2adad52eaee607a82a0f9d9c','nodekey:144ba4b580e0d6d9add9a482c5f893deba28ec44622ccd056a06a9ddf80af32c','discokey:62d0e22d743d8096882b23d1bc5f5810863dc39876bbec1253ff2a4c445f423b','db-15','node006',4,'cli',NULL,NULL,'2025-01-30 19:08:06.034183297+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[698:f124:543f:b5b7:644e:5b79:4160:6e0b]:42676","165.236.227.226:53522","[e65d:59b5:f599:8596:2bc9:56b7:820a:8c12]:12277","[8ddd:4aae:2b94:4c1a:d05f:65d2:2bdb:b400]:42839","[c493:a941:58b6:7634:6221:70ba:20e6:40c4]:35486"]','2023-06-11 13:57:44.975695604+02:00','2025-01-30 19:08:06.034942035+01:00',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(7,'mkey:26d1a98dc9d16df9ce9692bd330c25b5d021d11ff35b15a79f282b51c7f13888','nodekey:dd3d71574aa1270acb5176b071f1e99f512a4436ac20050df6d617865d2e47f9','discokey:def83e0a3c95bb379b8af036680ce07aa7725d1d2c4b7feb656c5a441f51fef7','laptop-38','node007',4,'cli',NULL,NULL,'2025-01-30 19:07:54.580925698+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[cef3:87e9:7ebe:e5a3:a6a0:5dc2:7a83:6a84]:43421","177.175.178.171:24266","[489b:6c59:1877:6215:ddc8:57f8:78dc:321c]:3025","77.213.161.20:47662","[adea:86d3:b312:f445:d835:6023:f1f:f928]:27483","124.104.237.237:47957"]','2023-06-11 14:16:56.951313537+02:00','2025-01-30 19:07:54.581710417+01:00',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(8,'mkey:9ced3abf3a281d71b6f361a75769c571c4aff9e4cbab5b317f6cf18918f66bbc','nodekey:e533ead6c5b810764db07631d7b9b14434bf66549837d33a6187daac1ab1d7a9','discokey:571a7ba01a8a0fff2af21d0f135caf8ae2ee0e15fd5ab996d2e490cf968d7217','email-22','node008',5,'cli',NULL,NULL,'2025-01-30 19:08:26.01751405+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5b29:3bfe:7aa9:2767:900a:8142:1ae:eb94]:59942","165.200.68.0:39862","187.166.20.165:11208"]','2023-06-11 19:59:30.401970393+02:00','2025-01-30 19:08:26.017863321+01:00',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(9,'mkey:4115777754bb14ec2d04345ee2ffb97968692a59f0f66fc4aec9737616903f41','nodekey:5a0133001bc6b02d996ea2e2cae3abcfcb073d69a25aefd4077f36c564af0075','discokey:91ec1c63e9572a6742c8bf8796ce7f5ffc3d42a03ad53070a3ee56a2523317a9','lt-39','node009',6,'cli',NULL,NULL,'2025-01-26 12:49:38.323826827+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["192.120.123.140:19810","63.152.247.204:38090"]','2023-06-17 19:40:45.468789461+02:00','2025-01-26 12:49:38.324187836+01:00',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(10,'mkey:94da5084f8fc1cfe7671b94a0d7ef767719bd0fed89f16bc2726728db4cd9d25','nodekey:e6527563ef7a2647b6c719e0c9c95c1ab2a2eeef7fbb3f46a108ee0fbca026f0','discokey:f76230afd20bfcce74fd0d689b35e82cab5bfdf4cd1530073e87b1acae513c2b','web-50','node010',6,'cli',NULL,NULL,'2025-01-30 05:10:56.348559998+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[bed5:a4c2:8547:c044:9956:2566:d794:c918]:56801","113.147.88.203:61138","22.207.212.228:27547","[2c3e:2260:8c34:275:2287:b721:1bdb:d462]:59540","70.115.64.117:6906"]','2023-06-20 11:18:35.905417341+02:00','2025-01-30 05:10:56.349025961+01:00',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(11,'mkey:4b59a62af15d9350f16c9a2e03aa6174692418948d6a5ad5c272f5bb88feb061','nodekey:5004a6cb840ab527bcf897c17761fd30338b1250b3a9e0ac3e3c60a422ee09d0','discokey:e191e0039edbf786f88ab163173eb3c297e060f51cb90249f36e4867d5d89928','email-58','node011',7,'cli',NULL,NULL,'2025-01-30 16:14:19.573081099+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f99c:24c3:b1b5:8b96:abe2:3ddc:c21e:87dc]:65141","[dfe7:6f6b:a382:4fc:a3f6:eb9:9ebc:5798]:1474","56.63.78.181:15200","[314c:5aba:d6ac:63d3:4de3:2c46:5e60:903b]:30789"]','2023-06-20 11:35:15.063855316+02:00','2025-01-30 16:14:19.573230274+01:00',NULL,'100.64.0.11','fd7a:115c:a1e0::b');
INSERT INTO nodes VALUES(12,'mkey:88ef4bda4139c7c09e33bbc866b88e069c51187346d8095238179c82502dffcc','nodekey:7ad274415b296099222e0ca334eb849e0e6595ffa54dbcc94a0fc9ffa69d1747','discokey:388c1077bdd17ce1f86b92936609756ecd3e8b21ab3f4b8a84da7727dd2b2552','web-70','node012',5,'cli',NULL,NULL,'2025-01-30 19:07:30.410870761+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["33.51.84.119:46756","[c844:704e:c3c0:e709:8f94:3564:1b4d:d2d9]:8357","[169:f098:49e9:99af:27bb:802f:fc22:bd59]:63749"]','2023-06-20 18:22:35.061914624+02:00','2025-01-30 19:07:30.411307945+01:00',NULL,'100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(18,'mkey:c2e0286f5c59bc66c9a7c950ffc72f8241916be6e9f16861fe3680cb3cd2c172','nodekey:2c67affcede5c938b2b0aa8a0a42753fecc147bcad5f3df411aa999751a3482d','discokey:7f4e89781a7a169060fdedb120b316e88a2c66f40c41118bdc1759ff818a28bc','srv-41','node018',9,'cli',NULL,NULL,'2025-01-30 09:35:22.409611504+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["204.36.161.195:61712","[bfe5:7c2f:e9:71b:749a:5176:3138:83c6]:63942","24.173.68.87:39654","216.16.204.79:19720"]','2023-06-22 08:30:54.08720463+02:00','2025-01-30 09:35:22.410235858+01:00',NULL,'100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(19,'mkey:28aaec5617646c94f895ba9449d924469be2345700d80131bd72c449b02346bb','nodekey:419dd05380491ade058b139b43fda78a99d52b00cb1984180c3f251c19c7bac1','discokey:0f0490d46f8794af22a08c1d6e874ee8303df7ba39095fdd78db9522849ed427','web-93','node019',10,'cli','null',NULL,'2024-08-07 09:35:12.220368767+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7b81:52eb:f4e9:e74d:905:79d4:67b1:d359]:13795","81.17.18.155:10091"]','2023-07-03 15:18:03.829428454+02:00','2024-09-18 16:15:14.037990869+02:00',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(20,'mkey:8bc474d6d0d812ab011b7748675802bd9d4af70c2edab0da6c682a0cf1ca34f8','nodekey:2cb4a0ab98e83dafb20621dcfec33cd5fa7fa99b97998546cb6796249bdba88a','discokey:e341e99f352acb61779807aea844516d7e9e220c58699f09232bcee105e88797','lt-43','node020',11,'cli',NULL,NULL,'2025-01-30 18:17:53.075807086+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["63.3.67.150:22907","[77ac:562:7c4c:438a:6ec:be48:743d:47b1]:11349","[33cd:731c:f110:9b45:66b5:de81:1daa:757f]:5997","[d618:5830:8a37:fbe4:3b37:a35c:fad9:11d1]:57112","9.144.234.157:13194"]','2023-07-10 12:40:34.838579199+02:00','2025-01-30 18:17:53.076540774+01:00',NULL,'100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(21,'mkey:84000655b74a39e42877c1941d84a4e5b94db841c5440f19950813a5c25e1204','nodekey:bf71cc04a7b081255d32ce73fa666db0090b20af8e6e6115d279edead8b15227','discokey:b37d86213f6b344b4b24c73541b9c65e5aebcfa8d5c25114d10ef57761da6c09','lt-77','node021',11,'cli','null',NULL,'2023-11-20 07:19:19.447470862+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[68:80fa:7b30:3a0:d1fb:3e89:2c73:256b]:30308","[ad42:3917:5edb:3e85:732:1c71:a19e:9fe0]:11799","25.63.36.137:903","179.61.150.131:36912"]','2023-07-10 12:42:43.290469734+02:00','2024-09-18 16:15:14.03886353+02:00',NULL,'100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(22,'mkey:5f7118e434c174dbac710b1d088db6213ca894ca3912a92688110ed5f96eb37d','nodekey:eb2dc8689a32bb671c62e8744f2c968b9ecf3a0e1e50775de39a0f2a4f4011aa','discokey:bc1e75ccfe1c7c282df689d559cc5ef08659f1ee198456bc82df99e13371dd1c','desktop-81','node022',6,'cli',NULL,NULL,'2025-01-26 12:49:36.385301301+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["146.144.83.178:46323","1.236.14.11:13477","184.41.32.72:1026","[f136:8b69:185a:7ec7:94a1:ca58:5d95:ba9f]:21119"]','2023-08-05 12:08:48.132161695+02:00','2025-01-26 12:49:36.385653182+01:00',NULL,'100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(23,'mkey:94d0eadf801d88022019f9353b7c29cafdd060a269a0245396e01f1293953cb0','nodekey:1db769d2ca42bc0f8b4e18b5c89a31fb4595edf0592ce1a534b713ba503f07e9','discokey:912056b78049017764c78a047b65feb3c3b934fa26ac62b44f8d7d561711321a','srv-85','node023',12,'cli','null',NULL,'2024-12-07 19:25:56.935152754+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["21.107.170.69:30767","212.18.227.41:50735","[f774:e89b:980f:975d:fd3e:93f:a9b5:2034]:46054","[7225:d0ce:d29a:59d8:f596:b945:9a02:29ed]:43419","[5a76:d5b0:b51d:6b56:afaa:3968:277b:192c]:19250"]','2023-12-15 08:05:56.592241745+01:00','2024-12-07 19:25:56.935317645+01:00',NULL,'100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(24,'mkey:247cad9ffd7d108f553e7658db14bbad992332458abb9b4bc5a0c0d3a13ead9f','nodekey:bbfb569ac8a34cf4d59d2bc13d0f03660d24aedf22c61b56510a65d20bdf0812','discokey:61f92520602549b9bc684eeed3186f608a38e13794d06d4b8d165c4efbb69a24','laptop-29','node024',12,'cli',NULL,NULL,'2025-01-29 22:13:40.47247515+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5b7b:e424:ea77:aa8a:f835:d6bb:2e1f:52ea]:19152","[bb06:d322:7cec:426b:ef38:55d0:e7ce:95bc]:31597","[320d:6314:eaa2:a098:8594:977d:27b:8442]:12827","163.235.127.125:61230","208.233.231.156:35248"]','2023-12-15 11:14:36.765183054+01:00','2025-01-29 22:13:40.472698887+01:00',NULL,'100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(25,'mkey:232be2297acbce00785cbdff20dad9faf2b2147e15eeab1a5282fd2a48e7fb6a','nodekey:87b7b1f5e238a246897514dc0b57eca6403f8483bed626a9400c6ebc54161544','discokey:d87d208ca22717686d41e21c9adba999965a5cbcd4336b3dc3876b10f58bfaff','web-78','node025',6,'cli',NULL,NULL,'2025-01-30 19:05:56.81412934+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["160.27.109.39:47606","[62f5:b64d:d2e4:9015:b03a:c64e:656:8c59]:5020","3.166.190.93:19852","[243b:de9c:b8c:ea69:b66d:b3ce:14a5:9671]:22747"]','2024-01-05 17:32:40.940566279+01:00','2025-01-30 19:05:56.814546683+01:00',NULL,'100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(26,'mkey:0fe76a3827debaf6af306bc25af56334fa1e02f73245aa70c508bc3e253c84cb','nodekey:0926a8072f34e14c1131b1e3c92402a4b8cf0dca5cd36a6dcf90887ec2890d41','discokey:69cd5153481aad99ea93df0e335d8aa7d8fd36171e49e1c6d11ef5830af2f7c5','email-86','node026',6,'cli',NULL,NULL,'2025-01-30 19:00:06.767381943+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["64.137.67.1:56198","163.42.128.241:47535","49.160.22.202:42427","[1526:e34a:8857:394e:bbe0:c043:4b37:68d4]:5245","32.31.195.128:7039","[c50a:ec:e2e:e109:3a08:f56b:2928:4921]:61265","221.147.144.138:44737","136.208.142.64:41091","[537d:7a83:c891:ac8:9460:e49:e769:988b]:55062","50.23.199.223:4814","[a2b8:ea55:f9e3:2c00:f423:8c56:7fec:c617]:53793"]','2024-01-05 17:34:19.811670479+01:00','2025-01-30 19:00:06.767773381+01:00',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
INSERT INTO nodes VALUES(27,'mkey:95e3d9972a77bda2f7b243091fbd9286ebbc415c108cd984c15b419b82867a59','nodekey:4c7e3c311374ae8f7b4983bfde91b950234915f4fef2da3445702f1d474f21da','discokey:4b5e41432c037af086249f5b0f7552da9cd523ba84092ed303f09e27d294859e','web-93','node027',6,'cli','null',NULL,'2024-01-16 14:32:21.570104175+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e56d:6121:30ef:4870:5bf5:1066:8aa7:dffc]:56225","87.98.228.228:42410","172.81.188.131:23453","[cbf3:dde3:47ec:2c76:49ea:93f1:f43c:d8d4]:39412","[7267:209d:7e:6a59:8e21:b285:91d8:fc9f]:1315","217.68.74.145:28707"]','2024-01-05 17:48:25.466030859+01:00','2024-09-18 16:15:14.040766068+02:00',NULL,'100.64.0.22','fd7a:115c:a1e0::16');
INSERT INTO nodes VALUES(28,'mkey:4a6e46330ccd4b3026337cdef37485c27592babda329107565c2a19d97253dcc','nodekey:17de47da1955a8a034788ae671c34fb10083568bf9e2f7494276cb2636065246','discokey:449f5f35a3507974cf03e3ac5c055d890de5122f57a7c2d84a0d3b324998607e','desktop-17','node028',7,'cli',NULL,NULL,'2025-01-30 17:08:57.494420371+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c2f1:82ab:922a:9b9d:f53d:a0b3:bccd:f6af]:299","[d28b:7b33:1f88:7583:7ed7:a923:4c90:9ee0]:62318","[68e3:a070:f02c:708c:a057:b579:aee9:4d25]:11747","[7224:b76a:cd04:e6d2:67fd:fec0:2f14:1837]:29002"]','2024-01-15 09:34:54.847632697+01:00','2025-01-30 17:08:57.494670314+01:00',NULL,'100.64.0.23','fd7a:115c:a1e0::17');
INSERT INTO nodes VALUES(29,'mkey:6472928030d718e6e2802fb3bceba7c14b4716d994be1b3562a1d03104fd37a9','nodekey:78bd59aba83429486e0ed2d50873211974650b2e2ad8f79dbc07c5d13d00c5a5','discokey:86ead449e1be5a300287e690fb9522ba4da3e5bdeb593d6261e4117708fe3ade','lt-82','node029',7,'cli',NULL,NULL,'2025-01-30 16:03:46.587400142+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[fd0d:f112:f642:c343:ac14:8ede:dc04:e2d9]:58412","[8a1a:5c17:bb81:bb69:c7db:3513:f14c:ca2d]:52077","123.235.220.59:59925","155.210.184.45:60093"]','2024-01-15 15:18:12.2871978+01:00','2025-01-30 16:03:46.587530619+01:00',NULL,'100.64.0.24','fd7a:115c:a1e0::18');
INSERT INTO nodes VALUES(30,'mkey:947247ecfc46c57c6806008c2edac71e9e88b87903b4814f1d4f2b3ae3b4824a','nodekey:d19005205b9e8a43b2727bc1f9bc44acb0ced560304f2aad60b335de457603a9','discokey:882d6a41700c79c95d228db394d4a59244a1c2f39493b658400d95bd162b957a','lt-04','node030',7,'cli','null',NULL,'2024-02-05 12:14:40.065688294+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e868:f68f:cceb:8d29:5451:c716:bdca:437d]:41081","[7016:b48d:8bcf:4ccd:8679:8c47:1c66:cd1e]:41980","22.231.20.85:41616","129.130.98.189:47833","[99c0:d769:2f38:10e9:c01a:e3d:898e:afc]:17505"]','2024-01-15 15:21:43.217136004+01:00','2024-09-18 16:15:14.041757308+02:00',NULL,'100.64.0.25','fd7a:115c:a1e0::19');
INSERT INTO nodes VALUES(31,'mkey:c4853fdd63bed5a98baaf74df437eff743f8a968fda613fdf1f2a111e7c1b100','nodekey:9fc3f32ce92ab7f8ab987f16258b11265037a47cd9a1a68ac0e07bd3c279c183','discokey:e52f22aa8e170b6a031e682b5ed6e5f790f2d6ae1eecb752de1b362a1cce7bd4','web-89','node031',7,'cli','null',NULL,'2024-02-22 08:35:27.098819037+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["133.177.207.78:47765","[d1b1:653:cd17:f39c:8a89:85d0:c7aa:b53]:5279","107.140.203.49:9365","[1660:741a:160:67c9:7972:5f9d:14bd:ee53]:21178"]','2024-01-29 16:05:35.338524634+01:00','2024-09-18 16:15:14.042191514+02:00',NULL,'100.64.0.26','fd7a:115c:a1e0::1a');
INSERT INTO nodes VALUES(32,'mkey:8c468799222af319e17ec309dbbf3a87fb6d924a1cb17e5a0bd7e027fe3bfe5e','nodekey:3c7d82f4a44cfa1469b957ac911e8506a68962fb2583d2afaf3e8a621c0c4aca','discokey:ba179b51f3540e619eaac9a6d4bc67403daa7c3cf28a6b579087cd6d284501b4','lt-53','node032',7,'cli','null',NULL,'2024-04-09 13:59:43.37062537+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d21f:d7bc:f690:e3ba:82fe:8122:c33d:5a86]:227","10.67.113.92:45634"]','2024-01-30 10:41:58.31917869+01:00','2024-09-18 16:15:14.042506082+02:00',NULL,'100.64.0.27','fd7a:115c:a1e0::1b');
INSERT INTO nodes VALUES(33,'mkey:be7f190677fd0cd1c5e78b4ae5b02a1738dd60be7d9a41017000b22ae9636af4','nodekey:a404e578d3edd3e3d879e9f1946c859b5982c59f5e528bf6b987bd55de00b25b','discokey:ad3013f116c370866fc9134b66999bb05e2dc10a8e2944230c3d9893c0a94c67','lt-80','node033',13,'cli',NULL,NULL,'2025-01-27 21:29:56.078640865+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[af8:f5e8:32f0:75ee:d351:c0e9:78e:93d9]:12624","71.151.27.31:51063","[f0d6:21dc:48f5:63f4:daff:a3c4:7d60:51ea]:17286","[38c5:9551:f6ed:b087:91ba:bef1:771c:273d]:62171"]','2024-02-03 16:33:26.706408143+01:00','2025-01-27 21:29:56.079623854+01:00',NULL,'100.64.0.28','fd7a:115c:a1e0::1c');
INSERT INTO nodes VALUES(34,'mkey:7784df3aabe1ca1edab5270028fb3cae8b66cee2384790d06969d1e6e298520f','nodekey:fd8e939fd6db8caf6623ac3d73c12ade4da110d8c1f29e3a3ee0d2be0c526915','discokey:59aff4582e00d92260e6a90d6d0da3d818fe8f52c081c8b65e18006ef8269ebe','lt-65','node034',13,'cli',NULL,NULL,'2025-01-30 19:07:28.343976513+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["71.155.69.236:8707","125.2.67.155:50785","32.6.80.181:17295"]','2024-02-03 16:42:32.683785672+01:00','2025-01-30 19:07:28.344657417+01:00',NULL,'100.64.0.29','fd7a:115c:a1e0::1d');
INSERT INTO nodes VALUES(35,'mkey:ad3838fa63fb120ae8d3e47d4bb6bb4009e7fc5d91483d1ba7417d0681fd7162','nodekey:b10ddbdcf826d79049d74a7d4ad036b499c86f7daf786bb1a9b295366b57afe8','discokey:618ef629d3bd261964c613ad3bc45e6278fa274d734c8cd2d3396cf8c9742d88','web-33','node035',5,'cli',NULL,NULL,'2025-01-26 12:49:34.225736739+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["169.159.71.157:18240","[bbb7:5b4d:218d:55ff:ac9b:1fb6:c933:9a55]:63943","18.156.132.228:63356"]','2024-02-03 16:51:52.010016072+01:00','2025-01-26 12:49:34.238493375+01:00',NULL,'100.64.0.30','fd7a:115c:a1e0::1e');
INSERT INTO nodes VALUES(36,'mkey:c536a3efc460fb2da4c4775e2b51d0c84f001dc46a4d902429e74e97b2d3c6d4','nodekey:91da2acfa3d7f7c7b0c1a2d952ee527514504fddc504809423762203a16145ab','discokey:989ff5f21d485dcb6312fade38c9047bbde1fbce46bc29ac5f6afe00610ad215','laptop-46','node036',13,'cli','null',NULL,'2025-01-19 14:01:48.956567669+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4017:a243:61d0:b302:7860:18f:7d4d:f605]:28633","[e5b8:6c78:ce2f:cf6f:13fb:401f:8223:3f04]:54121","38.137.88.247:35801","[eec2:61c0:e20a:2fa0:5e4d:56a4:5071:881b]:36628","[b8c2:c792:3329:2c93:f94b:a948:7d11:b9f2]:908","[5925:353c:bd9a:f42e:1916:45b4:c170:e515]:18400","[c2a5:cc2f:e2e8:573f:7b01:4aa:8a1a:fd71]:32146"]','2024-02-09 12:34:57.879970954+01:00','2025-01-19 14:01:48.956830267+01:00',NULL,'100.64.0.31','fd7a:115c:a1e0::1f');
INSERT INTO nodes VALUES(37,'mkey:142e67963c9045164df7b33af6d2149d72f59527df44fd75221647281444cbe7','nodekey:a3a2cd2bd0c3a1f783d0391ea1951c5c9226ddca0f18130b77fccff8b874d694','discokey:bdb788f8825b9bd816f37dcea882920382c7feb143edf0a6baefc9015774d8aa','lt-24','node037',5,'cli',NULL,NULL,'2025-01-30 18:52:12.369500276+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c31d:dd18:321:589:11fa:d85b:695f:1fca]:43064","168.4.78.117:48474","90.45.218.0:29326","90.233.46.138:29846","8.137.133.59:22781","[cb5c:f8d4:ccb0:8333:8ec:170c:a2b0:941d]:26248","[5802:df5c:8853:4851:6dcf:cb83:8208:d143]:24568","48.38.104.41:43702","139.100.200.227:62546"]','2024-02-27 12:14:40.452601042+01:00','2025-01-30 18:52:12.369790328+01:00',NULL,'100.64.0.32','fd7a:115c:a1e0::20');
INSERT INTO nodes VALUES(38,'mkey:6829f2d5523aba7a27c31e59e2341f3feb5a5a72a0268ef10d23c39811ea3b53','nodekey:10e4ff66fdd37fb54f6dcb0e42f483a15b6340610acc3a4517c24f0f350b5a9a','discokey:f20786f9c7edc967d0b415bbcce39468441af3b531ff15656c0683d3f328720a','lt-88','node038',6,'cli',NULL,NULL,'2025-01-30 16:09:13.024420431+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a393:f17f:6728:82e4:c1e7:2367:82d0:daaf]:18560","[d192:9897:4cd7:bfb5:de36:fc03:8cf4:c60d]:25096","212.199.67.213:11150"]','2024-05-22 08:08:16.045350656+02:00','2025-01-30 16:09:13.20760575+01:00',NULL,'100.64.0.33','fd7a:115c:a1e0::21');
INSERT INTO nodes VALUES(42,'mkey:33e764ae40265089c5e7dbfc8571aa23bb390fc7e1e8bd2f3e0cd6891c308214','nodekey:c444c9ff652ba29181a5f7fdf991f91f704e6698237ee18b0649c81879ec932f','discokey:2e1db3a1eea266673acf7826aa44b5aa6fdd23c6ba41330562b37c5a523ba358','laptop-81','node042',14,'cli',NULL,NULL,'2025-01-29 16:46:30.352621883+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["190.179.215.222:61930","45.131.187.230:22916","[510f:af99:ed4d:f53a:fc21:8640:9ad9:4930]:16050"]','2024-07-03 11:12:29.418355657+02:00','2025-01-29 16:46:30.353292973+01:00',NULL,'100.64.0.37','fd7a:115c:a1e0::25');
INSERT INTO nodes VALUES(43,'mkey:353844c4b332bdbf7f39796c522ee89d7f64fde342d3e566878f456df0d57a54','nodekey:c9f47cb50fd2b9075cda9d68018659491ac29dbbe7a04e8405039fd385966fa7','discokey:ec43638237bc43ab6a9839b3a4d54c2593e11a2ebd13bd491f08f68d7cf93ac0','desktop-90','node043',14,'cli',NULL,NULL,'2025-01-29 16:39:14.757499741+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e071:3cd7:878c:ae2d:7dcf:eab0:d0d1:decf]:37427","17.31.200.70:26794","[183d:f2d6:b80:36c5:318e:64e9:7f4a:b389]:12440","169.173.198.12:15274","[e5df:1889:6ac5:7d21:4dfd:614b:7eb9:d93c]:792"]','2024-07-03 14:48:50.263910778+02:00','2025-01-29 16:39:14.757996869+01:00',NULL,'100.64.0.34','fd7a:115c:a1e0::22');
INSERT INTO nodes VALUES(44,'mkey:6d3e50168ff6e672ed7650abc5a1de7fec7150c6f84932c705c84964824d1d39','nodekey:ad70f51f99efeefdf0c8e0a9e818db1e5de474e67b2b0a1609a53190339938ef','discokey:c4d4ad19814f9312b454cadb85b333f80cccca1b4a42f30780f7a0f4ccfe1bff','laptop-97','node044',14,'cli',NULL,NULL,'2025-01-29 16:27:57.81216036+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b501:efaa:c73b:b492:c3cf:865:d55b:9557]:26172","162.210.141.106:52036","[84ef:a164:d1c:d20d:797c:753e:f8fb:3108]:5767","[c15a:e322:a721:c9a7:a662:ccb8:26b8:e1c4]:63192","[87c4:c36b:d96f:525b:fa4c:c5f6:7bc8:d6bb]:35894"]','2024-07-03 15:23:48.066044194+02:00','2025-01-29 16:27:57.81269748+01:00',NULL,'100.64.0.35','fd7a:115c:a1e0::23');
INSERT INTO nodes VALUES(45,'mkey:e1772e6b138211afff6aa8fee08438c311b1d9d32576075c980d39591b13ae77','nodekey:92b8cc28bff0c53f95fbdd8c1363040100ae849e78aea04a3755e9a1fd03fe4e','discokey:7b368b5d64b6e4fb4f0ba9e5809bee8b769949ecdc69ec6ee6c9f12c2321fced','email-94','node045',14,'cli',NULL,NULL,'2025-01-29 16:48:59.640158179+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[caa0:946e:b130:39aa:31b0:8f9:7526:4960]:1729","120.102.247.255:41936","28.177.95.32:7841","[fb23:5998:c63d:b6c4:e86a:96b2:61c:e110]:51902","[89d4:f6c6:ccf6:b19d:3b76:642e:7a36:d229]:930"]','2024-07-03 15:54:01.706018896+02:00','2025-01-29 16:48:59.64070889+01:00',NULL,'100.64.0.36','fd7a:115c:a1e0::24');
INSERT INTO nodes VALUES(46,'mkey:af6c1d228b675ff04d2584e2c23d6288ec312a6b44c5c0eed213423a11711787','nodekey:f5b21f25bb22b5cf0cedb1b643d50c3a6512ef300cc971eccccbcc500cc23408','discokey:72843a1b2564c177d8556eb0d76dda7cbe0d9f1408bd250fcc6149518eb6d5c0','desktop-41','node046',14,'cli',NULL,NULL,'2025-01-26 18:40:46.403363149+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[37a8:9998:e94e:e297:940e:5414:5549:87c7]:37130","27.138.122.133:37304","98.38.29.194:12660"]','2024-07-03 19:38:07.783745318+02:00','2025-01-26 18:40:46.403759275+01:00',NULL,'100.64.0.38','fd7a:115c:a1e0::26');
INSERT INTO nodes VALUES(47,'mkey:5bbb77092f21b4835b0ae1af3871fc48445819c9b6e5ff9c46ad4a623b662ae8','nodekey:191c7cc089ee160c07b63e2b6b5ef0701d76d914009420baddad9bfce13e3f2d','discokey:712cadffd23f106abeea82ae70bbae8e06c2a58f3db617afd0d149b3012c64fb','web-61','node047',14,'cli',NULL,NULL,'2025-01-28 14:54:17.570894466+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["186.118.23.242:32373","[5bd8:a5a8:1b3:5e41:3c4d:5fc:4c0:c6cc]:24847"]','2024-07-04 10:38:08.344092869+02:00','2025-01-28 14:54:17.571166771+01:00',NULL,'100.64.0.39','fd7a:115c:a1e0::27');
INSERT INTO nodes VALUES(48,'mkey:a1e793aa09c20360cb4ef57e7dc42171a0abbc9f562140609e930ba5b7b12e83','nodekey:3343520915898c9d90b7517eabf8660d66c37ed12aea0b5a4935458f95c801c9','discokey:6a80e23d10d2cb3edb58c9c47ee997f9063d6aed2f29049f635b6bf1da090885','web-24','node048',15,'cli','null',NULL,'2024-10-20 13:53:33.831192385+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["101.103.129.11:50383","[3aab:52a2:b9d3:1816:5627:336:6c60:57d7]:13486","22.83.180.41:14147","26.126.135.206:7777","[8706:d109:5006:f832:dca7:58e4:4451:be15]:15180","177.4.27.29:60895"]','2024-07-26 08:09:56.608302315+02:00','2024-10-20 13:53:33.831387627+02:00',NULL,'100.64.0.40','fd7a:115c:a1e0::28');
INSERT INTO nodes VALUES(49,'mkey:13b8d4cafbdb8e9ab77928219aa57bf778878866ad8e6108b60aaab8dc8cec36','nodekey:17cefd68f8a9cc20b3d4fd93598f77ddfd6bd5a7e6e4b49861f9faad8623e0ef','discokey:939a04ddd2f9a24468e07ee7924dbb7a7662c1e8a1b67426f57fd48c7394448b','desktop-40','node049',16,'cli','null',NULL,'2024-09-19 09:07:18.28136023+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[19b0:8be2:708:d27f:4d3d:3c93:9979:e9e8]:50438","129.0.5.112:19015","[91e2:54c6:93fb:ec32:6ab4:186d:81cb:b815]:37323"]','2024-08-05 17:32:41.937626584+02:00','2024-09-19 09:07:18.281618912+02:00',NULL,'100.64.0.41','fd7a:115c:a1e0::29');
INSERT INTO nodes VALUES(50,'mkey:03979d5446bb3f596bf0234d81ca84482eacb132e874ceda6cc2703422cd728c','nodekey:805c03cada525f14ee90d28ea02b23a3f57b470c793314872ad9daacf6c6484e','discokey:eb4135e1cc73a3c6b513d8cc04ca0c55a2aef7b0009845fa1d2036488aadf0f8','desktop-02','node050',10,'cli','null',NULL,'2024-08-07 10:10:06.595550455+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9175:498d:64ac:4342:2eac:ffa1:99fd:d109]:21202","[5cba:56ef:db08:320c:333a:541f:605c:44d5]:57469","150.211.2.236:50360","203.180.122.83:13344","63.162.234.32:11653","[6b63:f552:f930:e22c:fc42:3b41:c5c6:6d5f]:63162","114.48.12.185:47837","[2964:cc5d:3a1b:7889:acc8:4d8:22c1:398a]:43515"]','2024-08-07 11:50:54.144157179+02:00','2024-09-18 16:15:14.050033969+02:00',NULL,'100.64.0.42','fd7a:115c:a1e0::2a');
INSERT INTO nodes VALUES(51,'mkey:5877139c52c0bf3c0fd054bd046aaf4530dd8946548a7bc1a06733649d1557d8','nodekey:553d9638c8c455e8d1bc811ea3af03db1eb3c586413447c8003e7d905a61d06c','discokey:1da883c9eff402d786362aaac2f478c835308b3acec0993e6293becf4474609f','web-62','node051',14,'cli',NULL,NULL,'2025-01-26 12:49:36.351868783+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["86.215.174.228:26026","93.101.159.155:64005"]','2024-08-07 14:19:31.156780417+02:00','2025-01-26 12:49:36.353124877+01:00',NULL,'100.64.0.43','fd7a:115c:a1e0::2b');
INSERT INTO nodes VALUES(52,'mkey:0e64072dafa5f9e49266b41fc4b21ff7d287be8f4e5f2b6c395487d632f1cf3f','nodekey:2f77bb8cbeb426bcded5ad9fc6da44b0b76b8d6759f10a8db28e634290760ee7','discokey:836558738056edd1fa8d190c7e42f120b365a48a3b1f1c96c87755bb82d7ad0f','desktop-07','node052',17,'cli','null',NULL,'2024-12-25 17:27:58.515851096+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d889:f751:710:257f:977f:5597:9908:14e0]:61162","[f83a:5ebb:911d:ef36:743c:8086:8a4c:a5c7]:23538","[dc45:365c:e426:71d7:fe23:fdd4:d2c2:9409]:57262"]','2024-09-22 15:48:41.385301399+02:00','2024-12-25 17:27:58.517153789+01:00',NULL,'100.64.0.45','fd7a:115c:a1e0::2d');
INSERT INTO nodes VALUES(53,'mkey:a6f93e99a5019b3b6a2941d95dc7fcbfea5a59317a48b99db93b7a3f4f0a65bb','nodekey:1f78a6d76ea4a2135c0da46b202560c86ed30cd7e8239d4508088d0e02ffb961','discokey:1744062452f052aba5320e37fc08aaa37f1430db7c32c94c5626f0f3c858de3d','desktop-82','node053',17,'cli',NULL,NULL,'2025-01-30 18:44:17.370143702+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6084:ee60:1697:864e:4a61:cf6e:e9b6:4c05]:63961","[fad7:2601:d286:4772:3cce:6e89:f66e:9eeb]:5430","216.60.124.11:45041","[d513:c472:d7a:f316:f610:10d0:9851:4feb]:3955","156.228.105.157:61542","102.126.185.0:50694","[156b:e934:d171:2693:8db4:f193:a58c:17b6]:24190","79.255.179.99:56057","[6369:4412:8cfc:2a5e:7cfb:8b45:e2ac:f98a]:16090","23.0.29.75:24889","[ab0:1193:7bb7:4a4a:c036:b911:994f:3aa4]:5116","[9491:7bd5:3979:414a:d198:a8b:f2e7:29b4]:62795","140.73.225.124:1710"]','2024-10-28 10:04:50.084492941+01:00','2025-01-30 18:44:17.370913494+01:00',NULL,'100.64.0.44','fd7a:115c:a1e0::2c');
INSERT INTO nodes VALUES(54,'mkey:e47e8ca8e89ebf89a399a8206916ac7a55f855b449acf80c7d27b6b225aac678','nodekey:377793cdc9eb6f2279806b2b70d0fea24c4f4c1dfdf92771eecd9199f67d80e9','discokey:299a45d53358f6a43234df87ceff28e642433aa06e8341862e8557d1d499ddae','email-83','node054',14,'cli',NULL,NULL,'2025-01-30 10:34:07.584992479+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7d2a:9d5:1fbb:54a7:fe7a:bc40:5ea2:ca20]:3534","[f630:8bb5:a4ff:95b1:6d95:decb:a5d2:373b]:42456"]','2024-12-09 17:10:55.363593066+01:00','2025-01-30 10:34:07.58575113+01:00',NULL,'100.64.0.46','fd7a:115c:a1e0::2e');
INSERT INTO nodes VALUES(55,'mkey:c0b2d0e2ff266bfc53e07b246f000847c7d0c86649152c2bc6a421443627c733','nodekey:105f9b052032e510f9ab817af7df0ea561dc304223ceaf75c9116ce487bbfe86','discokey:cfb384a16ce161420b9bd42615dfa45ca547084bf61f3728ccf342d8693a9383','lt-74','node055',18,'cli',NULL,NULL,'2025-01-30 13:48:04.74697862+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["155.233.51.24:54409","191.94.7.112:26528","[1f30:3a9a:19b:da4e:a3d7:9a55:707b:d112]:54974"]','2024-12-10 13:56:39.287449662+01:00','2025-01-30 13:48:04.74733257+01:00',NULL,'100.64.0.47','fd7a:115c:a1e0::2f');
INSERT INTO nodes VALUES(56,'mkey:5b28e1fc6b67cf4a900aeed7c413f06b83e8e9de3f5fada3cefac31ef51ac932','nodekey:8f015f994d88c5348b98c2cf40f9f224f85787941044438f4a9ee34cabbb5d4f','discokey:5b44ab87d7620b22294cae6536c69b272e9ca9ade6812bf4f41375fcb44ace7c','lt-86','node056',19,'cli',NULL,NULL,'2025-01-30 19:03:58.987501999+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["44.230.54.249:64083","29.229.203.183:13"]','2024-12-17 14:58:39.429211911+01:00','2025-01-30 19:03:58.987864718+01:00',NULL,'100.64.0.48','fd7a:115c:a1e0::30');
INSERT INTO nodes VALUES(57,'mkey:200d4ac92d1084e22e9cdcd0a74ac2a12e33a279dd2bd9aa88a779c92c82bf35','nodekey:48c2e3c2c51da5ce63d764bb3698482e96746c543f2c728235ea8afe971202b2','discokey:2b3dec80b092c04bb25c9c39bf18e7f85d38dc666de1fff2dd7a6dd95e6af162','desktop-62','node057',20,'cli',NULL,NULL,'2025-01-28 11:01:52.058651587+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["178.193.134.41:58563","29.219.180.224:55412","[2ddd:7c1b:a237:41c8:3baf:e9cc:1f31:9057]:62916","[9c34:190d:7bf0:c940:18d6:f96c:9aca:8c0a]:8787","181.226.177.82:63703"]','2024-12-17 15:17:14.26936913+01:00','2025-01-28 11:01:52.058860063+01:00',NULL,'100.64.0.49','fd7a:115c:a1e0::31');
INSERT INTO nodes VALUES(58,'mkey:4d690637aa5cdd6575d9dbb7fa0b55c83bece3e82bc689e73122c9120f871772','nodekey:8733914d48b0c34a0111ec5f633123ae4ec7de39e597077d659ab8f2354270b9','discokey:ff25bf692a69cc0e79101e1cc1b926ca97b6e3897e65c55e5bd3f09ca1ea6d16','lt-20','node058',12,'cli',NULL,NULL,'2025-01-25 18:41:03.881898904+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[57a6:fde1:814:36cd:f8de:668c:f5fb:4f60]:39714","[f08d:aeaa:107:fc17:5c30:ab9a:e31e:3147]:55879","80.27.167.78:21548"]','2025-01-17 10:17:23.455895657+01:00','2025-01-25 18:41:03.882180987+01:00',NULL,'100.64.0.50','fd7a:115c:a1e0::32');
INSERT INTO nodes VALUES(59,'mkey:581824fee9a91fdacfd3529d7e28548440259284e3f3251d00981c34ff1817a4','nodekey:ef7f1fd978b01f30758074df76c5eab42279ba200d7e3386fd6545e2d2865463','discokey:1e77e9eb061b34dd246f44cf32bf818b431948fed86d4dd02de112845caad4e3','srv-53','node059',21,'cli',NULL,NULL,'2025-01-30 18:54:11.030475733+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2e30:4d2d:4925:201f:e845:2a12:503c:9524]:34552","105.198.43.87:48215","214.199.117.40:30901","58.251.220.64:42364"]','2025-01-29 11:59:27.291048957+01:00','2025-01-30 18:54:11.030888364+01:00',NULL,'100.64.0.54','fd7a:115c:a1e0::36');
INSERT INTO nodes VALUES(60,'mkey:1fde1d60f3aacf01ce0d5faa329ebe3da2465dfc4a568e31648b06b313a690d4','nodekey:e1038e05b45f270e2d47d90898a9f599253421e9046a799d394b623766a81aae','discokey:d5e3dddd1a9422458643058ed2d8fd8e9da0cf3b4378cf4b421672cf1e13d71d','desktop-08','node060',21,'cli',NULL,NULL,'2025-01-30 19:04:25.435259221+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["15.226.94.222:41465","109.183.111.101:20875","[912a:9b6c:5845:f8d4:f476:491f:cdef:8b7d]:21677","22.203.32.217:28664"]','2025-01-29 12:01:57.48748166+01:00','2025-01-30 19:04:25.4358129+01:00',NULL,'100.64.0.55','fd7a:115c:a1e0::37');
INSERT INTO nodes VALUES(61,'mkey:17196701e0a4b870bae52dd1fc0eeb26843f2ceb0745ad263e69ef737d9a5403','nodekey:a8c47bf5faf5110c298862a919bc7308eb616c92c110f7dfd38194a74b3ffe7a','discokey:4dcc87f0698a1e669485874eaacf9438090ac69deb20fb9cc693d7df75b8265f','web-53','node061',21,'cli',NULL,NULL,'2025-01-29 23:58:55.106877823+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[1ad1:4e50:7001:e922:d6b0:2b1e:c718:f3f7]:31291","13.175.9.68:14464","[e9e:965b:7b7a:3219:44cc:f0f3:e3a0:a504]:34840","[2476:14e8:ab74:a221:cfca:bd5e:64aa:83d1]:48008"]','2025-01-29 12:03:01.464646336+01:00','2025-01-29 23:58:55.107564914+01:00',NULL,'100.64.0.56','fd7a:115c:a1e0::38');
INSERT INTO nodes VALUES(62,'mkey:e8ecee3b3c1e75bea1ee3d00a759ab31864c33f6c8df4a15c352d1b420450d88','nodekey:820bacc3e7d49bb90be56bb3297c98aed4c777bc1aed02b3b0b7b4301c8e445f','discokey:d16e93e7d7b6fbc451ec3576211f7c19398ca18f684fa285f5d6bd84be50286c','laptop-57','node062',21,'cli',NULL,NULL,'2025-01-30 17:23:37.246636502+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["69.125.5.213:11546","[68bb:e8d1:72d8:8b02:608b:2284:c9b3:184d]:20876"]','2025-01-29 19:23:14.092804852+01:00','2025-01-30 17:23:37.246792226+01:00',NULL,'100.64.0.57','fd7a:115c:a1e0::39');
INSERT INTO nodes VALUES(63,'mkey:3e0dcb286f6e19b1e3a0b5330978aa8a8d710934cc754e811d0f690046e04469','nodekey:cd2d301b9b163b806fe8d63cdd07004f26559706bf7dc782645f05e12ebe0ec3','discokey:14675666cf2b55697f0032897d1c6742413d7c24bada8cfdc6246bf150d06fc7','db-76','node063',21,'cli',NULL,NULL,'2025-01-30 19:07:01.231463482+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["74.32.222.198:59615","145.91.193.5:37126","[2fb6:ea0a:3639:a1cd:9075:a258:6a79:4f5c]:13944"]','2025-01-29 19:41:40.535299057+01:00','2025-01-30 19:07:01.23207245+01:00',NULL,'100.64.0.58','fd7a:115c:a1e0::3a');
INSERT INTO nodes VALUES(64,'mkey:1adfdd6ba590feffc711c40506ed5ecb16609cd6e90a536d50c5f54cec223508','nodekey:0d58cee32d99cde76b3d8769ae4605cb4bfc9cbb01fc13069c8b59faca320e48','discokey:cba00753c508df0b5cdea1e59eaa829c6cfda4f8399121307f931dbaa3730296','desktop-90','node064',21,'cli',NULL,NULL,'2025-01-30 19:04:27.551570027+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["172.210.49.58:58821","[23f9:9c6d:5069:a14f:33d2:c0b1:5ab5:f83b]:46288","[b341:3259:c5dd:9f91:fd70:c616:3033:2b3b]:59081"]','2025-01-30 18:18:57.519126133+01:00','2025-01-30 19:04:27.552291406+01:00',NULL,'100.64.0.59','fd7a:115c:a1e0::3b');
INSERT INTO nodes VALUES(65,'mkey:547a8b97c8c8227d9ba40174ce4d28d0e64f10fae3f39797c60e29742ed59e62','nodekey:cb4a9d1dee6f581036b7c262348cf2c4a96be8b2eea78f7805097e3f7b1a9fcf','discokey:c233a42a4afb5fbf921bf7b3fb4330e6c46273d18570aaf6b7254dbf3c67614f','desktop-82','node065',21,'cli',NULL,NULL,'2025-01-30 19:01:43.552616838+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["21.197.131.68:13997","6.193.99.72:20874","181.248.237.50:21695"]','2025-01-30 18:19:40.354692307+01:00','2025-01-30 19:01:43.553264821+01:00',NULL,'100.64.0.60','fd7a:115c:a1e0::3c');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-05-17 19:36:55.859473496+02:00','2023-05-17 19:36:55.859473496+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(2,'2023-05-17 19:36:57.059073465+02:00','2023-05-17 19:36:57.059073465+02:00',NULL,'user002','','',NULL,NULL,'');
INSERT INTO users VALUES(3,'2023-05-18 10:10:36.248939077+02:00','2023-05-18 10:10:36.248939077+02:00',NULL,'user003','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2023-06-10 09:06:13.920718561+02:00','2023-06-10 09:06:13.920718561+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(5,'2023-06-11 19:58:32.371218434+02:00','2023-06-11 19:58:32.371218434+02:00',NULL,'user005','','',NULL,NULL,'');
INSERT INTO users VALUES(6,'2023-06-17 19:39:53.031565686+02:00','2023-06-17 19:39:53.031565686+02:00',NULL,'user006','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2023-06-20 11:35:09.325846831+02:00','2023-06-20 11:35:09.325846831+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2023-06-21 22:47:48.196234382+02:00','2023-06-21 22:47:48.196234382+02:00',NULL,'user008','','',NULL,NULL,'');
INSERT INTO users VALUES(9,'2023-06-22 08:30:35.068995572+02:00','2023-06-22 08:30:35.068995572+02:00',NULL,'user009','','',NULL,NULL,'');
INSERT INTO users VALUES(10,'2023-07-03 10:18:32.123226+02:00','2023-07-03 10:18:32.123226+02:00',NULL,'user010','','',NULL,NULL,'');
INSERT INTO users VALUES(11,'2023-07-03 10:18:37.130387602+02:00','2023-07-03 10:18:37.130387602+02:00',NULL,'user011','','',NULL,NULL,'');
INSERT INTO users VALUES(12,'2023-12-15 08:05:06.013615212+01:00','2023-12-15 08:05:06.013615212+01:00',NULL,'user012','','',NULL,NULL,'');
INSERT INTO users VALUES(13,'2024-02-03 16:32:42.224977233+01:00','2024-02-03 16:32:42.224977233+01:00',NULL,'user013','','',NULL,NULL,'');
INSERT INTO users VALUES(14,'2024-05-03 10:12:38.220973042+02:00','2024-05-03 10:12:38.220973042+02:00',NULL,'user014','','',NULL,NULL,'');
INSERT INTO users VALUES(15,'2024-07-26 08:08:40.979783263+02:00','2024-07-26 08:08:40.979783263+02:00',NULL,'user015','','',NULL,NULL,'');
INSERT INTO users VALUES(16,'2024-08-05 17:32:02.878091894+02:00','2024-08-05 17:32:02.878091894+02:00',NULL,'user016','','',NULL,NULL,'');
INSERT INTO users VALUES(17,'2024-09-22 15:48:00.287392203+02:00','2024-09-22 15:48:00.287392203+02:00',NULL,'user017','','',NULL,NULL,'');
INSERT INTO users VALUES(18,'2024-12-10 13:55:11.256977421+01:00','2024-12-10 13:55:11.256977421+01:00',NULL,'user018','','',NULL,NULL,'');
INSERT INTO users VALUES(19,'2024-12-17 14:57:58.550971236+01:00','2024-12-17 14:57:58.550971236+01:00',NULL,'user019','','',NULL,NULL,'');
INSERT INTO users VALUES(20,'2024-12-17 15:02:08.053169491+01:00','2024-12-17 15:02:08.053169491+01:00',NULL,'user020','','',NULL,NULL,'');
INSERT INTO users VALUES(21,'2025-01-28 15:57:32.774456057+01:00','2025-01-28 15:57:32.774456057+01:00',NULL,'user021','','',NULL,'','');
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(1,'2023-05-19 07:09:23.387641743+02:00','2023-05-22 09:48:18.908103256+02:00',NULL,3,'192.168.224.0/21',1,0,0);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,113 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'463a8b372963aeaca12400faa0c7ea29e9bfa3b4c59e9622',3,0,0,1,'2023-05-19 05:09:19.66636462+00:00','2023-05-19 05:14:19.664224869+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'77a019cb12c0d0b9347a17ab23fa4c87983814fe36bb2fbb',14,0,0,0,'2024-05-03 08:13:55.8614948+00:00','2024-05-04 08:13:55.85782156+00:00',NULL);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:0ea01e8cd608548a171ebcedc16da73b25ec18d58861be7a6b4274eb17baf6ba','nodekey:0fcf591dc1997c1d7388a3835bd24dae48240e5b03b6a7f5f33b2e813d222bcf','discokey:ed27f0b3c04222f0d05bfbc6fb5787338275ed0e32fd42fe68c669aca0f3d7a4','desktop-54','node001',2,'cli',NULL,NULL,'2025-01-30 19:50:45.306207411+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b8f0:cf44:22c8:82d1:f79:c3eb:9144:c24f]:6142","[8e25:af1:e31a:8fcc:7dcf:be1:a3c9:ed6a]:38766","[37a1:215f:bf3d:3fb1:6399:f7cb:4048:3ca8]:51666","137.242.125.72:25376"]','2023-05-17 19:38:13.531518257+02:00','2025-01-30 19:50:45.306340015+01:00',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(2,'mkey:1e274f40556282a5bbab04b6754985233ccdf971b663e5b38fc027035e833e9a','nodekey:5b16c7e14191ca2e57eccd86ec636db605fa5dc2c8856be5fa7f9b087cf24890','discokey:5fd2f116700fd48ce06e35e8dd11c847ccd7694e01ec4b3f6ef25f67c14ee197','email-21','node002',1,'cli',NULL,NULL,'2025-02-05 17:24:25.870524261+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5aae:55d1:7b5d:628d:bc07:b3e0:eca2:836d]:13912","[5583:8a0e:1564:ac5b:98ab:59a3:126:cba2]:35537","84.23.188.83:48876","44.184.117.89:36643","90.223.136.253:7056","[e43c:be7:7f4e:8217:a009:7f9d:a510:1af6]:18872","[3a86:865b:2f4c:f3b7:88a0:4aa2:f05d:c3fd]:47680","86.50.30.30:18216"]','2023-05-18 10:09:21.757289398+02:00','2025-02-05 17:24:25.870620505+01:00',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(3,'mkey:4405716e66f6a07a8fea90183cb078a8b87108aef23965b1c65f51375f3882d3','nodekey:96f979ded4cf1a02655d0b9069fb14e04d2da09c182624313acccf8c7f6b67a4','discokey:f0f4a89d7893303e1a336c9838c9a55b36a5215da006fccb72c237a794f4c5ea','email-51','node003',3,'authkey','[]',1,'2025-02-01 06:03:00.282713364+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7cd1:a579:7ddd:ed37:5f70:5783:8e09:1968]:5323","110.83.0.14:9543"]','2023-05-19 07:09:21.399903526+02:00','2025-02-01 06:03:00.284151738+01:00',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:9cd192ff56bc94ec9439083852bb541469d6725e6cda7a2aa624df6e8c8c380d','nodekey:ac53dbdd1bb1c2a36a1dde021e8f5f33d2cf01ef2892fe74853e945b9a08fda3','discokey:57cae29ceafb73857b478955a77927ff5bd8f38c313a869be093f92c6f6303da','email-15','node004',4,'cli',NULL,NULL,'2025-02-05 18:08:25.40794648+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2421:d8be:14:6b5f:7fe:56a8:54b6:8d58]:25207","[20b0:e4f:96fd:1cf3:5d39:ad75:6b8e:d0ce]:51455"]','2023-06-10 09:31:51.940506933+02:00','2025-02-05 18:08:25.408568806+01:00',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(5,'mkey:7f9c690aab22d9db060086ea375d86924359210816ad562dab2db804ad3434c0','nodekey:88fe0bcd504fd98c35a71484820dbf7b91c1704b9d29c0c7950ce5ab06ef2d17','discokey:fbaef49f1a2c61469168a9e81ee6c5bd49a777048288975a22c0f253aa14e2e3','web-24','node005',4,'cli',NULL,NULL,'2025-02-05 18:06:41.054161543+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["186.84.191.82:2621","[c9d0:4e15:513a:171b:9911:f9a0:cccf:cd83]:24151","66.84.158.199:63451","47.94.115.240:6677","19.74.30.92:1284"]','2023-06-11 13:56:42.694329408+02:00','2025-02-05 18:06:41.054829684+01:00',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(6,'mkey:00e154160e4bd8db73f2707c7a5b2f0bae04f3e26427a1aca5b0dcf2dcc1872f','nodekey:4f61b1414dd622304d407a7b4812640f774247f0c3d369a2292e3f4e88383c17','discokey:1028826beface553dd6ea7e553cc63ca59fd529716cb639981d1aa2965ed8885','laptop-48','node006',4,'cli',NULL,NULL,'2025-02-05 18:07:48.852563038+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["220.204.45.94:59135","187.96.173.136:34092","[fece:76ed:4c23:1e89:f225:97a1:94be:b5c4]:33472","[e1e6:a14:535a:668b:698:f125:543f:b5b7]:31740","[b8e3:18de:5ece:3e24:8bbf:1cbd:d27c:7de]:53522"]','2023-06-11 13:57:44.975695604+02:00','2025-02-05 18:07:48.869613078+01:00',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(7,'mkey:69a5389410061b4c336c1f337ae3ccca903f729ff249b6f1e556dcb9d9a3b7eb','nodekey:54c0d87c263afc07b7a3bb5569f8d6b67c58fecdcabefcbe7b8057e91e573a31','discokey:765930463b973ddead698512fe882cbe5e13885d14d44808596600efbcf5303f','db-22','node007',4,'cli',NULL,NULL,'2025-02-05 18:08:07.927513966+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9b54:61a6:c678:edac:956f:741e:5e2c:9ec9]:17930","[cd3f:af1c:fcb4:bcb3:806e:adf4:3f3f:ab36]:58513","[7a83:6a84:9f15:ba1a:9671:3d54:2e31:d5e9]:64893","167.223.65.194:6907","[debd:ad2f:ae50:cd14:9cd2:b297:bb94:d03c]:24266","[489b:6c59:1877:6215:ddc8:57f8:78dc:321c]:3025"]','2023-06-11 14:16:56.951313537+02:00','2025-02-05 18:08:07.927964234+01:00',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(8,'mkey:3fa0a7da3e9f0eecb11b442d911620b629981f5eb3f4ee851256a55b7252a1e7','nodekey:1912a3b843ba973c55b449fb0e1e01faff114b440e7bd1ca8b9af3be0cc56762','discokey:0d4f62fb22a9ab554a8983123cc118ec17b9d47c97d1d84bf082c90f82fe267b','lt-35','node008',5,'cli',NULL,NULL,'2025-02-05 18:07:59.389906976+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["124.104.237.237:47957","[b9f9:eec0:d656:cd83:8595:46fc:b677:6ade]:17494","126.251.133.86:44347"]','2023-06-11 19:59:30.401970393+02:00','2025-02-05 18:07:59.390393378+01:00',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(9,'mkey:dc84e5b1cf58ec8f7200ec0a655c1d5843c520ea59aa7ddd111ad5c9beba9bd8','nodekey:3c06f5a6d7f267023044ab632892b51f5af1ce4d84f0739e88823bc22cda6c57','discokey:3c1aa008a7811012038cd6658b6f290b3d252074c47d23cf1766f878340a30bf','desktop-75','node009',6,'cli',NULL,NULL,'2025-01-31 13:55:16.93378169+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["187.166.20.165:11208","78.47.168.253:34957"]','2023-06-17 19:40:45.468789461+02:00','2025-01-31 13:55:16.976650183+01:00',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(10,'mkey:2325e928fb41b3a3815b7635223411100ba10eba8ea1b442838b40da35379ec9','nodekey:8654f75dc553fbb381f57fd3f8669b5c2572f65d97989d0a69c3b294bb8cc685','discokey:24037160babf3208537006968c9f47ec3e689b1873796a787eaa44fa95afd986','desktop-46','node010',6,'cli',NULL,NULL,'2025-02-05 15:46:53.720788609+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[97a8:bbb7:9bb9:aa2b:e449:4d57:4a65:3561]:17392","151.97.159.85:8120","[69bc:fe73:f6c7:31b2:bc4f:1a95:4676:201d]:4806","[d794:c918:b0e8:6023:d7cd:709:79eb:23f7]:56801","113.147.88.203:61138"]','2023-06-20 11:18:35.905417341+02:00','2025-02-05 15:46:53.721181098+01:00',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(11,'mkey:4fb69f4bf77b8159e4814764398e6cd3bf2067b3fd4eda0eacc443ec299fcde2','nodekey:cebae8af02150eeb54b67f2cadc33dda38a98c94cfec05c1f378bf130007e946','discokey:fd5c9fefc960538a070c2bddafd53c3f890c561e02b62218e4aa8e6ae38cbe4f','email-12','node011',7,'cli',NULL,NULL,'2025-02-05 15:58:04.837157467+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d86:4301:d7d:7706:8b4a:86bf:19cd:1d6]:55529","151.169.147.218:56573","[9e9e:2802:ebb9:ba03:a564:7999:7137:65e3]:52919","[ede2:462a:f99c:24c3:b1b5:8b97:abe2:3ddb]:65141","[dfe7:6f6b:a382:4fc:a3f6:eb9:9ebc:5798]:1474"]','2023-06-20 11:35:15.063855316+02:00','2025-02-05 15:58:04.83726028+01:00',NULL,'100.64.0.11','fd7a:115c:a1e0::b');
INSERT INTO nodes VALUES(12,'mkey:5e192b1b323439fcc3b921c4f523ce9b7cce867220bd092d23be2451ce93a4a5','nodekey:1452cb2c8f26c8988cd8d8ed42957c78e3ab922bdf9773978c853e4254e23fbb','discokey:b7b41dc5de1fdcc4bd609dc72f79d27269367dbf72ab73ab61e998aa31eac6a2','web-19','node012',5,'cli',NULL,NULL,'2025-02-05 18:07:24.629305293+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["60.5.210.145:1193","[5698:e318:b38c:4331:5152:c2df:743f:8ead]:34839","33.51.84.119:46756"]','2023-06-20 18:22:35.061914624+02:00','2025-02-05 18:07:24.630116588+01:00',NULL,'100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(18,'mkey:f11332335d9f1f9d4bfc8cf9bf4edc0c958d4e4364b7dcde3c67d847f7d05edb','nodekey:e97d97a2751ef3533818907c9f24acf3270e3824f2294bb9a36d60ca196e161e','discokey:412b0eee00b68721d9169fc81039b9cda6cf57143e4cae8f7c417db15b83411a','web-18','node018',9,'cli',NULL,NULL,'2025-02-05 10:23:02.664643604+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2acf:3f32:1763:5d21:88a:4af:8779:1b1d]:36283","84.177.251.38:32968","[3138:83c6:ae09:a073:7888:71e0:494:3863]:59700","191.156.96.176:5489"]','2023-06-22 08:30:54.08720463+02:00','2025-02-05 10:23:02.664955259+01:00',NULL,'100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(19,'mkey:157706346bfe3502b6e24a84efa59b1a151be08f5a260ff96c72a734c1da1390','nodekey:139a99de286f52c55bdd61e932827c9d7cb84101a698df3576bdffbeedbf654d','discokey:293abc1a1cf2921e7961f5753cc39097956648bab47879791afb12ea03a4e6dd','lt-42','node019',10,'cli','null',NULL,'2024-08-07 09:35:12.220368767+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ce0f:9f05:96dc:a47d:edcd:1c25:f578:7551]:30363","[cc06:9c56:919a:2341:4ef7:7f28:c8ca:2a5c]:30788"]','2023-07-03 15:18:03.829428454+02:00','2024-09-18 16:15:14.037990869+02:00',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(20,'mkey:e4713082f1a4d5e2f5ca126b95eedc7ce673782a871afde980a74aa98e31273a','nodekey:3957decaff55af98415799c81e6cec28edc377d6e2a9ddca3c909c26bcffd45b','discokey:9e8360b263f67dc8d5dea9d37f023ebbbb8882f265f6ca43f5923194d7931609','db-08','node020',11,'cli',NULL,NULL,'2025-02-05 08:11:36.462419884+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4692:f8a0:842b:c26a:e549:1f3b:6795:964e]:31064","207.187.74.99:12216","63.3.67.150:22907","[77ac:562:7c4c:438a:6ec:be48:743d:47b1]:11349","[33cd:731c:f110:9b45:66b5:de81:1daa:757f]:5997"]','2023-07-10 12:40:34.838579199+02:00','2025-02-05 08:11:36.462522474+01:00',NULL,'100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(21,'mkey:2894a7babdc030bac1e4ec0e14aa4b6b67ebe382a1773e0ff4aa8b16ecd443a3','nodekey:1e219f3cc03eaa868018b9f6870d108317c31760fdc38ad4bec7200d58379f26','discokey:a81e998383baa23adb3e1e6757ef0c4b960095022f00b500b57f53c6147c71e4','laptop-48','node021',11,'cli','null',NULL,'2023-11-20 07:19:19.447470862+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[736d:a0a:e343:6b2c:b48b:7510:ace2:edc]:60377","82.193.154.129:23713","[68:80fa:7b30:3a0:d1fb:3e89:2c73:256b]:30308","[ad42:3917:5edb:3e85:732:1c71:a19e:9fe0]:11799"]','2023-07-10 12:42:43.290469734+02:00','2024-09-18 16:15:14.03886353+02:00',NULL,'100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(22,'mkey:9ab69494a274cba5b22cbcf35b3ada57d4b3d2ee03930a456f80fb34dc69064b','nodekey:0345912b4e39cd9d03dec55edec6fba7f8aca631312884b49538550475332182','discokey:a2c1be2ae50af07e5b96b0a3ee2d3a1b0148fbfc5c1a283bc787e31410d6f74c','web-51','node022',6,'cli',NULL,NULL,'2025-01-31 13:55:08.655562681+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["9.237.225.227:64622","[46a1:e1e6:6b82:6599:acc7:2273:afea:f09f]:38018","93.129.193.97:13477","184.41.32.72:1026"]','2023-08-05 12:08:48.132161695+02:00','2025-01-31 13:55:08.655891626+01:00',NULL,'100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(23,'mkey:d1b90c1c72090d082067c2dfbf287f26510b58519bbc5113f1ca63ad3ef20b96','nodekey:2d0d6f2300d295c8f91d0b954d733a2f8c4106595070d3efc6eb709df09591f6','discokey:87ef4543866a337716d7d5021346b82bbbd1aab14c36deadf96b4c38718e8cd1','srv-45','node023',12,'cli','null',NULL,'2024-12-07 19:25:56.935152754+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[79e6:8519:803b:6054:5c13:9069:8dfa:1dcd]:45055","30.154.162.65:53795","21.107.170.69:30767","212.18.227.41:50735","[f774:e89b:980f:975d:fd3e:93f:a9b5:2034]:46054"]','2023-12-15 08:05:56.592241745+01:00','2024-12-07 19:25:56.935317645+01:00',NULL,'100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(24,'mkey:f10b7f9f385e48dc99ec0944b8a04ec4d3e5613587419c134440121fa747ee75','nodekey:9559349d25dd3fa88b9595cb4ccebeeb4712338757a209e936afe37ec2643dbc','discokey:b9a07315c1eb2e074871feebe899bd2ecae64d98a8edf08883785130ef386728','laptop-25','node024',12,'cli',NULL,NULL,'2025-02-04 22:10:50.44476731+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9e60:1bb7:b542:2f50:269f:5ef:72b6:f4ba]:34677","159.52.2.200:7205","[5b7b:e424:ea77:aa8a:f835:d6bb:2e1f:52ea]:19152","[bb06:d322:7cec:426b:ef38:55d0:e7ce:95bc]:31597","[320d:6314:eaa2:a098:8594:977d:27b:8442]:12827"]','2023-12-15 11:14:36.765183054+01:00','2025-02-04 22:10:50.444923245+01:00',NULL,'100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(25,'mkey:84784f348b4e879e87986ef13b6f02ddef91639cd7de65540903cd846f93e1f2','nodekey:c15dc98ef47cf6f5dd52f59c22b3b6b0d8536ea5d248787a0145b45e6598cff6','discokey:c14e1be497f1423b4f4aa799f8ee907307eec987a1c3f7e32d4adf215fa731c6','srv-70','node025',6,'cli',NULL,NULL,'2025-02-05 18:05:52.512447937+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[23d7:1ab8:8bd1:10f3:a4f7:bd70:7803:773d]:50718","[3200:76c9:dca8:d60:e5d6:868e:a264:3efa]:33138","[975a:978:5cfb:5e5a:1b6:d272:a1c1:50dd]:3245","[e6e4:7cfc:9ce:b47:62f5:b64e:d2e4:9015]:42369"]','2024-01-05 17:32:40.940566279+01:00','2025-02-05 18:05:52.557755672+01:00',NULL,'100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(26,'mkey:dba47da985e4770a27031261b989e24ddd437983652bd1f96cc520ed78c5fc0c','nodekey:3c36d35f3e9ec98b36741e5973d8f5542fd82503a1752ad9e20545fb6be984bc','discokey:b30567e26d2fae861e566c4081179d8c72f9e659521dd7e6afecb3fbaaeae63a','db-02','node026',6,'cli',NULL,NULL,'2025-02-05 18:04:25.764764072+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["192.175.239.121:921","98.153.121.140:5003","208.68.161.128:56198","163.42.128.241:47535","49.160.22.202:42427","[1526:e34a:8857:394e:bbe0:c043:4b37:68d4]:5245","32.31.195.128:7039","[c50a:ec:e2e:e109:3a08:f56b:2928:4921]:61265","221.147.144.138:44737","136.208.142.64:41091"]','2024-01-05 17:34:19.811670479+01:00','2025-02-05 18:04:25.765166307+01:00',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
INSERT INTO nodes VALUES(27,'mkey:73868242348c7d709b77f52963c32eb4b95c8b6f89abb5db76bd95cdaaa538b7','nodekey:2de3f421f78de3f5cfd824ffaa80cf3fde3060bc42f51c2ee2f55b49fd5fbe20','discokey:5ff3b0ad430ee5530c972ecf0d3e69f25eecdadf6ef8a309b3841d7aaa6f70d4','web-56','node027',6,'cli','null',NULL,'2024-01-16 14:32:21.570104175+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a2b8:ea55:f9e3:2c00:f423:8c56:7fec:c617]:53793","[ed88:2277:3c9a:4f64:a25e:5b41:a3ca:e904]:27852","[d203:40a2:5efc:4a42:8910:81f8:59c6:4d8d]:23389","187.126.162.12:25054","[5d8b:9391:47f1:1bbc:e01:92de:4a90:7614]:42410","172.81.188.131:23453"]','2024-01-05 17:48:25.466030859+01:00','2024-09-18 16:15:14.040766068+02:00',NULL,'100.64.0.22','fd7a:115c:a1e0::16');
INSERT INTO nodes VALUES(28,'mkey:300a566a21fcaab2665dc091300e2c5110dcaee25e2fcc4cc23b011fdae471e6','nodekey:8e36531b406e0b7b9c1b9abadc00626ccc8c6e7a0c37f70f42ccf06cd2dd03fa','discokey:a4134738054f6fc0c57b6eb47913e68a3f47ffb81af8a3496754921c2fcb02f8','laptop-98','node028',7,'cli',NULL,NULL,'2025-02-05 17:14:09.968775535+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["113.143.9.36:55432","[e266:66fe:4929:3831:7830:6f10:1572:20df]:9977","[afe5:7d57:fac5:a1c5:78d4:ee33:d474:1e56]:52223","7.208.95.117:299"]','2024-01-15 09:34:54.847632697+01:00','2025-02-05 17:14:09.968981413+01:00',NULL,'100.64.0.23','fd7a:115c:a1e0::17');
INSERT INTO nodes VALUES(29,'mkey:6d3edcfd40971c25174fa55eeddf76d05447d7d28f216c6118d8d6e35aa1ae89','nodekey:4b7d7ef564535f114a410c384aa3eb95103b5895cfd74962c7d37d3a8b0bb6ed','discokey:569e08cefcaec4d1312b70c41c12d82b26712965cbab41ac3ca5db857274ba46','web-76','node029',7,'cli',NULL,NULL,'2025-02-05 16:04:20.309612735+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[24c5:f1ec:38a5:5a2d:7224:b76b:cd04:e6d2]:63943","162.176.178.140:46577","[4f52:1708:c0a:7991:9c16:bd7d:4045:195d]:50362","[fd0d:f112:f642:c343:ac14:8ede:dc04:e2d9]:58412"]','2024-01-15 15:18:12.2871978+01:00','2025-02-05 16:04:20.309824144+01:00',NULL,'100.64.0.24','fd7a:115c:a1e0::18');
INSERT INTO nodes VALUES(30,'mkey:edae4836dee6e165a4201e0d106fe5db539aaefd4fa95e6f660cb16457bab645','nodekey:59e8b5e492cdce7b05498db07e621fd6f326f8a6141751bfda409b2e1e5e56de','discokey:bb6fff0c0615c5aeb083d7175b6838f6c2cd22634ff3717cd227063709e243c6','laptop-44','node030',7,'cli','null',NULL,'2024-02-05 12:14:40.065688294+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c204:d59b:29a8:ac18:75bc:1a4a:755e:a8f2]:26579","35.41.214.64:38835","143.202.189.84:43171","[8679:8c46:1c66:cd1e:95f8:2b0a:503c:819b]:57389","107.115.138.42:41616"]','2024-01-15 15:21:43.217136004+01:00','2024-09-18 16:15:14.041757308+02:00',NULL,'100.64.0.25','fd7a:115c:a1e0::19');
INSERT INTO nodes VALUES(31,'mkey:fbebb2c69f263a519c8902463ef9c7db0597109fae5730a222f1c6567278bc86','nodekey:d83666c0acac1a9cd306cb884a1ce24adaabbc2102eb553ef5514ac5ea1714cf','discokey:6f4280bcb38ac995d22543db32230d8f22f2c0a0dc5efe2d86c7361c897ae812','lt-82','node031',7,'cli','null',NULL,'2024-02-22 08:35:27.098819037+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4327:29dd:a02:fb00:9645:d497:8ffc:4a68]:26342","[5d4a:a2f2:16c7:3d3a:a2b8:2962:30f9:3407]:5279","107.140.203.49:9365","[1660:741a:160:67c9:7972:5f9d:14bd:ee53]:21178"]','2024-01-29 16:05:35.338524634+01:00','2024-09-18 16:15:14.042191514+02:00',NULL,'100.64.0.26','fd7a:115c:a1e0::1a');
INSERT INTO nodes VALUES(32,'mkey:8c468799222af319e17ec309dbbf3a87fb6d924a1cb17e5a0bd7e027fe3bfe5e','nodekey:3c7d82f4a44cfa1469b957ac911e8506a68962fb2583d2afaf3e8a621c0c4aca','discokey:ba179b51f3540e619eaac9a6d4bc67403daa7c3cf28a6b579087cd6d284501b4','lt-53','node032',7,'cli','null',NULL,'2024-04-09 13:59:43.37062537+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d21f:d7bc:f690:e3ba:82fe:8122:c33d:5a86]:227","10.67.113.92:45634"]','2024-01-30 10:41:58.31917869+01:00','2024-09-18 16:15:14.042506082+02:00',NULL,'100.64.0.27','fd7a:115c:a1e0::1b');
INSERT INTO nodes VALUES(33,'mkey:be7f190677fd0cd1c5e78b4ae5b02a1738dd60be7d9a41017000b22ae9636af4','nodekey:a404e578d3edd3e3d879e9f1946c859b5982c59f5e528bf6b987bd55de00b25b','discokey:ad3013f116c370866fc9134b66999bb05e2dc10a8e2944230c3d9893c0a94c67','lt-80','node033',13,'cli',NULL,NULL,'2025-02-03 21:25:19.620235627+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[af8:f5e8:32f0:75ee:d351:c0e9:78e:93d9]:12624","71.151.27.31:51063","[f0d6:21dc:48f5:63f4:daff:a3c4:7d60:51ea]:17286","[38c5:9551:f6ed:b087:91ba:bef1:771c:273d]:62171"]','2024-02-03 16:33:26.706408143+01:00','2025-02-03 21:25:19.6205373+01:00',NULL,'100.64.0.28','fd7a:115c:a1e0::1c');
INSERT INTO nodes VALUES(34,'mkey:7784df3aabe1ca1edab5270028fb3cae8b66cee2384790d06969d1e6e298520f','nodekey:fd8e939fd6db8caf6623ac3d73c12ade4da110d8c1f29e3a3ee0d2be0c526915','discokey:59aff4582e00d92260e6a90d6d0da3d818fe8f52c081c8b65e18006ef8269ebe','lt-65','node034',13,'cli',NULL,NULL,'2025-02-05 17:49:20.10044606+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["71.155.69.236:8707","125.2.67.155:50785","32.6.80.181:17295"]','2024-02-03 16:42:32.683785672+01:00','2025-02-05 17:49:20.100741067+01:00',NULL,'100.64.0.29','fd7a:115c:a1e0::1d');
INSERT INTO nodes VALUES(35,'mkey:ad3838fa63fb120ae8d3e47d4bb6bb4009e7fc5d91483d1ba7417d0681fd7162','nodekey:b10ddbdcf826d79049d74a7d4ad036b499c86f7daf786bb1a9b295366b57afe8','discokey:618ef629d3bd261964c613ad3bc45e6278fa274d734c8cd2d3396cf8c9742d88','web-33','node035',5,'cli',NULL,NULL,'2025-02-04 17:50:49.267594119+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["169.159.71.157:18240","[bbb7:5b4d:218d:55ff:ac9b:1fb6:c933:9a55]:63943","18.156.132.228:63356"]','2024-02-03 16:51:52.010016072+01:00','2025-02-04 17:50:49.26844864+01:00',NULL,'100.64.0.30','fd7a:115c:a1e0::1e');
INSERT INTO nodes VALUES(36,'mkey:c536a3efc460fb2da4c4775e2b51d0c84f001dc46a4d902429e74e97b2d3c6d4','nodekey:91da2acfa3d7f7c7b0c1a2d952ee527514504fddc504809423762203a16145ab','discokey:989ff5f21d485dcb6312fade38c9047bbde1fbce46bc29ac5f6afe00610ad215','laptop-46','node036',13,'cli','null',NULL,'2025-01-19 14:01:48.956567669+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4017:a243:61d0:b302:7860:18f:7d4d:f605]:28633","[e5b8:6c78:ce2f:cf6f:13fb:401f:8223:3f04]:54121","38.137.88.247:35801","[eec2:61c0:e20a:2fa0:5e4d:56a4:5071:881b]:36628","[b8c2:c792:3329:2c93:f94b:a948:7d11:b9f2]:908","[5925:353c:bd9a:f42e:1916:45b4:c170:e515]:18400","[c2a5:cc2f:e2e8:573f:7b01:4aa:8a1a:fd71]:32146"]','2024-02-09 12:34:57.879970954+01:00','2025-01-19 14:01:48.956830267+01:00',NULL,'100.64.0.31','fd7a:115c:a1e0::1f');
INSERT INTO nodes VALUES(37,'mkey:142e67963c9045164df7b33af6d2149d72f59527df44fd75221647281444cbe7','nodekey:a3a2cd2bd0c3a1f783d0391ea1951c5c9226ddca0f18130b77fccff8b874d694','discokey:bdb788f8825b9bd816f37dcea882920382c7feb143edf0a6baefc9015774d8aa','lt-24','node037',5,'cli',NULL,NULL,'2025-02-05 18:06:12.650485457+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c31d:dd18:321:589:11fa:d85b:695f:1fca]:43064","168.4.78.117:48474","90.45.218.0:29326","90.233.46.138:29846","8.137.133.59:22781","[cb5c:f8d4:ccb0:8333:8ec:170c:a2b0:941d]:26248","[5802:df5c:8853:4851:6dcf:cb83:8208:d143]:24568","48.38.104.41:43702","139.100.200.227:62546"]','2024-02-27 12:14:40.452601042+01:00','2025-02-05 18:06:12.651261596+01:00',NULL,'100.64.0.32','fd7a:115c:a1e0::20');
INSERT INTO nodes VALUES(38,'mkey:6829f2d5523aba7a27c31e59e2341f3feb5a5a72a0268ef10d23c39811ea3b53','nodekey:10e4ff66fdd37fb54f6dcb0e42f483a15b6340610acc3a4517c24f0f350b5a9a','discokey:f20786f9c7edc967d0b415bbcce39468441af3b531ff15656c0683d3f328720a','lt-88','node038',6,'cli',NULL,NULL,'2025-02-05 16:57:29.735032128+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a393:f17f:6728:82e4:c1e7:2367:82d0:daaf]:18560","[d192:9897:4cd7:bfb5:de36:fc03:8cf4:c60d]:25096","212.199.67.213:11150","64.251.26.199:56246"]','2024-05-22 08:08:16.045350656+02:00','2025-02-05 16:57:29.735397461+01:00',NULL,'100.64.0.33','fd7a:115c:a1e0::21');
INSERT INTO nodes VALUES(42,'mkey:374ff35e7639239dbd6f70c03d04025febb0a7050cfa9d065dfb17233d200b06','nodekey:46ee597a17ca7641b7e450e55eefbfe243413ca76dc9c8e1f9d5df6e00e5abb6','discokey:f258814fe446b9599b1e601a6d51f85ba03cb6ee8154c64c5df9c7101cd34291','db-40','node042',14,'cli',NULL,NULL,'2025-02-05 06:03:02.17883855+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["109.16.250.249:16050","[5ea4:3410:eaa2:9da:b8d:b61a:2d9d:edaa]:3526","209.107.206.184:46974"]','2024-07-03 11:12:29.418355657+02:00','2025-02-05 06:03:02.372767209+01:00',NULL,'100.64.0.37','fd7a:115c:a1e0::25');
INSERT INTO nodes VALUES(43,'mkey:1099debb0ba187ef1f43f001c75abc118eaf017bf3bd6b48ca333fb046b98de9','nodekey:d49ef9ad4a7ecbdabcd24cae92d9ac32fbb765467cbc20abe61b4bda6ef15f1f','discokey:9f2faf39514eccb7f3d7d66ebcaf804474f75284d8b1aedbf97aee6ccdf47ed5','laptop-84','node043',14,'cli',NULL,NULL,'2025-02-05 06:03:09.741784038+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[183d:f2d6:b80:36c5:318e:64e9:7f4a:b389]:12440","169.173.198.12:15274","[e5df:1889:6ac5:7d21:4dfd:614b:7eb9:d93c]:792","119.123.40.237:58615"]','2024-07-03 14:48:50.263910778+02:00','2025-02-05 06:03:09.743853396+01:00',NULL,'100.64.0.34','fd7a:115c:a1e0::22');
INSERT INTO nodes VALUES(44,'mkey:bbcd4d386de509eaa162b9e6b7ecb5896bd2af74d6dade72463343b98ecba03e','nodekey:9b6dc646c9a4595a7e073a409a79d76b2624d3516d42eb36a5a2d34f5f8fdb69','discokey:109a9fae4a89679b17a8604d4dc8a07c172187683402c999927585ea28a40f4d','web-17','node044',14,'cli',NULL,NULL,'2025-02-05 06:03:08.642240566+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[797c:753d:f8fb:3108:8b9a:2bca:65a2:459d]:6713","[699e:74ba:cb1c:93f0:cad7:784f:b43:a4b7]:19825","[acd8:3779:7b6c:3a71:c15a:e323:a721:c9a7]:63377","[6816:3377:edb0:3f8e:a65b:bd60:461b:ceb]:24642"]','2024-07-03 15:23:48.066044194+02:00','2025-02-05 06:03:08.823204997+01:00',NULL,'100.64.0.35','fd7a:115c:a1e0::23');
INSERT INTO nodes VALUES(45,'mkey:f8ddd3a46ff292d9d1c00ad78526306ae1182b38e7cfdef477c4024297683495','nodekey:37bd7c1295c38de87a979ade273598b47023217e57ce45af4b02429bcab81db4','discokey:9b89e8e84da2d01590108b6f83f4f0479abcdfac8791b5da44dd2543299de31b','desktop-11','node045',14,'cli',NULL,NULL,'2025-02-05 06:03:08.197696258+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["120.102.247.255:41936","28.177.95.32:7841","[fb23:5998:c63d:b6c4:e86a:96b2:61c:e110]:51902","[89d4:f6c6:ccf6:b19d:3b76:642e:7a36:d229]:930"]','2024-07-03 15:54:01.706018896+02:00','2025-02-05 06:03:08.241135037+01:00',NULL,'100.64.0.36','fd7a:115c:a1e0::24');
INSERT INTO nodes VALUES(46,'mkey:af6c1d228b675ff04d2584e2c23d6288ec312a6b44c5c0eed213423a11711787','nodekey:f5b21f25bb22b5cf0cedb1b643d50c3a6512ef300cc971eccccbcc500cc23408','discokey:72843a1b2564c177d8556eb0d76dda7cbe0d9f1408bd250fcc6149518eb6d5c0','desktop-41','node046',14,'cli',NULL,NULL,'2025-02-05 06:02:55.262487942+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[37a8:9998:e94e:e297:940e:5414:5549:87c7]:37130","27.138.122.133:37304"]','2024-07-03 19:38:07.783745318+02:00','2025-02-05 06:02:55.262915688+01:00',NULL,'100.64.0.38','fd7a:115c:a1e0::26');
INSERT INTO nodes VALUES(47,'mkey:c3ea2fb606807d06b1ed3e10219fee70456d1db0208d2e73a081a258992e4316','nodekey:a246b6e4b6a19ab09836e54c6fe7d5da442c2f9097ec6eea01490500872805c6','discokey:e16c22490ad1b9cbbafc0dbb4d4596f19593bf528d69bba3bb37e643aa82023b','email-63','node047',14,'cli',NULL,NULL,'2025-02-05 06:03:02.549111852+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["140.167.197.208:6850","[b895:b3f0:c9b8:845d:3f3a:e534:53b0:bf90]:2433"]','2024-07-04 10:38:08.344092869+02:00','2025-02-05 06:03:02.55637113+01:00',NULL,'100.64.0.39','fd7a:115c:a1e0::27');
INSERT INTO nodes VALUES(48,'mkey:8fede09a569258fc0fd7ebfbd12b2b4e8c2f4ce95c43ab0d89e41ab3998e6d24','nodekey:63af6498d4fb0e1e8312e3ec6a1639b178c051a271f33f213324e3ac1af53e17','discokey:a1e793aa09c20360cb4ef57e7dc42171a0abbc9f562140609e930ba5b7b12e83','email-92','node048',15,'cli','null',NULL,'2024-10-20 13:53:33.831192385+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[33c0:859c:4a78:8bdb:359e:31e4:1e71:7e39]:50383","[3aab:52a2:b9d3:1816:5627:336:6c60:57d7]:13486","22.83.180.41:14147","26.126.135.206:7777","[8706:d109:5006:f832:dca7:58e4:4451:be15]:15180","177.4.27.29:60895"]','2024-07-26 08:09:56.608302315+02:00','2024-10-20 13:53:33.831387627+02:00',NULL,'100.64.0.40','fd7a:115c:a1e0::28');
INSERT INTO nodes VALUES(49,'mkey:13b8d4cafbdb8e9ab77928219aa57bf778878866ad8e6108b60aaab8dc8cec36','nodekey:17cefd68f8a9cc20b3d4fd93598f77ddfd6bd5a7e6e4b49861f9faad8623e0ef','discokey:939a04ddd2f9a24468e07ee7924dbb7a7662c1e8a1b67426f57fd48c7394448b','desktop-40','node049',16,'cli','null',NULL,'2024-09-19 09:07:18.28136023+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[19b0:8be2:708:d27f:4d3d:3c93:9979:e9e8]:50438","129.0.5.112:19015","[91e2:54c6:93fb:ec32:6ab4:186d:81cb:b815]:37323"]','2024-08-05 17:32:41.937626584+02:00','2024-09-19 09:07:18.281618912+02:00',NULL,'100.64.0.41','fd7a:115c:a1e0::29');
INSERT INTO nodes VALUES(50,'mkey:03979d5446bb3f596bf0234d81ca84482eacb132e874ceda6cc2703422cd728c','nodekey:805c03cada525f14ee90d28ea02b23a3f57b470c793314872ad9daacf6c6484e','discokey:eb4135e1cc73a3c6b513d8cc04ca0c55a2aef7b0009845fa1d2036488aadf0f8','desktop-02','node050',10,'cli','null',NULL,'2024-08-07 10:10:06.595550455+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9175:498d:64ac:4342:2eac:ffa1:99fd:d109]:21202","[5cba:56ef:db08:320c:333a:541f:605c:44d5]:57469","150.211.2.236:50360","203.180.122.83:13344","63.162.234.32:11653","[6b63:f552:f930:e22c:fc42:3b41:c5c6:6d5f]:63162","114.48.12.185:47837","[2964:cc5d:3a1b:7889:acc8:4d8:22c1:398a]:43515"]','2024-08-07 11:50:54.144157179+02:00','2024-09-18 16:15:14.050033969+02:00',NULL,'100.64.0.42','fd7a:115c:a1e0::2a');
INSERT INTO nodes VALUES(51,'mkey:5877139c52c0bf3c0fd054bd046aaf4530dd8946548a7bc1a06733649d1557d8','nodekey:553d9638c8c455e8d1bc811ea3af03db1eb3c586413447c8003e7d905a61d06c','discokey:1da883c9eff402d786362aaac2f478c835308b3acec0993e6293becf4474609f','web-62','node051',14,'cli',NULL,NULL,'2025-02-05 06:02:31.63336842+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["86.215.174.228:26026","93.101.159.155:64005"]','2024-08-07 14:19:31.156780417+02:00','2025-02-05 06:02:31.633461601+01:00',NULL,'100.64.0.43','fd7a:115c:a1e0::2b');
INSERT INTO nodes VALUES(52,'mkey:0e64072dafa5f9e49266b41fc4b21ff7d287be8f4e5f2b6c395487d632f1cf3f','nodekey:2f77bb8cbeb426bcded5ad9fc6da44b0b76b8d6759f10a8db28e634290760ee7','discokey:836558738056edd1fa8d190c7e42f120b365a48a3b1f1c96c87755bb82d7ad0f','desktop-07','node052',17,'cli','null',NULL,'2024-12-25 17:27:58.515851096+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d889:f751:710:257f:977f:5597:9908:14e0]:61162","[f83a:5ebb:911d:ef36:743c:8086:8a4c:a5c7]:23538","[dc45:365c:e426:71d7:fe23:fdd4:d2c2:9409]:57262"]','2024-09-22 15:48:41.385301399+02:00','2024-12-25 17:27:58.517153789+01:00',NULL,'100.64.0.45','fd7a:115c:a1e0::2d');
INSERT INTO nodes VALUES(53,'mkey:a6f93e99a5019b3b6a2941d95dc7fcbfea5a59317a48b99db93b7a3f4f0a65bb','nodekey:1f78a6d76ea4a2135c0da46b202560c86ed30cd7e8239d4508088d0e02ffb961','discokey:1744062452f052aba5320e37fc08aaa37f1430db7c32c94c5626f0f3c858de3d','desktop-82','node053',17,'cli',NULL,NULL,'2025-02-05 18:04:29.018269861+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6084:ee60:1697:864e:4a61:cf6e:e9b6:4c05]:63961","[fad7:2601:d286:4772:3cce:6e89:f66e:9eeb]:5430","216.60.124.11:45041","[d513:c472:d7a:f316:f610:10d0:9851:4feb]:3955","156.228.105.157:61542","102.126.185.0:50694"]','2024-10-28 10:04:50.084492941+01:00','2025-02-05 18:04:29.01861254+01:00',NULL,'100.64.0.44','fd7a:115c:a1e0::2c');
INSERT INTO nodes VALUES(54,'mkey:7ad9c5af6111cc3286256127e6b6a939f1fb87e08c9018bd7bd8671c4b9cefc2','nodekey:84fec35781c2032d05c7e8524bada9f7242165e9ab5df5d66f993266cc6f090d','discokey:ad9158862b9c58848c37b519543415166938b6be3dfe3a8463842ebbd09eb00e','srv-14','node054',14,'cli',NULL,NULL,'2025-02-05 06:03:07.205609421+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e669:9684:b8bf:9a64:8ec7:bec:6369:4412]:16090","23.0.29.75:24889"]','2024-12-09 17:10:55.363593066+01:00','2025-02-05 06:03:07.20590574+01:00',NULL,'100.64.0.46','fd7a:115c:a1e0::2e');
INSERT INTO nodes VALUES(55,'mkey:ae8c967065558f9f03a95979d2181b3aa2b3537c25a894046a65554beaf553e7','nodekey:bc9cbaeb5cd70e708b5a23565ffb1fb6e1c18f35b1861083196209dcc1e0e20c','discokey:f8647d1a8ab876931f49a8abf785d429f7f21bd1fe6317528bfbf78e38d7aafe','db-73','node055',18,'cli',NULL,NULL,'2025-02-01 12:07:16.769615426+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[caa3:7372:5199:2416:357:7b48:3127:85f1]:21026","[e2a5:db96:e7e3:6335:8bdc:90b4:40ff:920d]:28128"]','2024-12-10 13:56:39.287449662+01:00','2025-02-01 12:07:16.770515926+01:00',NULL,'100.64.0.47','fd7a:115c:a1e0::2f');
INSERT INTO nodes VALUES(56,'mkey:b3558cd3cf69119c2015a9cb0a87678b00231eb52b4a2b9ad93b92d7019c54da','nodekey:08f90ff45aa02d7e6b1c8bdca99e8560b70ffc7e3baafeffc3fee5477696602c','discokey:48a4765cbbf46b7f990fe03b6ceb2aefbd78dc18c462935109c51e2a3ba309a9','lt-51','node056',19,'cli',NULL,NULL,'2025-02-05 18:07:11.261451892+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f0ea:121a:661e:b1e0:52ec:5313:f630:8bb5]:55696","[bfb6:c553:e032:b418:f3c9:c0cd:9e44:f135]:60965"]','2024-12-17 14:58:39.429211911+01:00','2025-02-05 18:07:11.274103693+01:00',NULL,'100.64.0.48','fd7a:115c:a1e0::30');
INSERT INTO nodes VALUES(57,'mkey:5bb86c2f730c0b247b01634f73a4f67a19bf271de3ee39cf13f879db671da5b1','nodekey:64f016a04093cc91f7d2ca3639a07a17ae8f95f246a7ad759141d598136bd060','discokey:066b4845ec135e6251d6ef6119c832b46e2bc310332d3ea836c5f39896538b38','lt-49','node057',20,'cli',NULL,NULL,'2025-02-05 14:17:30.564397966+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["128.102.246.147:15968","[d0d3:beb7:361b:71d1:af88:4105:6b5f:343e]:14598","155.200.222.111:64410","[b554:3604:41e8:60a4:229:a09c:efd3:c73e]:39533","44.230.54.249:64083","29.229.203.183:13","153.68.228.171:36559"]','2024-12-17 15:17:14.26936913+01:00','2025-02-05 14:17:30.564974331+01:00',NULL,'100.64.0.49','fd7a:115c:a1e0::31');
INSERT INTO nodes VALUES(58,'mkey:557cba9878553b95245e4880d662200c70ab60ec53f2a47a48a71b5a3455bf39','nodekey:cf788f8a13f031bb446fc3f12a0120a4b0b89d8918d0ccd7a1b089c600e75b65','discokey:2ca62c3163c1aa5ef0585d1fe67ead83578f835a9ccbc86f64fc13102df0b4c5','db-41','node058',12,'cli',NULL,NULL,'2025-01-25 18:41:03.881898904+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["29.219.180.224:55412","[2ddd:7c1b:a237:41c8:3baf:e9cc:1f31:9057]:62916","[9c34:190d:7bf0:c940:18d6:f96c:9aca:8c0a]:8787"]','2025-01-17 10:17:23.455895657+01:00','2025-01-25 18:41:03.882180987+01:00',NULL,'100.64.0.50','fd7a:115c:a1e0::32');
INSERT INTO nodes VALUES(59,'mkey:63163f3f5e4b511affa1046328d92add5e5c1e8f883bc851f6853517acc11e8f','nodekey:71f9f812a4b177da766a6a93ada6de6bf41a7f143e4c1c5073704c1938b53931','discokey:93079aca00038320a7f125193e7e2b4658efd88ce24d04ba15a3da1491b8d71d','srv-82','node059',21,'cli',NULL,NULL,'2025-02-04 15:03:47.081255506+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[82b6:6c3:f2d4:e056:dc1f:57e4:7842:53ba]:4136","55.12.42.230:527","[406e:9d3a:4fca:33e7:176:4fca:4450:3e0c]:21548","[536b:bf65:da86:c7ca:ecc4:c84a:1811:334e]:24087"]','2025-01-29 11:59:27.291048957+01:00','2025-02-04 15:03:47.081635111+01:00',NULL,'100.64.0.54','fd7a:115c:a1e0::36');
INSERT INTO nodes VALUES(60,'mkey:552ca0e4c611df54a38bd150d7f6c4ef77c66625435073b3751718e44884b92a','nodekey:7b4b25d90935b79af2efc7f0499d3f16a49d5078997314de57b65fb5ce01cf1c','discokey:2118ebb5a0b1c12de379802db2b247fcbf516de56216c4d0ee7a0489dde05071','laptop-14','node060',21,'cli',NULL,NULL,'2025-02-05 00:58:59.940225737+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["67.131.191.86:14533","45.142.234.80:30901","58.251.220.64:42364","[d9a7:5288:3427:e52b:4eb5:794f:11d2:5d6b]:33898"]','2025-01-29 12:01:57.48748166+01:00','2025-02-05 00:58:59.940897467+01:00',NULL,'100.64.0.55','fd7a:115c:a1e0::37');
INSERT INTO nodes VALUES(61,'mkey:f5eaa64ce3d0dbd7539fd9c3f9a494688a4a64b9a3d1fc0b9f40dedc14192ba8','nodekey:ccd6aadf68fdcc95d0d15f6654a0c6bfd5ebbf282491539ee63e5b0848de9ef5','discokey:a492c6d1d0b9de44f6adcf7ac919d49c269058d301b4be21fbb5bf4203b2fa8b','db-97','node061',21,'cli',NULL,NULL,'2025-01-31 13:55:16.761715226+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d002:74d:2b8b:87bb:25cf:5512:50fc:e379]:46829","206.194.47.198:21677","22.203.32.217:28664","112.239.138.73:43954"]','2025-01-29 12:03:01.464646336+01:00','2025-01-31 13:55:16.762309571+01:00',NULL,'100.64.0.56','fd7a:115c:a1e0::38');
INSERT INTO nodes VALUES(62,'mkey:4cbd491b0977f3a8cc92ef9f20a7726b3984f3c0699429ae46a0bceec5febee4','nodekey:66a7e77700fb0f4bae5b282413bdb5ff7c375549dd85c4300c73ff3d8029b4a4','discokey:2e9034fc43993eaa0cf2bc21118d378bb02afb3d197a33cf9f0dd201d176b23c','web-06','node062',21,'cli',NULL,NULL,'2025-02-04 18:18:13.742833978+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["81.51.60.60:63220","12.64.198.119:51541"]','2025-01-29 19:23:14.092804852+01:00','2025-02-04 18:18:13.743206432+01:00',NULL,'100.64.0.57','fd7a:115c:a1e0::39');
INSERT INTO nodes VALUES(63,'mkey:4f53e8f17a458333f6c3baa9c54246a6bdf6b9b431fda11cb4982aaec8da44e3','nodekey:cfa7416a7c22869f6875a73cb68c5e71afa3efdba93aa52d97d0d5ba546a3e43','discokey:66b691bca43b231ad1ebfed80944bb4a78150b16e99a6bab48c530ad2573556c','desktop-44','node063',21,'cli',NULL,NULL,'2025-02-05 18:07:10.372444037+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[62ed:996a:ea86:6865:c4ee:753b:e387:5fee]:19029","105.95.65.117:11546","[68bb:e8d1:72d8:8b02:608b:2284:c9b3:184d]:20876"]','2025-01-29 19:41:40.535299057+01:00','2025-02-05 18:07:10.372725767+01:00',NULL,'100.64.0.58','fd7a:115c:a1e0::3a');
INSERT INTO nodes VALUES(64,'mkey:3e0dcb286f6e19b1e3a0b5330978aa8a8d710934cc754e811d0f690046e04469','nodekey:cd2d301b9b163b806fe8d63cdd07004f26559706bf7dc782645f05e12ebe0ec3','discokey:14675666cf2b55697f0032897d1c6742413d7c24bada8cfdc6246bf150d06fc7','db-76','node064',21,'cli',NULL,NULL,'2025-02-05 18:06:48.587173709+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["74.32.222.198:59615","145.91.193.5:37126","[2fb6:ea0a:3639:a1cd:9075:a258:6a79:4f5c]:13944"]','2025-01-30 18:18:57.519126133+01:00','2025-02-05 18:06:48.587847966+01:00',NULL,'100.64.0.59','fd7a:115c:a1e0::3b');
INSERT INTO nodes VALUES(65,'mkey:1adfdd6ba590feffc711c40506ed5ecb16609cd6e90a536d50c5f54cec223508','nodekey:0d58cee32d99cde76b3d8769ae4605cb4bfc9cbb01fc13069c8b59faca320e48','discokey:cba00753c508df0b5cdea1e59eaa829c6cfda4f8399121307f931dbaa3730296','desktop-90','node065',21,'cli',NULL,NULL,'2025-02-05 18:05:58.789731794+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["172.210.49.58:58821","[23f9:9c6d:5069:a14f:33d2:c0b1:5ab5:f83b]:46288","[b341:3259:c5dd:9f91:fd70:c616:3033:2b3b]:59081"]','2025-01-30 18:19:40.354692307+01:00','2025-02-05 18:05:58.790429401+01:00',NULL,'100.64.0.60','fd7a:115c:a1e0::3c');
INSERT INTO nodes VALUES(66,'mkey:547a8b97c8c8227d9ba40174ce4d28d0e64f10fae3f39797c60e29742ed59e62','nodekey:cb4a9d1dee6f581036b7c262348cf2c4a96be8b2eea78f7805097e3f7b1a9fcf','discokey:c233a42a4afb5fbf921bf7b3fb4330e6c46273d18570aaf6b7254dbf3c67614f','desktop-82','node066',21,'cli',NULL,NULL,'2025-02-05 18:06:09.975856526+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["21.197.131.68:13997","6.193.99.72:20874","181.248.237.50:21695"]','2025-01-31 12:05:28.65297301+01:00','2025-02-05 18:06:09.976571645+01:00',NULL,'100.64.0.61','fd7a:115c:a1e0::3d');
INSERT INTO nodes VALUES(67,'mkey:a8c1493c4f14cc5f41d2a37ee172d4871795f15df1d694e3e60cb00e85753133','nodekey:330d0406c86db5dad6e8c8f3aeea4a9d2e400f5979148c8dc0362c99a732359a','discokey:48d90798a39a3f18baf394f4c5470f6130e4e71b9b3537ab794729a69cb39fed','email-36','node067',21,'cli',NULL,NULL,'2025-02-05 18:07:12.217604914+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f54c:f310:c771:8240:30ba:d473:9e15:10c7]:14619","[b271:6307:9d44:59d0:49bd:4f2e:f1:367c]:65399","140.8.191.17:10998"]','2025-01-31 12:06:30.121464114+01:00','2025-02-05 18:07:12.218026563+01:00',NULL,'100.64.0.62','fd7a:115c:a1e0::3e');
INSERT INTO nodes VALUES(68,'mkey:45e8c4a1edae8a0cdcabff6034ce05d4a52d3409257ab29296f6cf3a264e83c8','nodekey:b3059cba99de1e33977250c037645ba9d16cd632437994b34684b0907fe3ceac','discokey:3c55aa60782b081dc35d241058173ee1b33b787c275cece979f7e42a5b18342f','email-71','node068',22,'cli',NULL,NULL,'2025-02-05 17:22:26.298576706+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5162:12d4:c733:e842:4621:e95e:6576:9cce]:59605","207.56.208.145:2966"]','2025-02-03 14:16:55.56431345+01:00','2025-02-05 17:22:26.298939503+01:00',NULL,'100.64.0.51','fd7a:115c:a1e0::33');
INSERT INTO nodes VALUES(69,'mkey:bac278a5ad2db26a926acc26fd63948ba6bd59f251f7cb63189686ce6ab708a1','nodekey:24a9b3c24f38b690ca357a9659d7694a2a4fc85da77fb1412eae653c644b3bd2','discokey:1146959bad3ded51876532d5bd19cb803a242cd31ec4139dbcff8253c0ad3688','desktop-73','node069',22,'cli',NULL,NULL,'2025-02-05 18:04:17.831085877+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["54.50.198.66:11070","29.172.28.99:15557"]','2025-02-03 15:23:16.312084161+01:00','2025-02-05 18:04:17.83122503+01:00',NULL,'100.64.0.52','fd7a:115c:a1e0::34');
INSERT INTO nodes VALUES(70,'mkey:70c4138967c4f507d775370eb51027481476532f60551ad6a15d7d7f409bed0e','nodekey:f7a1ee8db2e3b1d46d312fa05852ca855dc4fb1c08c661f9d6ae72cf158312c4','discokey:2ef78cf519914d9d37837930ec28165ac6ed347ea0704dc38143c6763d5e0da9','web-04','node070',21,'cli',NULL,NULL,'2025-02-05 18:07:47.934048862+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["74.194.16.233:59572","182.2.129.47:16383","[b20b:7689:a05d:fa7b:596f:af42:cc23:5379]:28028"]','2025-02-03 18:09:35.161109801+01:00','2025-02-05 18:07:47.989204771+01:00',NULL,'100.64.0.53','fd7a:115c:a1e0::35');
INSERT INTO nodes VALUES(71,'mkey:e50a34b03da2a75cc4317bd6499e8d3acc04c79a7fed05b4fc0fd9f4d039c457','nodekey:d0a2d496173e1283a1bedfb91ed66eb6c329939cdd49186fff95dbbd8793d453','discokey:e5263b334eadce0e0ec392ada8e3c2e9365c3d84c2b66e12159298a3ac1bdec9','laptop-52','node071',21,'cli',NULL,NULL,'2025-02-05 14:26:52.974125098+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a9c8:980f:e64c:96b3:b612:ecf5:c8c9:44cd]:35202","52.120.18.3:13372"]','2025-02-04 12:03:50.32663805+01:00','2025-02-05 14:26:52.974521366+01:00',NULL,'100.64.0.63','fd7a:115c:a1e0::3f');
INSERT INTO nodes VALUES(72,'mkey:4c796b98359112a863206aac0c0227cb52ff020ab4ae85f4bfe0a6d607605b48','nodekey:e7e7abfb764bef835912f27af2c65edb3c5d01f2d2ac01943b3a6f5e67cd0c6a','discokey:7890936e6fadf5482ac24097a8c38c09b767fd9bfc2e83c05501524120f869a1','email-48','node072',21,'cli',NULL,NULL,'2025-02-05 17:10:05.65587839+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["126.19.171.233:19526","[91e1:a8d7:5c43:b695:4f5:b147:b5f7:9f75]:62218"]','2025-02-04 12:07:36.231437299+01:00','2025-02-05 17:10:05.656193493+01:00',NULL,'100.64.0.64','fd7a:115c:a1e0::40');
INSERT INTO nodes VALUES(73,'mkey:a46b92cea88a9bac37dcb612a4a50dee75684f736c8c7f2aab812fa5fb9d463f','nodekey:1bbfdddf7b2a929a3da1e69236aa8b8fbd4b25d1839e57aaecf2ab910592bc78','discokey:c2188df6632aded7862de4b5d07c3993b3e908c59ce38f9d481f4840d85448c7','srv-06','node073',21,'cli',NULL,NULL,'2025-02-04 18:18:08.553472495+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[99f:9853:60cd:a4c5:e9d7:2a40:f86:742b]:782","[99cd:c956:e0f9:b633:5f8b:5c6a:50b1:571]:18474"]','2025-02-04 12:10:26.50545127+01:00','2025-02-04 18:18:08.559366076+01:00',NULL,'100.64.0.65','fd7a:115c:a1e0::41');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-05-17 19:36:55.859473496+02:00','2023-05-17 19:36:55.859473496+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(2,'2023-05-17 19:36:57.059073465+02:00','2023-05-17 19:36:57.059073465+02:00',NULL,'user002','','',NULL,NULL,'');
INSERT INTO users VALUES(3,'2023-05-18 10:10:36.248939077+02:00','2023-05-18 10:10:36.248939077+02:00',NULL,'user003','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2023-06-10 09:06:13.920718561+02:00','2023-06-10 09:06:13.920718561+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(5,'2023-06-11 19:58:32.371218434+02:00','2023-06-11 19:58:32.371218434+02:00',NULL,'user005','','',NULL,NULL,'');
INSERT INTO users VALUES(6,'2023-06-17 19:39:53.031565686+02:00','2023-06-17 19:39:53.031565686+02:00',NULL,'user006','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2023-06-20 11:35:09.325846831+02:00','2023-06-20 11:35:09.325846831+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2023-06-21 22:47:48.196234382+02:00','2023-06-21 22:47:48.196234382+02:00',NULL,'user008','','',NULL,NULL,'');
INSERT INTO users VALUES(9,'2023-06-22 08:30:35.068995572+02:00','2023-06-22 08:30:35.068995572+02:00',NULL,'user009','','',NULL,NULL,'');
INSERT INTO users VALUES(10,'2023-07-03 10:18:32.123226+02:00','2023-07-03 10:18:32.123226+02:00',NULL,'user010','','',NULL,NULL,'');
INSERT INTO users VALUES(11,'2023-07-03 10:18:37.130387602+02:00','2023-07-03 10:18:37.130387602+02:00',NULL,'user011','','',NULL,NULL,'');
INSERT INTO users VALUES(12,'2023-12-15 08:05:06.013615212+01:00','2023-12-15 08:05:06.013615212+01:00',NULL,'user012','','',NULL,NULL,'');
INSERT INTO users VALUES(13,'2024-02-03 16:32:42.224977233+01:00','2024-02-03 16:32:42.224977233+01:00',NULL,'user013','','',NULL,NULL,'');
INSERT INTO users VALUES(14,'2024-05-03 10:12:38.220973042+02:00','2024-05-03 10:12:38.220973042+02:00',NULL,'user014','','',NULL,NULL,'');
INSERT INTO users VALUES(15,'2024-07-26 08:08:40.979783263+02:00','2024-07-26 08:08:40.979783263+02:00',NULL,'user015','','',NULL,NULL,'');
INSERT INTO users VALUES(16,'2024-08-05 17:32:02.878091894+02:00','2024-08-05 17:32:02.878091894+02:00',NULL,'user016','','',NULL,NULL,'');
INSERT INTO users VALUES(17,'2024-09-22 15:48:00.287392203+02:00','2024-09-22 15:48:00.287392203+02:00',NULL,'user017','','',NULL,NULL,'');
INSERT INTO users VALUES(18,'2024-12-10 13:55:11.256977421+01:00','2024-12-10 13:55:11.256977421+01:00',NULL,'user018','','',NULL,NULL,'');
INSERT INTO users VALUES(19,'2024-12-17 14:57:58.550971236+01:00','2024-12-17 14:57:58.550971236+01:00',NULL,'user019','','',NULL,NULL,'');
INSERT INTO users VALUES(20,'2024-12-17 15:02:08.053169491+01:00','2024-12-17 15:02:08.053169491+01:00',NULL,'user020','','',NULL,NULL,'');
INSERT INTO users VALUES(21,'2025-01-28 15:57:32.774456057+01:00','2025-02-04 14:53:57.282402538+01:00',NULL,'user021','','',NULL,'','');
INSERT INTO users VALUES(22,'2025-02-03 14:10:50.491924701+01:00','2025-02-03 14:10:50.491924701+01:00',NULL,'user022','','',NULL,'','');
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(1,'2023-05-19 07:09:23.387641743+02:00','2023-05-22 09:48:18.908103256+02:00',NULL,3,'192.168.224.0/21',1,0,0);
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,117 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
INSERT INTO migrations VALUES('202501311657');
INSERT INTO migrations VALUES('202502070949');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'463a8b372963aeaca12400faa0c7ea29e9bfa3b4c59e9622',3,0,0,1,'2023-05-19 05:09:19.66636462+00:00','2023-05-19 05:14:19.664224869+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'77a019cb12c0d0b9347a17ab23fa4c87983814fe36bb2fbb',14,0,0,0,'2024-05-03 08:13:55.8614948+00:00','2024-05-04 08:13:55.85782156+00:00',NULL);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:0ea01e8cd608548a171ebcedc16da73b25ec18d58861be7a6b4274eb17baf6ba','nodekey:0fcf591dc1997c1d7388a3835bd24dae48240e5b03b6a7f5f33b2e813d222bcf','discokey:ed27f0b3c04222f0d05bfbc6fb5787338275ed0e32fd42fe68c669aca0f3d7a4','desktop-54','node001',2,'cli',NULL,NULL,'2025-01-30 19:50:45.306207411+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b8f0:cf44:22c8:82d1:f79:c3eb:9144:c24f]:6142","[8e25:af1:e31a:8fcc:7dcf:be1:a3c9:ed6a]:38766","[37a1:215f:bf3d:3fb1:6399:f7cb:4048:3ca8]:51666","137.242.125.72:25376"]','2023-05-17 19:38:13.531518257+02:00','2025-01-30 19:50:45.306340015+01:00',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(2,'mkey:1e274f40556282a5bbab04b6754985233ccdf971b663e5b38fc027035e833e9a','nodekey:5b16c7e14191ca2e57eccd86ec636db605fa5dc2c8856be5fa7f9b087cf24890','discokey:5fd2f116700fd48ce06e35e8dd11c847ccd7694e01ec4b3f6ef25f67c14ee197','email-21','node002',1,'cli',NULL,NULL,'2025-02-07 13:37:43.531171201+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5aae:55d1:7b5d:628d:bc07:b3e0:eca2:836d]:13912","[5583:8a0e:1564:ac5b:98ab:59a3:126:cba2]:35537","84.23.188.83:48876","44.184.117.89:36643","90.223.136.253:7056","[e43c:be7:7f4e:8217:a009:7f9d:a510:1af6]:18872","[3a86:865b:2f4c:f3b7:88a0:4aa2:f05d:c3fd]:47680","86.50.30.30:18216"]','2023-05-18 10:09:21.757289398+02:00','2025-02-07 13:37:43.531627524+01:00',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(3,'mkey:4405716e66f6a07a8fea90183cb078a8b87108aef23965b1c65f51375f3882d3','nodekey:96f979ded4cf1a02655d0b9069fb14e04d2da09c182624313acccf8c7f6b67a4','discokey:f0f4a89d7893303e1a336c9838c9a55b36a5215da006fccb72c237a794f4c5ea','email-51','node003',3,'authkey','[]',1,'2025-02-07 13:37:15.112124641+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7cd1:a579:7ddd:ed37:5f70:5783:8e09:1968]:5323","110.83.0.14:9543"]','2023-05-19 07:09:21.399903526+02:00','2025-02-07 13:37:15.122168073+01:00',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:9cd192ff56bc94ec9439083852bb541469d6725e6cda7a2aa624df6e8c8c380d','nodekey:ac53dbdd1bb1c2a36a1dde021e8f5f33d2cf01ef2892fe74853e945b9a08fda3','discokey:57cae29ceafb73857b478955a77927ff5bd8f38c313a869be093f92c6f6303da','email-15','node004',4,'cli',NULL,NULL,'2025-02-07 13:43:11.76403969+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2421:d8be:14:6b5f:7fe:56a8:54b6:8d58]:25207","[20b0:e4f:96fd:1cf3:5d39:ad75:6b8e:d0ce]:51455"]','2023-06-10 09:31:51.940506933+02:00','2025-02-07 13:43:11.765088576+01:00',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(5,'mkey:7f9c690aab22d9db060086ea375d86924359210816ad562dab2db804ad3434c0','nodekey:88fe0bcd504fd98c35a71484820dbf7b91c1704b9d29c0c7950ce5ab06ef2d17','discokey:fbaef49f1a2c61469168a9e81ee6c5bd49a777048288975a22c0f253aa14e2e3','web-24','node005',4,'cli',NULL,NULL,'2025-02-07 13:41:53.142598056+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["186.84.191.82:2621","[c9d0:4e15:513a:171b:9911:f9a0:cccf:cd83]:24151","66.84.158.199:63451","47.94.115.240:6677","19.74.30.92:1284"]','2023-06-11 13:56:42.694329408+02:00','2025-02-07 13:41:53.143294241+01:00',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(6,'mkey:00e154160e4bd8db73f2707c7a5b2f0bae04f3e26427a1aca5b0dcf2dcc1872f','nodekey:4f61b1414dd622304d407a7b4812640f774247f0c3d369a2292e3f4e88383c17','discokey:1028826beface553dd6ea7e553cc63ca59fd529716cb639981d1aa2965ed8885','laptop-48','node006',4,'cli',NULL,NULL,'2025-02-07 13:43:59.675348504+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["220.204.45.94:59135","187.96.173.136:34092","[fece:76ed:4c23:1e89:f225:97a1:94be:b5c4]:33472","[e1e6:a14:535a:668b:698:f125:543f:b5b7]:31740","[b8e3:18de:5ece:3e24:8bbf:1cbd:d27c:7de]:53522"]','2023-06-11 13:57:44.975695604+02:00','2025-02-07 13:43:59.676029923+01:00',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(7,'mkey:69a5389410061b4c336c1f337ae3ccca903f729ff249b6f1e556dcb9d9a3b7eb','nodekey:54c0d87c263afc07b7a3bb5569f8d6b67c58fecdcabefcbe7b8057e91e573a31','discokey:765930463b973ddead698512fe882cbe5e13885d14d44808596600efbcf5303f','db-22','node007',4,'cli',NULL,NULL,'2025-02-07 13:43:32.833347079+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9b54:61a6:c678:edac:956f:741e:5e2c:9ec9]:17930","[cd3f:af1c:fcb4:bcb3:806e:adf4:3f3f:ab36]:58513","[7a83:6a84:9f15:ba1a:9671:3d54:2e31:d5e9]:64893","167.223.65.194:6907","[debd:ad2f:ae50:cd14:9cd2:b297:bb94:d03c]:24266","[489b:6c59:1877:6215:ddc8:57f8:78dc:321c]:3025"]','2023-06-11 14:16:56.951313537+02:00','2025-02-07 13:43:32.833827225+01:00',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(8,'mkey:3fa0a7da3e9f0eecb11b442d911620b629981f5eb3f4ee851256a55b7252a1e7','nodekey:1912a3b843ba973c55b449fb0e1e01faff114b440e7bd1ca8b9af3be0cc56762','discokey:0d4f62fb22a9ab554a8983123cc118ec17b9d47c97d1d84bf082c90f82fe267b','lt-35','node008',5,'cli',NULL,NULL,'2025-02-07 13:44:16.543907578+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["124.104.237.237:47957","[b9f9:eec0:d656:cd83:8595:46fc:b677:6ade]:17494","126.251.133.86:44347"]','2023-06-11 19:59:30.401970393+02:00','2025-02-07 13:44:16.544521726+01:00',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(9,'mkey:dc84e5b1cf58ec8f7200ec0a655c1d5843c520ea59aa7ddd111ad5c9beba9bd8','nodekey:3c06f5a6d7f267023044ab632892b51f5af1ce4d84f0739e88823bc22cda6c57','discokey:3c1aa008a7811012038cd6658b6f290b3d252074c47d23cf1766f878340a30bf','desktop-75','node009',6,'cli',NULL,NULL,'2025-02-07 13:37:15.10720621+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["187.166.20.165:11208","78.47.168.253:34957"]','2023-06-17 19:40:45.468789461+02:00','2025-02-07 13:37:15.127284919+01:00',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(10,'mkey:2325e928fb41b3a3815b7635223411100ba10eba8ea1b442838b40da35379ec9','nodekey:8654f75dc553fbb381f57fd3f8669b5c2572f65d97989d0a69c3b294bb8cc685','discokey:24037160babf3208537006968c9f47ec3e689b1873796a787eaa44fa95afd986','desktop-46','node010',6,'cli',NULL,NULL,'2025-02-07 13:37:36.447602378+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[97a8:bbb7:9bb9:aa2b:e449:4d57:4a65:3561]:17392","151.97.159.85:8120","[69bc:fe73:f6c7:31b2:bc4f:1a95:4676:201d]:4806","[d794:c918:b0e8:6023:d7cd:709:79eb:23f7]:56801","113.147.88.203:61138"]','2023-06-20 11:18:35.905417341+02:00','2025-02-07 13:37:36.47098382+01:00',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(11,'mkey:4fb69f4bf77b8159e4814764398e6cd3bf2067b3fd4eda0eacc443ec299fcde2','nodekey:cebae8af02150eeb54b67f2cadc33dda38a98c94cfec05c1f378bf130007e946','discokey:fd5c9fefc960538a070c2bddafd53c3f890c561e02b62218e4aa8e6ae38cbe4f','email-12','node011',7,'cli',NULL,NULL,'2025-02-07 13:38:08.624346736+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d86:4301:d7d:7706:8b4a:86bf:19cd:1d6]:55529","151.169.147.218:56573","[9e9e:2802:ebb9:ba03:a564:7999:7137:65e3]:52919","[ede2:462a:f99c:24c3:b1b5:8b97:abe2:3ddb]:65141","[dfe7:6f6b:a382:4fc:a3f6:eb9:9ebc:5798]:1474"]','2023-06-20 11:35:15.063855316+02:00','2025-02-07 13:38:08.624847369+01:00',NULL,'100.64.0.11','fd7a:115c:a1e0::b');
INSERT INTO nodes VALUES(12,'mkey:5e192b1b323439fcc3b921c4f523ce9b7cce867220bd092d23be2451ce93a4a5','nodekey:1452cb2c8f26c8988cd8d8ed42957c78e3ab922bdf9773978c853e4254e23fbb','discokey:b7b41dc5de1fdcc4bd609dc72f79d27269367dbf72ab73ab61e998aa31eac6a2','web-19','node012',5,'cli',NULL,NULL,'2025-02-07 13:44:08.729267096+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["60.5.210.145:1193","[5698:e318:b38c:4331:5152:c2df:743f:8ead]:34839","33.51.84.119:46756"]','2023-06-20 18:22:35.061914624+02:00','2025-02-07 13:44:08.729820984+01:00',NULL,'100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(18,'mkey:f11332335d9f1f9d4bfc8cf9bf4edc0c958d4e4364b7dcde3c67d847f7d05edb','nodekey:e97d97a2751ef3533818907c9f24acf3270e3824f2294bb9a36d60ca196e161e','discokey:412b0eee00b68721d9169fc81039b9cda6cf57143e4cae8f7c417db15b83411a','web-18','node018',9,'cli',NULL,NULL,'2025-02-07 13:37:16.15950606+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2acf:3f32:1763:5d21:88a:4af:8779:1b1d]:36283","84.177.251.38:32968","[3138:83c6:ae09:a073:7888:71e0:494:3863]:59700","191.156.96.176:5489"]','2023-06-22 08:30:54.08720463+02:00','2025-02-07 13:37:16.721306872+01:00',NULL,'100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(19,'mkey:157706346bfe3502b6e24a84efa59b1a151be08f5a260ff96c72a734c1da1390','nodekey:139a99de286f52c55bdd61e932827c9d7cb84101a698df3576bdffbeedbf654d','discokey:293abc1a1cf2921e7961f5753cc39097956648bab47879791afb12ea03a4e6dd','lt-42','node019',10,'cli','null',NULL,'2024-08-07 09:35:12.220368767+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ce0f:9f05:96dc:a47d:edcd:1c25:f578:7551]:30363","[cc06:9c56:919a:2341:4ef7:7f28:c8ca:2a5c]:30788"]','2023-07-03 15:18:03.829428454+02:00','2024-09-18 16:15:14.037990869+02:00',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(20,'mkey:e4713082f1a4d5e2f5ca126b95eedc7ce673782a871afde980a74aa98e31273a','nodekey:3957decaff55af98415799c81e6cec28edc377d6e2a9ddca3c909c26bcffd45b','discokey:9e8360b263f67dc8d5dea9d37f023ebbbb8882f265f6ca43f5923194d7931609','db-08','node020',11,'cli',NULL,NULL,'2025-02-07 07:28:20.585544641+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4692:f8a0:842b:c26a:e549:1f3b:6795:964e]:31064","207.187.74.99:12216","63.3.67.150:22907","[77ac:562:7c4c:438a:6ec:be48:743d:47b1]:11349","[33cd:731c:f110:9b45:66b5:de81:1daa:757f]:5997"]','2023-07-10 12:40:34.838579199+02:00','2025-02-07 07:28:20.585679087+01:00',NULL,'100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(21,'mkey:2894a7babdc030bac1e4ec0e14aa4b6b67ebe382a1773e0ff4aa8b16ecd443a3','nodekey:1e219f3cc03eaa868018b9f6870d108317c31760fdc38ad4bec7200d58379f26','discokey:a81e998383baa23adb3e1e6757ef0c4b960095022f00b500b57f53c6147c71e4','laptop-48','node021',11,'cli','null',NULL,'2023-11-20 07:19:19.447470862+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[736d:a0a:e343:6b2c:b48b:7510:ace2:edc]:60377","82.193.154.129:23713","[68:80fa:7b30:3a0:d1fb:3e89:2c73:256b]:30308","[ad42:3917:5edb:3e85:732:1c71:a19e:9fe0]:11799"]','2023-07-10 12:42:43.290469734+02:00','2024-09-18 16:15:14.03886353+02:00',NULL,'100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(22,'mkey:9ab69494a274cba5b22cbcf35b3ada57d4b3d2ee03930a456f80fb34dc69064b','nodekey:0345912b4e39cd9d03dec55edec6fba7f8aca631312884b49538550475332182','discokey:a2c1be2ae50af07e5b96b0a3ee2d3a1b0148fbfc5c1a283bc787e31410d6f74c','web-51','node022',6,'cli',NULL,NULL,'2025-02-07 13:37:15.266244078+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["9.237.225.227:64622","[46a1:e1e6:6b82:6599:acc7:2273:afea:f09f]:38018","93.129.193.97:13477","184.41.32.72:1026"]','2023-08-05 12:08:48.132161695+02:00','2025-02-07 13:37:15.266464476+01:00',NULL,'100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(23,'mkey:d1b90c1c72090d082067c2dfbf287f26510b58519bbc5113f1ca63ad3ef20b96','nodekey:2d0d6f2300d295c8f91d0b954d733a2f8c4106595070d3efc6eb709df09591f6','discokey:87ef4543866a337716d7d5021346b82bbbd1aab14c36deadf96b4c38718e8cd1','srv-45','node023',12,'cli','null',NULL,'2024-12-07 19:25:56.935152754+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[79e6:8519:803b:6054:5c13:9069:8dfa:1dcd]:45055","30.154.162.65:53795","21.107.170.69:30767","212.18.227.41:50735","[f774:e89b:980f:975d:fd3e:93f:a9b5:2034]:46054"]','2023-12-15 08:05:56.592241745+01:00','2024-12-07 19:25:56.935317645+01:00',NULL,'100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(24,'mkey:f10b7f9f385e48dc99ec0944b8a04ec4d3e5613587419c134440121fa747ee75','nodekey:9559349d25dd3fa88b9595cb4ccebeeb4712338757a209e936afe37ec2643dbc','discokey:b9a07315c1eb2e074871feebe899bd2ecae64d98a8edf08883785130ef386728','laptop-25','node024',12,'cli',NULL,NULL,'2025-02-06 16:36:01.609321017+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9e60:1bb7:b542:2f50:269f:5ef:72b6:f4ba]:34677","159.52.2.200:7205","[5b7b:e424:ea77:aa8a:f835:d6bb:2e1f:52ea]:19152","[bb06:d322:7cec:426b:ef38:55d0:e7ce:95bc]:31597","[320d:6314:eaa2:a098:8594:977d:27b:8442]:12827"]','2023-12-15 11:14:36.765183054+01:00','2025-02-06 16:36:01.609441418+01:00',NULL,'100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(25,'mkey:84784f348b4e879e87986ef13b6f02ddef91639cd7de65540903cd846f93e1f2','nodekey:c15dc98ef47cf6f5dd52f59c22b3b6b0d8536ea5d248787a0145b45e6598cff6','discokey:c14e1be497f1423b4f4aa799f8ee907307eec987a1c3f7e32d4adf215fa731c6','srv-70','node025',6,'cli',NULL,NULL,'2025-02-07 13:42:34.03052815+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[23d7:1ab8:8bd1:10f3:a4f7:bd70:7803:773d]:50718","[3200:76c9:dca8:d60:e5d6:868e:a264:3efa]:33138","[975a:978:5cfb:5e5a:1b6:d272:a1c1:50dd]:3245","[e6e4:7cfc:9ce:b47:62f5:b64e:d2e4:9015]:42369"]','2024-01-05 17:32:40.940566279+01:00','2025-02-07 13:42:34.031054525+01:00',NULL,'100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(26,'mkey:dba47da985e4770a27031261b989e24ddd437983652bd1f96cc520ed78c5fc0c','nodekey:3c36d35f3e9ec98b36741e5973d8f5542fd82503a1752ad9e20545fb6be984bc','discokey:b30567e26d2fae861e566c4081179d8c72f9e659521dd7e6afecb3fbaaeae63a','db-02','node026',6,'cli',NULL,NULL,'2025-02-07 13:37:36.216420089+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["192.175.239.121:921","98.153.121.140:5003","208.68.161.128:56198","163.42.128.241:47535","49.160.22.202:42427","[1526:e34a:8857:394e:bbe0:c043:4b37:68d4]:5245","32.31.195.128:7039","[c50a:ec:e2e:e109:3a08:f56b:2928:4921]:61265","221.147.144.138:44737","136.208.142.64:41091"]','2024-01-05 17:34:19.811670479+01:00','2025-02-07 13:37:36.272729094+01:00',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
INSERT INTO nodes VALUES(27,'mkey:73868242348c7d709b77f52963c32eb4b95c8b6f89abb5db76bd95cdaaa538b7','nodekey:2de3f421f78de3f5cfd824ffaa80cf3fde3060bc42f51c2ee2f55b49fd5fbe20','discokey:5ff3b0ad430ee5530c972ecf0d3e69f25eecdadf6ef8a309b3841d7aaa6f70d4','web-56','node027',6,'cli','null',NULL,'2024-01-16 14:32:21.570104175+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a2b8:ea55:f9e3:2c00:f423:8c56:7fec:c617]:53793","[ed88:2277:3c9a:4f64:a25e:5b41:a3ca:e904]:27852","[d203:40a2:5efc:4a42:8910:81f8:59c6:4d8d]:23389","187.126.162.12:25054","[5d8b:9391:47f1:1bbc:e01:92de:4a90:7614]:42410","172.81.188.131:23453"]','2024-01-05 17:48:25.466030859+01:00','2024-09-18 16:15:14.040766068+02:00',NULL,'100.64.0.22','fd7a:115c:a1e0::16');
INSERT INTO nodes VALUES(28,'mkey:300a566a21fcaab2665dc091300e2c5110dcaee25e2fcc4cc23b011fdae471e6','nodekey:8e36531b406e0b7b9c1b9abadc00626ccc8c6e7a0c37f70f42ccf06cd2dd03fa','discokey:a4134738054f6fc0c57b6eb47913e68a3f47ffb81af8a3496754921c2fcb02f8','laptop-98','node028',7,'cli',NULL,NULL,'2025-02-07 13:37:15.697245044+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["113.143.9.36:55432","[e266:66fe:4929:3831:7830:6f10:1572:20df]:9977","[afe5:7d57:fac5:a1c5:78d4:ee33:d474:1e56]:52223","7.208.95.117:299","[d28b:7b33:1f88:7583:7ed7:a923:4c90:9ee0]:62318"]','2024-01-15 09:34:54.847632697+01:00','2025-02-07 13:37:15.743059169+01:00',NULL,'100.64.0.23','fd7a:115c:a1e0::17');
INSERT INTO nodes VALUES(29,'mkey:8e49fb1776eb7ce9cf27cd557a05f6d1868e6ac5a06eab48baa953a0a0b17381','nodekey:3ff07a931e2725e7f96c378dc8b4a531818fa64e853879df8c51d5f2bbff8f9d','discokey:bcf9648f2249fbc34d8fe61593c8ffcfd4205593b9c6525196148b1f280228d2','email-91','node029',7,'cli',NULL,NULL,'2025-02-07 13:37:14.081795989+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["162.176.178.140:46577","[4f52:1708:c0a:7991:9c16:bd7d:4045:195d]:50362","[fd0d:f112:f642:c343:ac14:8ede:dc04:e2d9]:58412","[8a1a:5c17:bb81:bb69:c7db:3513:f14c:ca2d]:52077","123.235.220.59:59925"]','2024-01-15 15:18:12.2871978+01:00','2025-02-07 13:37:14.172137472+01:00',NULL,'100.64.0.24','fd7a:115c:a1e0::18');
INSERT INTO nodes VALUES(30,'mkey:15fa512b5b78a7714edf3477babba0d325e0b121f5b81b63dafa434a9eb71c32','nodekey:b61427ebfd1dd6801f5bccb3fb42c30e1ace79441daa9d5d0cadcdd9ff199370','discokey:6a09d51cbcafc8c1eb9983a744f2df3f288d43a3b8ba06f088eb7fe1c375b341','laptop-77','node030',7,'cli','null',NULL,'2024-02-05 12:14:40.065688294+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e84c:35c4:4bd9:a100:c271:8921:ca7:5901]:21828","[fab9:f181:95a4:a769:df9b:b7ae:9799:83dd]:32341","[e868:f68f:cceb:8d29:5451:c716:bdca:437d]:41081","[7016:b48d:8bcf:4ccd:8679:8c47:1c66:cd1e]:41980","22.231.20.85:41616"]','2024-01-15 15:21:43.217136004+01:00','2024-09-18 16:15:14.041757308+02:00',NULL,'100.64.0.25','fd7a:115c:a1e0::19');
INSERT INTO nodes VALUES(31,'mkey:fbebb2c69f263a519c8902463ef9c7db0597109fae5730a222f1c6567278bc86','nodekey:d83666c0acac1a9cd306cb884a1ce24adaabbc2102eb553ef5514ac5ea1714cf','discokey:6f4280bcb38ac995d22543db32230d8f22f2c0a0dc5efe2d86c7361c897ae812','lt-82','node031',7,'cli','null',NULL,'2024-02-22 08:35:27.098819037+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4327:29dd:a02:fb00:9645:d497:8ffc:4a68]:26342","[5d4a:a2f2:16c7:3d3a:a2b8:2962:30f9:3407]:5279","107.140.203.49:9365","[1660:741a:160:67c9:7972:5f9d:14bd:ee53]:21178"]','2024-01-29 16:05:35.338524634+01:00','2024-09-18 16:15:14.042191514+02:00',NULL,'100.64.0.26','fd7a:115c:a1e0::1a');
INSERT INTO nodes VALUES(32,'mkey:8c468799222af319e17ec309dbbf3a87fb6d924a1cb17e5a0bd7e027fe3bfe5e','nodekey:3c7d82f4a44cfa1469b957ac911e8506a68962fb2583d2afaf3e8a621c0c4aca','discokey:ba179b51f3540e619eaac9a6d4bc67403daa7c3cf28a6b579087cd6d284501b4','lt-53','node032',7,'cli','null',NULL,'2024-04-09 13:59:43.37062537+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d21f:d7bc:f690:e3ba:82fe:8122:c33d:5a86]:227","10.67.113.92:45634"]','2024-01-30 10:41:58.31917869+01:00','2024-09-18 16:15:14.042506082+02:00',NULL,'100.64.0.27','fd7a:115c:a1e0::1b');
INSERT INTO nodes VALUES(33,'mkey:be7f190677fd0cd1c5e78b4ae5b02a1738dd60be7d9a41017000b22ae9636af4','nodekey:a404e578d3edd3e3d879e9f1946c859b5982c59f5e528bf6b987bd55de00b25b','discokey:ad3013f116c370866fc9134b66999bb05e2dc10a8e2944230c3d9893c0a94c67','lt-80','node033',13,'cli',NULL,NULL,'2025-02-07 13:37:15.862018576+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[af8:f5e8:32f0:75ee:d351:c0e9:78e:93d9]:12624","71.151.27.31:51063","[f0d6:21dc:48f5:63f4:daff:a3c4:7d60:51ea]:17286","[38c5:9551:f6ed:b087:91ba:bef1:771c:273d]:62171"]','2024-02-03 16:33:26.706408143+01:00','2025-02-07 13:37:16.21569294+01:00',NULL,'100.64.0.28','fd7a:115c:a1e0::1c');
INSERT INTO nodes VALUES(34,'mkey:7784df3aabe1ca1edab5270028fb3cae8b66cee2384790d06969d1e6e298520f','nodekey:fd8e939fd6db8caf6623ac3d73c12ade4da110d8c1f29e3a3ee0d2be0c526915','discokey:59aff4582e00d92260e6a90d6d0da3d818fe8f52c081c8b65e18006ef8269ebe','lt-65','node034',13,'cli',NULL,NULL,'2025-02-07 13:37:13.91519638+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["71.155.69.236:8707","125.2.67.155:50785","32.6.80.181:17295"]','2024-02-03 16:42:32.683785672+01:00','2025-02-07 13:37:14.346290035+01:00',NULL,'100.64.0.29','fd7a:115c:a1e0::1d');
INSERT INTO nodes VALUES(35,'mkey:ad3838fa63fb120ae8d3e47d4bb6bb4009e7fc5d91483d1ba7417d0681fd7162','nodekey:b10ddbdcf826d79049d74a7d4ad036b499c86f7daf786bb1a9b295366b57afe8','discokey:618ef629d3bd261964c613ad3bc45e6278fa274d734c8cd2d3396cf8c9742d88','web-33','node035',5,'cli',NULL,NULL,'2025-02-04 17:50:49.267594119+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["169.159.71.157:18240","[bbb7:5b4d:218d:55ff:ac9b:1fb6:c933:9a55]:63943","18.156.132.228:63356"]','2024-02-03 16:51:52.010016072+01:00','2025-02-04 17:50:49.26844864+01:00',NULL,'100.64.0.30','fd7a:115c:a1e0::1e');
INSERT INTO nodes VALUES(36,'mkey:c536a3efc460fb2da4c4775e2b51d0c84f001dc46a4d902429e74e97b2d3c6d4','nodekey:91da2acfa3d7f7c7b0c1a2d952ee527514504fddc504809423762203a16145ab','discokey:989ff5f21d485dcb6312fade38c9047bbde1fbce46bc29ac5f6afe00610ad215','laptop-46','node036',13,'cli','null',NULL,'2025-01-19 14:01:48.956567669+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4017:a243:61d0:b302:7860:18f:7d4d:f605]:28633","[e5b8:6c78:ce2f:cf6f:13fb:401f:8223:3f04]:54121","38.137.88.247:35801","[eec2:61c0:e20a:2fa0:5e4d:56a4:5071:881b]:36628","[b8c2:c792:3329:2c93:f94b:a948:7d11:b9f2]:908","[5925:353c:bd9a:f42e:1916:45b4:c170:e515]:18400","[c2a5:cc2f:e2e8:573f:7b01:4aa:8a1a:fd71]:32146"]','2024-02-09 12:34:57.879970954+01:00','2025-01-19 14:01:48.956830267+01:00',NULL,'100.64.0.31','fd7a:115c:a1e0::1f');
INSERT INTO nodes VALUES(37,'mkey:142e67963c9045164df7b33af6d2149d72f59527df44fd75221647281444cbe7','nodekey:a3a2cd2bd0c3a1f783d0391ea1951c5c9226ddca0f18130b77fccff8b874d694','discokey:bdb788f8825b9bd816f37dcea882920382c7feb143edf0a6baefc9015774d8aa','lt-24','node037',5,'cli',NULL,NULL,'2025-02-07 13:40:58.763825796+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c31d:dd18:321:589:11fa:d85b:695f:1fca]:43064","168.4.78.117:48474","90.45.218.0:29326","90.233.46.138:29846","8.137.133.59:22781","[cb5c:f8d4:ccb0:8333:8ec:170c:a2b0:941d]:26248","[5802:df5c:8853:4851:6dcf:cb83:8208:d143]:24568","48.38.104.41:43702","139.100.200.227:62546"]','2024-02-27 12:14:40.452601042+01:00','2025-02-07 13:40:58.764224794+01:00',NULL,'100.64.0.32','fd7a:115c:a1e0::20');
INSERT INTO nodes VALUES(38,'mkey:6829f2d5523aba7a27c31e59e2341f3feb5a5a72a0268ef10d23c39811ea3b53','nodekey:10e4ff66fdd37fb54f6dcb0e42f483a15b6340610acc3a4517c24f0f350b5a9a','discokey:f20786f9c7edc967d0b415bbcce39468441af3b531ff15656c0683d3f328720a','lt-88','node038',6,'cli',NULL,NULL,'2025-02-07 13:42:43.738264414+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a393:f17f:6728:82e4:c1e7:2367:82d0:daaf]:18560","[d192:9897:4cd7:bfb5:de36:fc03:8cf4:c60d]:25096","212.199.67.213:11150"]','2024-05-22 08:08:16.045350656+02:00','2025-02-07 13:42:43.772029617+01:00',NULL,'100.64.0.33','fd7a:115c:a1e0::21');
INSERT INTO nodes VALUES(42,'mkey:33e764ae40265089c5e7dbfc8571aa23bb390fc7e1e8bd2f3e0cd6891c308214','nodekey:c444c9ff652ba29181a5f7fdf991f91f704e6698237ee18b0649c81879ec932f','discokey:2e1db3a1eea266673acf7826aa44b5aa6fdd23c6ba41330562b37c5a523ba358','laptop-81','node042',14,'cli',NULL,NULL,'2025-02-07 13:37:15.183056803+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["190.179.215.222:61930","45.131.187.230:22916","[510f:af99:ed4d:f53a:fc21:8640:9ad9:4930]:16050"]','2024-07-03 11:12:29.418355657+02:00','2025-02-07 13:37:15.184237123+01:00',NULL,'100.64.0.37','fd7a:115c:a1e0::25');
INSERT INTO nodes VALUES(43,'mkey:353844c4b332bdbf7f39796c522ee89d7f64fde342d3e566878f456df0d57a54','nodekey:c9f47cb50fd2b9075cda9d68018659491ac29dbbe7a04e8405039fd385966fa7','discokey:ec43638237bc43ab6a9839b3a4d54c2593e11a2ebd13bd491f08f68d7cf93ac0','desktop-90','node043',14,'cli',NULL,NULL,'2025-02-07 13:37:15.256444976+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e071:3cd7:878c:ae2d:7dcf:eab0:d0d1:decf]:37427","17.31.200.70:26794","[183d:f2d6:b80:36c5:318e:64e9:7f4a:b389]:12440","169.173.198.12:15274","[e5df:1889:6ac5:7d21:4dfd:614b:7eb9:d93c]:792"]','2024-07-03 14:48:50.263910778+02:00','2025-02-07 13:37:15.258418656+01:00',NULL,'100.64.0.34','fd7a:115c:a1e0::22');
INSERT INTO nodes VALUES(44,'mkey:6d3e50168ff6e672ed7650abc5a1de7fec7150c6f84932c705c84964824d1d39','nodekey:ad70f51f99efeefdf0c8e0a9e818db1e5de474e67b2b0a1609a53190339938ef','discokey:c4d4ad19814f9312b454cadb85b333f80cccca1b4a42f30780f7a0f4ccfe1bff','laptop-97','node044',14,'cli',NULL,NULL,'2025-02-07 13:37:15.264418779+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b501:efaa:c73b:b492:c3cf:865:d55b:9557]:26172","162.210.141.106:52036","[84ef:a164:d1c:d20d:797c:753e:f8fb:3108]:5767","[c15a:e322:a721:c9a7:a662:ccb8:26b8:e1c4]:63192","[87c4:c36b:d96f:525b:fa4c:c5f6:7bc8:d6bb]:35894"]','2024-07-03 15:23:48.066044194+02:00','2025-02-07 13:37:15.265313019+01:00',NULL,'100.64.0.35','fd7a:115c:a1e0::23');
INSERT INTO nodes VALUES(45,'mkey:e1772e6b138211afff6aa8fee08438c311b1d9d32576075c980d39591b13ae77','nodekey:92b8cc28bff0c53f95fbdd8c1363040100ae849e78aea04a3755e9a1fd03fe4e','discokey:7b368b5d64b6e4fb4f0ba9e5809bee8b769949ecdc69ec6ee6c9f12c2321fced','email-94','node045',14,'cli',NULL,NULL,'2025-02-07 13:37:14.65277645+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[caa0:946e:b130:39aa:31b0:8f9:7526:4960]:1729","120.102.247.255:41936","28.177.95.32:7841","[fb23:5998:c63d:b6c4:e86a:96b2:61c:e110]:51902","[89d4:f6c6:ccf6:b19d:3b76:642e:7a36:d229]:930"]','2024-07-03 15:54:01.706018896+02:00','2025-02-07 13:37:14.741317691+01:00',NULL,'100.64.0.36','fd7a:115c:a1e0::24');
INSERT INTO nodes VALUES(46,'mkey:af6c1d228b675ff04d2584e2c23d6288ec312a6b44c5c0eed213423a11711787','nodekey:f5b21f25bb22b5cf0cedb1b643d50c3a6512ef300cc971eccccbcc500cc23408','discokey:72843a1b2564c177d8556eb0d76dda7cbe0d9f1408bd250fcc6149518eb6d5c0','desktop-41','node046',14,'cli',NULL,NULL,'2025-02-07 13:37:15.182378567+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[37a8:9998:e94e:e297:940e:5414:5549:87c7]:37130","27.138.122.133:37304","98.38.29.194:12660"]','2024-07-03 19:38:07.783745318+02:00','2025-02-07 13:37:15.183590138+01:00',NULL,'100.64.0.38','fd7a:115c:a1e0::26');
INSERT INTO nodes VALUES(47,'mkey:5bbb77092f21b4835b0ae1af3871fc48445819c9b6e5ff9c46ad4a623b662ae8','nodekey:191c7cc089ee160c07b63e2b6b5ef0701d76d914009420baddad9bfce13e3f2d','discokey:712cadffd23f106abeea82ae70bbae8e06c2a58f3db617afd0d149b3012c64fb','web-61','node047',14,'cli',NULL,NULL,'2025-02-07 13:37:15.16567498+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["186.118.23.242:32373","[5bd8:a5a8:1b3:5e41:3c4d:5fc:4c0:c6cc]:24847"]','2024-07-04 10:38:08.344092869+02:00','2025-02-07 13:37:15.167818666+01:00',NULL,'100.64.0.39','fd7a:115c:a1e0::27');
INSERT INTO nodes VALUES(48,'mkey:a1e793aa09c20360cb4ef57e7dc42171a0abbc9f562140609e930ba5b7b12e83','nodekey:3343520915898c9d90b7517eabf8660d66c37ed12aea0b5a4935458f95c801c9','discokey:6a80e23d10d2cb3edb58c9c47ee997f9063d6aed2f29049f635b6bf1da090885','web-24','node048',15,'cli','null',NULL,'2024-10-20 13:53:33.831192385+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["101.103.129.11:50383","[3aab:52a2:b9d3:1816:5627:336:6c60:57d7]:13486","22.83.180.41:14147","26.126.135.206:7777","[8706:d109:5006:f832:dca7:58e4:4451:be15]:15180","177.4.27.29:60895"]','2024-07-26 08:09:56.608302315+02:00','2024-10-20 13:53:33.831387627+02:00',NULL,'100.64.0.40','fd7a:115c:a1e0::28');
INSERT INTO nodes VALUES(49,'mkey:13b8d4cafbdb8e9ab77928219aa57bf778878866ad8e6108b60aaab8dc8cec36','nodekey:17cefd68f8a9cc20b3d4fd93598f77ddfd6bd5a7e6e4b49861f9faad8623e0ef','discokey:939a04ddd2f9a24468e07ee7924dbb7a7662c1e8a1b67426f57fd48c7394448b','desktop-40','node049',16,'cli','null',NULL,'2024-09-19 09:07:18.28136023+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[19b0:8be2:708:d27f:4d3d:3c93:9979:e9e8]:50438","129.0.5.112:19015","[91e2:54c6:93fb:ec32:6ab4:186d:81cb:b815]:37323"]','2024-08-05 17:32:41.937626584+02:00','2024-09-19 09:07:18.281618912+02:00',NULL,'100.64.0.41','fd7a:115c:a1e0::29');
INSERT INTO nodes VALUES(50,'mkey:03979d5446bb3f596bf0234d81ca84482eacb132e874ceda6cc2703422cd728c','nodekey:805c03cada525f14ee90d28ea02b23a3f57b470c793314872ad9daacf6c6484e','discokey:eb4135e1cc73a3c6b513d8cc04ca0c55a2aef7b0009845fa1d2036488aadf0f8','desktop-02','node050',10,'cli','null',NULL,'2024-08-07 10:10:06.595550455+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9175:498d:64ac:4342:2eac:ffa1:99fd:d109]:21202","[5cba:56ef:db08:320c:333a:541f:605c:44d5]:57469","150.211.2.236:50360","203.180.122.83:13344","63.162.234.32:11653","[6b63:f552:f930:e22c:fc42:3b41:c5c6:6d5f]:63162","114.48.12.185:47837","[2964:cc5d:3a1b:7889:acc8:4d8:22c1:398a]:43515"]','2024-08-07 11:50:54.144157179+02:00','2024-09-18 16:15:14.050033969+02:00',NULL,'100.64.0.42','fd7a:115c:a1e0::2a');
INSERT INTO nodes VALUES(51,'mkey:5877139c52c0bf3c0fd054bd046aaf4530dd8946548a7bc1a06733649d1557d8','nodekey:553d9638c8c455e8d1bc811ea3af03db1eb3c586413447c8003e7d905a61d06c','discokey:1da883c9eff402d786362aaac2f478c835308b3acec0993e6293becf4474609f','web-62','node051',14,'cli',NULL,NULL,'2025-02-07 13:37:38.925095255+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["86.215.174.228:26026","93.101.159.155:64005"]','2024-08-07 14:19:31.156780417+02:00','2025-02-07 13:37:38.92600407+01:00',NULL,'100.64.0.43','fd7a:115c:a1e0::2b');
INSERT INTO nodes VALUES(52,'mkey:0e64072dafa5f9e49266b41fc4b21ff7d287be8f4e5f2b6c395487d632f1cf3f','nodekey:2f77bb8cbeb426bcded5ad9fc6da44b0b76b8d6759f10a8db28e634290760ee7','discokey:836558738056edd1fa8d190c7e42f120b365a48a3b1f1c96c87755bb82d7ad0f','desktop-07','node052',17,'cli','null',NULL,'2024-12-25 17:27:58.515851096+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d889:f751:710:257f:977f:5597:9908:14e0]:61162","[f83a:5ebb:911d:ef36:743c:8086:8a4c:a5c7]:23538","[dc45:365c:e426:71d7:fe23:fdd4:d2c2:9409]:57262"]','2024-09-22 15:48:41.385301399+02:00','2024-12-25 17:27:58.517153789+01:00',NULL,'100.64.0.45','fd7a:115c:a1e0::2d');
INSERT INTO nodes VALUES(53,'mkey:a6f93e99a5019b3b6a2941d95dc7fcbfea5a59317a48b99db93b7a3f4f0a65bb','nodekey:1f78a6d76ea4a2135c0da46b202560c86ed30cd7e8239d4508088d0e02ffb961','discokey:1744062452f052aba5320e37fc08aaa37f1430db7c32c94c5626f0f3c858de3d','desktop-82','node053',17,'cli',NULL,NULL,'2025-02-07 13:37:13.842388728+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6084:ee60:1697:864e:4a61:cf6e:e9b6:4c05]:63961","[fad7:2601:d286:4772:3cce:6e89:f66e:9eeb]:5430","216.60.124.11:45041","[d513:c472:d7a:f316:f610:10d0:9851:4feb]:3955","156.228.105.157:61542","102.126.185.0:50694","[156b:e934:d171:2693:8db4:f193:a58c:17b6]:24190","79.255.179.99:56057"]','2024-10-28 10:04:50.084492941+01:00','2025-02-07 13:37:14.011393166+01:00',NULL,'100.64.0.44','fd7a:115c:a1e0::2c');
INSERT INTO nodes VALUES(54,'mkey:4eee40f0117b3b8580f4cf3ec7be063bb4d82173cfa3c015c8932431940d9c92','nodekey:4241ffb9768a0e31f38cc0c5b2f240c1de72b8810e7ff3705964316e63c1a055','discokey:3ad8f2ebea95d15109a0adfc69b3a6b566ce02ce82df7a32e68f278538bc05a2','lt-15','node054',14,'cli',NULL,NULL,'2025-02-07 13:37:15.059804316+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9fe:6ddd:ab0:1193:7bb7:4a4b:c036:b910]:63516","158.169.112.249:5480"]','2024-12-09 17:10:55.363593066+01:00','2025-02-07 13:37:15.113575346+01:00',NULL,'100.64.0.46','fd7a:115c:a1e0::2e');
INSERT INTO nodes VALUES(55,'mkey:22e4ac4e25b05db4e94b5211e08ed14d983972f92e192f15e0231ff355fd46bf','nodekey:225f907deaffccb674416dc4ba532f0b20304e86d57808eef2d96f15211f2309','discokey:e695b849380f698178e7457311dca3cc10ae13a79b0a71d22130e7c401c4f246','web-26','node055',18,'cli',NULL,NULL,'2025-02-07 13:37:15.324226266+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ecbc:a9b6:cbb7:695b:62ad:27cb:36f0:2380]:27992","135.238.213.41:64084","[a5d2:373b:9599:8abc:6e7:2efe:f921:3a09]:56107"]','2024-12-10 13:56:39.287449662+01:00','2025-02-07 13:37:15.355747009+01:00',NULL,'100.64.0.47','fd7a:115c:a1e0::2f');
INSERT INTO nodes VALUES(56,'mkey:6b8c199041c26e52d594b6e9be9d4d9bb695d32e9fe247c84314b6809b8f38fc','nodekey:26b392e9f02b3910c5974f133282119f99e67ed084b4327aa818333e04010d40','discokey:8312bc333f55d0d6d7fc3e28dcb6300364c3008dff0cc64d2b480d5cba8260f4','web-69','node056',19,'cli',NULL,NULL,'2025-02-07 13:42:18.972640971+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5437:6f4:94c1:c6c1:43ce:7a41:e5c2:65d0]:57161","[7af0:3b83:a2ec:716d:bc46:deca:1685:e863]:26528"]','2024-12-17 14:58:39.429211911+01:00','2025-02-07 13:42:18.973110667+01:00',NULL,'100.64.0.48','fd7a:115c:a1e0::30');
INSERT INTO nodes VALUES(57,'mkey:edabd08e316b276318382fb96ca0ed40cf36f64c0a0de538295c0a69b0035243','nodekey:6576807f6b92bca841c85256b56daef25ab7113770f1db8ebc903d8b9de41308','discokey:a42e3f0759628634516ca1b4d4fa87450026af9101040401a23532a48ee07c76','laptop-31','node057',20,'cli',NULL,NULL,'2025-02-07 13:42:22.378213299+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[229:a09b:efd3:c73e:b885:d236:7dcd:20c9]:33744","[2de9:ec02:ffc4:1715:4d36:94f9:d726:fb8b]:55312","[72a1:a0b2:624a:827d:7d29:bd5a:3398:dbe4]:56924","[9875:c11c:289c:3b14:dc40:d7af:6:8372]:51751","125.170.153.154:21718","68.3.248.154:42390","[f621:b605:bd04:a964:160c:314a:141a:2e8d]:58563"]','2024-12-17 15:17:14.26936913+01:00','2025-02-07 13:42:22.378739434+01:00',NULL,'100.64.0.49','fd7a:115c:a1e0::31');
INSERT INTO nodes VALUES(58,'mkey:06bd440cb68a2856dcab4ae09ba4c4e7969b78a99a1d06bbacebc9d1fba037b7','nodekey:c0a2b88f5f4b9aee6a50df28b6ff5e5c495053c26d969100ef23f13a51349bec','discokey:4023ff7bfd754262fe36745731a9d1175cc0b49d7acac56123cfbf0c633fa0c6','db-32','node058',12,'cli',NULL,NULL,'2025-01-25 18:41:03.881898904+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["50.133.88.187:24107","[ed61:9d51:b21f:7096:32fa:e473:f6d4:9f69]:17106","110.235.245.179:61572"]','2025-01-17 10:17:23.455895657+01:00','2025-01-25 18:41:03.882180987+01:00',NULL,'100.64.0.50','fd7a:115c:a1e0::32');
INSERT INTO nodes VALUES(59,'mkey:837b21b2de65f931fa922fbc8fae0552beb9e5d5f3f089caa3b23e05e21afc9c','nodekey:2966f862ddc948ac6bec836f818b6af9717a5972128c20cadb0756dca94421a1','discokey:81f0e2ccd5b3292e6129c66588862e399a2e2685592f7e8b9e45254932532bf7','desktop-45','node059',21,'cli',NULL,NULL,'2025-02-07 13:37:15.162862529+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["121.80.178.149:12322","148.31.205.9:26021","51.210.182.192:52299","[2e30:4d2d:4925:201f:e845:2a12:503c:9524]:34552"]','2025-01-29 11:59:27.291048957+01:00','2025-02-07 13:37:15.166959448+01:00',NULL,'100.64.0.54','fd7a:115c:a1e0::36');
INSERT INTO nodes VALUES(60,'mkey:a8258e2d7302528bdad3321e5251beac7b920c0fd2be9a31ac541ceba25f868f','nodekey:f6dcffb992bfd5f22fd31752d1f450d79e68fd9d3a5d8c6002846d7c7e7ca780','discokey:5ce092b58afaaeac550606cb9ca49b9a82d8ec71c5bba6cea2727f3a6c51ed58','desktop-83','node060',21,'cli',NULL,NULL,'2025-02-07 13:37:14.448391309+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9bc9:59d8:52be:2e78:c641:a523:6bef:7101]:9124","103.8.213.76:348","[ac:5c65:da8d:d68c:eb0d:3692:d441:5363]:63612","107.250.166.141:64587"]','2025-01-29 12:01:57.48748166+01:00','2025-02-07 13:37:14.48001932+01:00',NULL,'100.64.0.55','fd7a:115c:a1e0::37');
INSERT INTO nodes VALUES(61,'mkey:274b3c292aff1b069c84dcb1708adbf93c479a88eff35023edd1d42ff9d2f3a1','nodekey:ff576e5a5d91943d1b95cc0bd0d02edf9ce965b04f4d55cf44cbc328a46e81e4','discokey:da967cf6cf6122fb4c3381342341fe2013bbb02592871a6a4875c0f2ed088497','web-95','node061',21,'cli',NULL,NULL,'2025-02-07 13:37:18.210665072+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["97.178.200.54:28664","112.239.138.73:43954","174.168.204.29:5611","190.0.61.36:13730"]','2025-01-29 12:03:01.464646336+01:00','2025-02-07 13:37:18.211304165+01:00',NULL,'100.64.0.56','fd7a:115c:a1e0::38');
INSERT INTO nodes VALUES(62,'mkey:55fead8ba87f06051dbc7eb41fc9263832e89a23587dc5161f4caa73e52b86c2','nodekey:ce19e593db9037b1ca155c2eee3628bdadf18183e7bb2c2e8452c490a4a70fc6','discokey:3fe7586ae2c3942956fa5929c628519dd776326bd41941bf9c4ca67c20b39d39','web-47','node062',21,'cli',NULL,NULL,'2025-02-07 13:37:15.119660489+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2476:14e8:ab74:a221:cfca:bd5e:64aa:83d1]:48008","203.192.235.192:35390","30.40.23.45:22912"]','2025-01-29 19:23:14.092804852+01:00','2025-02-07 13:37:15.125730738+01:00',NULL,'100.64.0.57','fd7a:115c:a1e0::39');
INSERT INTO nodes VALUES(63,'mkey:375546b6250c3cb141b036b348e902de244a8572dd7572422e95e36a6f6e4db8','nodekey:4fc64d645299720f14481c889ecaa1f08e48a3b83f19ece638b7d4d9d00bf75c','discokey:404b99d3c51100cd92dcf7caaee677b9c3f5371070504f0848759bf792ce1ed3','lt-21','node063',21,'cli',NULL,NULL,'2025-02-07 13:44:32.21661957+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[68bb:e8d1:72d8:8b02:608b:2284:c9b3:184d]:20876","[5c17:4014:ea6a:5528:b1a:61b7:5cda:5c5e]:21597","22.244.181.59:21123"]','2025-01-29 19:41:40.535299057+01:00','2025-02-07 13:44:32.217372195+01:00',NULL,'100.64.0.58','fd7a:115c:a1e0::3a');
INSERT INTO nodes VALUES(64,'mkey:ea810305395687d011a783dcd058cf511363eb4d5638eeeb6886b7f5e690482e','nodekey:c5b9b10d988bc237815f7c98830abfb86981972949898f2ce9a1451a7bc617bc','discokey:1e0c9544833ff8f89685b81f2795c330500d8d414f856e0e9f4ec439e3c76dad','web-27','node064',21,'cli',NULL,NULL,'2025-02-07 13:40:53.575919211+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2fb6:ea0a:3639:a1cd:9075:a258:6a79:4f5c]:13944","[2384:3000:4d47:a9e7:54ef:99:52c0:e920]:39358","130.195.116.24:53838"]','2025-01-30 18:18:57.519126133+01:00','2025-02-07 13:40:53.576418189+01:00',NULL,'100.64.0.59','fd7a:115c:a1e0::3b');
INSERT INTO nodes VALUES(65,'mkey:fe494a29de4149025e3c41744cabfaaa2ae9a95795bdb6425e3beee27048e0f6','nodekey:2b078ccb547dc8b01f19749735f5fc43e65e4d468357a08a880fa54dc0a1e00d','discokey:cb991d6c0a14b0213e6f807e9c37a837b181c889a1e2d25e10d65d4a7e8b2b05','laptop-33','node065',21,'cli',NULL,NULL,'2025-02-07 13:44:09.41583007+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["54.154.28.86:64790","197.205.147.181:38523","[5e11:9ab9:6805:dec0:99aa:65e6:d1fe:6e58]:45247"]','2025-01-30 18:19:40.354692307+01:00','2025-02-07 13:44:09.416328169+01:00',NULL,'100.64.0.60','fd7a:115c:a1e0::3c');
INSERT INTO nodes VALUES(66,'mkey:6c97e6102fbb96b98090402e9414b0d8e2e5ded0aa8cded7ebae64da5c2518d9','nodekey:f2d5b51602df1f8c57ab59973c100919b7f84bdc09386d43ad49fa30d6595e38','discokey:15d3ca06419e377b06e2e0a3b36d53f5b448087f9609c73a128429e17c88102c','lt-62','node066',21,'cli',NULL,NULL,'2025-02-07 13:41:35.878248155+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["6.193.99.72:20874","181.248.237.50:21695","171.59.96.217:25726"]','2025-01-31 12:05:28.65297301+01:00','2025-02-07 13:41:35.879388156+01:00',NULL,'100.64.0.61','fd7a:115c:a1e0::3d');
INSERT INTO nodes VALUES(67,'mkey:eb72ad359958c98e28f93485b720b6edef80d1bc33c4f99d772fc17c766039e9','nodekey:9122bd587ae90984e3231e0f48e15aa8abcfbc1b3324becd1f3622bbbe534da1','discokey:7610d45f8d2d3d4d7774c43288a6d50cd798a832732613647caa15e96621a3e3','laptop-93','node067',21,'cli',NULL,NULL,'2025-02-07 13:42:35.535333727+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[3022:fc47:6534:7fe3:9d1e:8d49:75b:984b]:10998","60.241.100.13:15037","[9356:40f8:a98c:a1a9:18e6:e781:f169:4277]:63375"]','2025-01-31 12:06:30.121464114+01:00','2025-02-07 13:42:35.535828442+01:00',NULL,'100.64.0.62','fd7a:115c:a1e0::3e');
INSERT INTO nodes VALUES(68,'mkey:b1f44437d8d3550b23e7d3a79e6fb1c2649a48c2566d95dc308b78e56a1ce2f5','nodekey:17d7b53b408bcc2459fce9db6e689099b7a99de8ca26be948f2a0eebf71970c7','discokey:2af8a6603509410d88c13a6d39763e0109e8f422f27fc8da08d2e256dd7569b3','desktop-87','node068',22,'cli',NULL,NULL,'2025-02-07 13:37:14.673907509+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8ac8:a469:4cc:90b5:c84b:f4f:5cb:49e1]:35646","[d152:3a18:3826:ee28:a323:74d6:7140:ca5]:40749"]','2025-02-03 14:16:55.56431345+01:00','2025-02-07 13:37:15.115578974+01:00',NULL,'100.64.0.51','fd7a:115c:a1e0::33');
INSERT INTO nodes VALUES(69,'mkey:0a0aec355a4e4e478a9e73ac6141c7882ab29d1d14da893ba7442acc11bf6cbe','nodekey:5c3cbe65b07b0676fdc9eef42acb6f0a56196a20fa82d34429b6adc878aa4d0e','discokey:f813981e0cdb97880468aa23f9745b4b3ca367e3e9eac72c6631b8e2530a822b','desktop-75','node069',22,'cli',NULL,NULL,'2025-02-07 13:30:51.951476674+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[443d:d8da:884:82e4:de49:13e:8449:d06d]:43135","152.191.25.57:54747"]','2025-02-03 15:23:16.312084161+01:00','2025-02-07 13:30:51.951819286+01:00',NULL,'100.64.0.52','fd7a:115c:a1e0::34');
INSERT INTO nodes VALUES(70,'mkey:fa142bd90a16d891af17e0732fc3060af64e41d0ad7f0024afacbd941a538f88','nodekey:2ad7938dba6ec89f4d73dd9d8558d15efd3ef3b5b752a90e40a064835c073fc2','discokey:31457c9296771d81dd053d962b86845adc3ab09ae53f9ed42be57037a0ea2368','email-13','node070',21,'cli',NULL,NULL,'2025-02-07 13:37:15.228318848+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["7.34.191.227:52597","200.133.152.206:14119","28.101.69.72:35202"]','2025-02-03 18:09:35.161109801+01:00','2025-02-07 13:37:15.245827564+01:00',NULL,'100.64.0.53','fd7a:115c:a1e0::35');
INSERT INTO nodes VALUES(71,'mkey:fc9d5a1c4658644beeb3130cf62b19042698652298ef36899d41f588bec371ab','nodekey:d44ef585e416773d29e627cf9a6e590af9b676d23a0a816865d05d775517ab4b','discokey:0c87d487f7a4f4ec5e045ff0c83c1b6c54453f7afe0e5f13c7ce90746e18da49','lt-48','node071',21,'cli',NULL,NULL,'2025-02-07 13:37:36.853568516+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["126.19.171.233:19526","[91e1:a8d7:5c43:b695:4f5:b147:b5f7:9f75]:62218"]','2025-02-04 12:03:50.32663805+01:00','2025-02-07 13:37:36.85423361+01:00',NULL,'100.64.0.63','fd7a:115c:a1e0::3f');
INSERT INTO nodes VALUES(72,'mkey:a46b92cea88a9bac37dcb612a4a50dee75684f736c8c7f2aab812fa5fb9d463f','nodekey:1bbfdddf7b2a929a3da1e69236aa8b8fbd4b25d1839e57aaecf2ab910592bc78','discokey:c2188df6632aded7862de4b5d07c3993b3e908c59ce38f9d481f4840d85448c7','srv-06','node072',21,'cli',NULL,NULL,'2025-02-07 13:37:15.252280835+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[99f:9853:60cd:a4c5:e9d7:2a40:f86:742b]:782","[99cd:c956:e0f9:b633:5f8b:5c6a:50b1:571]:18474"]','2025-02-04 12:07:36.231437299+01:00','2025-02-07 13:37:15.256879188+01:00',NULL,'100.64.0.64','fd7a:115c:a1e0::40');
INSERT INTO nodes VALUES(73,'mkey:2c018031737bb172064fe31674acafe1b8b4d62d2b82db835e2c38061c5bfdbb','nodekey:575f781bb36f7c93cde4d9808e3dedef2c8999864ea1d4e5ee73fdd3d53ac217','discokey:00e3275941e7a0a73a1e5c44cea638a411c60bb2e257812e0f39152ec0c5a21b','lt-01','node073',21,'cli',NULL,NULL,'2025-02-07 13:37:46.354359607+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["56.80.126.49:13907","95.196.223.110:47343"]','2025-02-04 12:10:26.50545127+01:00','2025-02-07 13:37:46.354928354+01:00',NULL,'100.64.0.65','fd7a:115c:a1e0::41');
INSERT INTO nodes VALUES(74,'mkey:a5a8194cef984a1cc2081212405c10c8cc1061d3d00e6aa7e1415c854e3ded72','nodekey:ca37a131e58c14ebec3a6e179549d7c8742a31b42ed0e6e52aed138ecc176907','discokey:8a4990c19c547da50875ad00613118d5382717652b4ef9897a1d1c060c40a976','laptop-71','node074',21,'cli',NULL,NULL,'2025-02-07 13:37:15.235404491+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["114.141.127.86:11858","[d05b:3c4f:8402:823f:409f:87b2:4dab:4959]:58420"]','2025-02-06 17:33:12.557302525+01:00','2025-02-07 13:37:15.238509319+01:00',NULL,'100.64.0.67','fd7a:115c:a1e0::43');
INSERT INTO nodes VALUES(75,'mkey:fb413a3831a1db1639197bf6eb887a913ff044346d9fc07eeadc50aa96ae196f','nodekey:763f78cdd841a2859c2a7e1b00129ed1a527e97afc193da93d864263fb048c0e','discokey:1c658f44f2e30f60cd35d6d730625710bb86ca1873f0cc55f6a08f0fc62bd814','srv-20','node075',9,'cli',NULL,NULL,'2025-02-07 13:37:39.952195811+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["147.221.39.105:29051","146.211.135.172:35153"]','2025-02-06 18:23:55.709687186+01:00','2025-02-07 13:37:39.95290257+01:00',NULL,'100.64.0.66','fd7a:115c:a1e0::42');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(1,'2023-05-19 07:09:23.387641743+02:00','2023-05-22 09:48:18.908103256+02:00',NULL,3,'192.168.224.0/21',1,0,0);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-05-17 19:36:55.859473496+02:00','2023-05-17 19:36:55.859473496+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(2,'2023-05-17 19:36:57.059073465+02:00','2023-05-17 19:36:57.059073465+02:00',NULL,'user002','','',NULL,NULL,'');
INSERT INTO users VALUES(3,'2023-05-18 10:10:36.248939077+02:00','2023-05-18 10:10:36.248939077+02:00',NULL,'user003','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2023-06-10 09:06:13.920718561+02:00','2023-06-10 09:06:13.920718561+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(5,'2023-06-11 19:58:32.371218434+02:00','2023-06-11 19:58:32.371218434+02:00',NULL,'user005','','',NULL,NULL,'');
INSERT INTO users VALUES(6,'2023-06-17 19:39:53.031565686+02:00','2023-06-17 19:39:53.031565686+02:00',NULL,'user006','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2023-06-20 11:35:09.325846831+02:00','2023-06-20 11:35:09.325846831+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2023-06-21 22:47:48.196234382+02:00','2023-06-21 22:47:48.196234382+02:00',NULL,'user008','','',NULL,NULL,'');
INSERT INTO users VALUES(9,'2023-06-22 08:30:35.068995572+02:00','2023-06-22 08:30:35.068995572+02:00',NULL,'user009','','',NULL,NULL,'');
INSERT INTO users VALUES(10,'2023-07-03 10:18:32.123226+02:00','2023-07-03 10:18:32.123226+02:00',NULL,'user010','','',NULL,NULL,'');
INSERT INTO users VALUES(11,'2023-07-03 10:18:37.130387602+02:00','2023-07-03 10:18:37.130387602+02:00',NULL,'user011','','',NULL,NULL,'');
INSERT INTO users VALUES(12,'2023-12-15 08:05:06.013615212+01:00','2023-12-15 08:05:06.013615212+01:00',NULL,'user012','','',NULL,NULL,'');
INSERT INTO users VALUES(13,'2024-02-03 16:32:42.224977233+01:00','2024-02-03 16:32:42.224977233+01:00',NULL,'user013','','',NULL,NULL,'');
INSERT INTO users VALUES(14,'2024-05-03 10:12:38.220973042+02:00','2024-05-03 10:12:38.220973042+02:00',NULL,'user014','','',NULL,NULL,'');
INSERT INTO users VALUES(15,'2024-07-26 08:08:40.979783263+02:00','2024-07-26 08:08:40.979783263+02:00',NULL,'user015','','',NULL,NULL,'');
INSERT INTO users VALUES(16,'2024-08-05 17:32:02.878091894+02:00','2024-08-05 17:32:02.878091894+02:00',NULL,'user016','','',NULL,NULL,'');
INSERT INTO users VALUES(17,'2024-09-22 15:48:00.287392203+02:00','2024-09-22 15:48:00.287392203+02:00',NULL,'user017','','',NULL,NULL,'');
INSERT INTO users VALUES(18,'2024-12-10 13:55:11.256977421+01:00','2024-12-10 13:55:11.256977421+01:00',NULL,'user018','','',NULL,NULL,'');
INSERT INTO users VALUES(19,'2024-12-17 14:57:58.550971236+01:00','2024-12-17 14:57:58.550971236+01:00',NULL,'user019','','',NULL,NULL,'');
INSERT INTO users VALUES(20,'2024-12-17 15:02:08.053169491+01:00','2024-12-17 15:02:08.053169491+01:00',NULL,'user020','','',NULL,NULL,'');
INSERT INTO users VALUES(21,'2025-01-28 15:57:32.774456057+01:00','2025-02-06 17:43:41.935399542+01:00',NULL,'user021','','',NULL,'','');
INSERT INTO users VALUES(22,'2025-02-03 14:10:50.491924701+01:00','2025-02-03 14:10:50.491924701+01:00',NULL,'user022','','',NULL,'','');
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,124 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
INSERT INTO migrations VALUES('202501311657');
INSERT INTO migrations VALUES('202502070949');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'463a8b372963aeaca12400faa0c7ea29e9bfa3b4c59e9622',3,0,0,1,'2023-05-19 05:09:19.66636462+00:00','2023-05-19 05:14:19.664224869+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'77a019cb12c0d0b9347a17ab23fa4c87983814fe36bb2fbb',14,0,0,0,'2024-05-03 08:13:55.8614948+00:00','2024-05-04 08:13:55.85782156+00:00',NULL);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:0ea01e8cd608548a171ebcedc16da73b25ec18d58861be7a6b4274eb17baf6ba','nodekey:0fcf591dc1997c1d7388a3835bd24dae48240e5b03b6a7f5f33b2e813d222bcf','discokey:ed27f0b3c04222f0d05bfbc6fb5787338275ed0e32fd42fe68c669aca0f3d7a4','desktop-54','node001',2,'cli',NULL,NULL,'2025-02-21 16:47:31.967030967+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b8f0:cf44:22c8:82d1:f79:c3eb:9144:c24f]:6142","[8e25:af1:e31a:8fcc:7dcf:be1:a3c9:ed6a]:38766","[37a1:215f:bf3d:3fb1:6399:f7cb:4048:3ca8]:51666","137.242.125.72:25376","86.84.184.63:26062","[c187:a8:1181:8321:28ab:fe72:b0b8:8ec6]:41236"]','2023-05-17 19:38:13.531518257+02:00','2025-02-21 16:47:31.967134366+01:00',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(2,'mkey:77e0289c8c37caae9d3d7b6c851db0beb9e47fc8854dbe2d5bb0d7a33d377c56','nodekey:7b550e852203d47984bce22eaca3a6a738e711869c79932b087b848cf33c8065','discokey:d1a6b93cedd0e850997eeb0ff84be2d169d15b8b29192dffbf49dea812d50874','web-87','node002',1,'cli',NULL,NULL,'2025-02-25 18:07:33.299494262+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["149.96.226.131:35537","84.23.188.83:48876","44.184.117.89:36643","90.223.136.253:7056","[e43c:be7:7f4e:8217:a009:7f9d:a510:1af6]:18872","[3a86:865b:2f4c:f3b7:88a0:4aa2:f05d:c3fd]:47680","86.50.30.30:18216","[fdbe:7908:805e:6c8f:47c2:2c87:b1c4:44]:48470","188.237.187.170:7622"]','2023-05-18 10:09:21.757289398+02:00','2025-02-25 18:07:33.299970499+01:00',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(3,'mkey:538f91fe9e485697ce13f9444ee0dadf2aaaed712fdfa03ba102113c6505db37','nodekey:1936bdc567d6758b11b2cc06ea7ff74bb933a44421fb17323965d5a402e39783','discokey:e8b762a384d644175f3b4e4fd36867b2c435e03eb0bf6b9e7ebd4f0ce83c13ef','lt-57','node003',3,'authkey','[]',1,'2025-02-14 06:23:29.821940467+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f6d5:e904:28e7:a5a4:12a3:96d8:9391:b22c]:37336","113.59.7.205:48432"]','2023-05-19 07:09:21.399903526+02:00','2025-02-14 06:23:29.828817276+01:00',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:12afa721b0310fd9cf7501a19e5f23a2d33c87f989a9b0233bc09e8eb9e5eaa2','nodekey:83e8f99465cfd0ef79190bfb341bb742b39d9ddd7cfeab237153b58858a2fed2','discokey:d4fdc314c7b73e21589efef171f10158379ade1adbdc281482a62c6c20fc2ed8','lt-50','node004',4,'cli',NULL,NULL,'2025-02-25 18:57:43.626901249+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8105:c5c2:647f:e97e:85b7:577b:20b0:e4f]:16947","1.79.159.39:34092"]','2023-06-10 09:31:51.940506933+02:00','2025-02-25 18:57:43.62738857+01:00',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(5,'mkey:517d332699122618020754ebd6b7aa342136392cbb3186a181c32bad87cfa666','nodekey:ab36644fc8e56ce3816124f4e51be0a2e74505b0b6669ec7dac0001ec3774bf5','discokey:f1413ef26f1c11540e6d0b3f8ae7124e8b2eeffc9a330016cab23036f5b4fcf6','srv-15','node005',4,'cli',NULL,NULL,'2025-02-25 18:54:08.745255864+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["66.84.158.199:63451","47.94.115.240:6677","19.74.30.92:1284","213.110.62.40:49373","222.60.90.114:9445"]','2023-06-11 13:56:42.694329408+02:00','2025-02-25 18:54:08.745544477+01:00',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(6,'mkey:cc260b25fa19bf6d04469bdd96eab67578ec80bb0f2c4e3c4e188050951f8ff4','nodekey:d2730f52d9efa38cc46e37ba658c8bc6df42a4dac4b4fa3a9cc7f284cc1a17a0','discokey:665b19ab4efaa1bdbe9cf27d21a57be739c2713ac442f6342cfc988e410d66e3','web-56','node006',4,'cli',NULL,NULL,'2025-02-25 18:56:58.143735821+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[fece:76ed:4c23:1e89:f225:97a1:94be:b5c4]:33472","[e1e6:a14:535a:668b:698:f125:543f:b5b7]:31740","[b8e3:18de:5ece:3e24:8bbf:1cbd:d27c:7de]:53522","[e65d:59b5:f599:8596:2bc9:56b7:820a:8c12]:12277","[8ddd:4aae:2b94:4c1a:d05f:65d2:2bdb:b400]:42839"]','2023-06-11 13:57:44.975695604+02:00','2025-02-25 18:56:58.144115128+01:00',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(7,'mkey:b1d6228a1bad37f4e8491772fe83a3e7e4832fb93f8a7aeef1fe97a1a1ec6ee0','nodekey:f352383d311b4f323d0a5ae82c06ac24230a6a98671f00b09a2300c6d7413b36','discokey:92304c75e1c7d328f4445ac6f278f66244f11b66ac6e89060b498b0fe122f096','desktop-85','node007',4,'cli',NULL,NULL,'2025-02-25 18:57:34.843267809+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2e31:d5e9:a2fb:d204:f840:3746:7248:ba38]:62726","[cbb6:53d4:54ce:cd07:cef3:87ea:7ebe:e5a3]:12262","[bb94:d03c:901b:a7d6:d7d:955d:7df4:1c2a]:24266","[489b:6c59:1877:6215:ddc8:57f8:78dc:321c]:3025","77.213.161.20:47662","[adea:86d3:b312:f445:d835:6023:f1f:f928]:27483"]','2023-06-11 14:16:56.951313537+02:00','2025-02-25 18:57:34.843605919+01:00',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(8,'mkey:1ec07ddb5eefc8bf45fc902699a9b656dc6c4be81224aff81ef4b14990f02b76','nodekey:f2ad6282c57e4ac666137b69e68805d137e0d002eb05f6173a76b38965b5a877','discokey:6bcc988157ed256c25d0487285b8bd02379ece8f0292608f80f4e4ccfaeca269','desktop-82','node008',5,'cli',NULL,NULL,'2025-02-25 18:58:08.246285374+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["31.85.36.236:46674","[80ab:9956:c1bc:b242:cd97:6bb:52e3:10fb]:47368","[4ddb:3188:c8f2:6122:e983:bf33:d2d4:74bf]:25781"]','2023-06-11 19:59:30.401970393+02:00','2025-02-25 18:58:08.24660639+01:00',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(9,'mkey:f436d5d56dca10e95dac89d2d2b10629a7d1888543378d56d6a66c4ed5e8acbd','nodekey:200327faa3d157c1ab859e71a27bfd52642b863352a219146e7fcae245b0b35f','discokey:08d0b384d256d12f19297672b41d62b87174af0b8332602760dd6615f8ceb796','db-78','node009',6,'cli',NULL,NULL,'2025-02-11 14:57:51.798862802+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f78c:8abc:854e:670e:1d14:fb13:d0a0:ad7a]:33635","41.172.94.101:32111"]','2023-06-17 19:40:45.468789461+02:00','2025-02-11 14:57:53.417438918+01:00',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(10,'mkey:628fa7eba9bc1474eeb62eedf4e6b7e5b970a3acaeb2e020f4de7bd2aad547ef','nodekey:c105625e67654c70809a72beddc9ab34e7da931e4e7b72784c5d2781acbfb9c6','discokey:0d7060f2779a56c357749e61ba7b1cbd03a0d0d8397c9989c54087e1a80b5224','web-49','node010',6,'cli',NULL,NULL,'2025-02-25 18:16:38.447549074+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[69bc:fe73:f6c7:31b2:bc4f:1a95:4676:201d]:4806","[d794:c918:b0e8:6023:d7cd:709:79eb:23f7]:56801","113.147.88.203:61138","22.207.212.228:27547","[2c3e:2260:8c34:275:2287:b721:1bdb:d462]:59540"]','2023-06-20 11:18:35.905417341+02:00','2025-02-25 18:16:38.448089273+01:00',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(11,'mkey:4d2ff8526b10e056a5d073d5640fd28002ca21b561c55407175712a98e37ada7','nodekey:a1835798e4fefbece3000abb9afdd3cb01e5a4eebafc1218ed627cde2175c1f1','discokey:24b8f6da3ef9e024e273918de8869fdfebc45f789d14c4a50a592cc27259f1c1','db-64','node011',7,'cli',NULL,NULL,'2025-02-25 16:12:02.791603536+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f1ba:2aea:9e9e:2802:ebb9:ba04:a564:7998]:52919","[ede2:462a:f99c:24c3:b1b5:8b97:abe2:3ddb]:65141","[dfe7:6f6b:a382:4fc:a3f6:eb9:9ebc:5798]:1474","56.63.78.181:15200"]','2023-06-20 11:35:15.063855316+02:00','2025-02-25 16:12:02.791828881+01:00',NULL,'100.64.0.11','fd7a:115c:a1e0::b');
INSERT INTO nodes VALUES(12,'mkey:80fb6f55cbac10695c455ecd74fdd59ae5e804ef27a53085450e713eb6afc4ad','nodekey:8b94382fa21050586620d8a5ee69649c9e854b3dfe06f1341e85768a0f6a1185','discokey:27c408f43b0d0857a1897d995513d907107d8e6f04c6a3bc5826d066324f2303','email-92','node012',5,'cli',NULL,NULL,'2025-02-25 18:57:33.682368055+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[743f:8ead:64df:d533:ccdd:f29a:254:97ee]:41637","[f780:17d4:440b:f400:cb10:dc8d:5698:e318]:37997","33.51.84.119:46756"]','2023-06-20 18:22:35.061914624+02:00','2025-02-25 18:57:33.682775689+01:00',NULL,'100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(18,'mkey:f11332335d9f1f9d4bfc8cf9bf4edc0c958d4e4364b7dcde3c67d847f7d05edb','nodekey:e97d97a2751ef3533818907c9f24acf3270e3824f2294bb9a36d60ca196e161e','discokey:412b0eee00b68721d9169fc81039b9cda6cf57143e4cae8f7c417db15b83411a','web-18','node018',9,'cli',NULL,NULL,'2025-02-25 14:45:50.465939403+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2acf:3f32:1763:5d21:88a:4af:8779:1b1d]:36283","84.177.251.38:32968","[3138:83c6:ae09:a073:7888:71e0:494:3863]:59700","191.156.96.176:5489"]','2023-06-22 08:30:54.08720463+02:00','2025-02-25 14:45:50.466242342+01:00',NULL,'100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(20,'mkey:157706346bfe3502b6e24a84efa59b1a151be08f5a260ff96c72a734c1da1390','nodekey:139a99de286f52c55bdd61e932827c9d7cb84101a698df3576bdffbeedbf654d','discokey:293abc1a1cf2921e7961f5753cc39097956648bab47879791afb12ea03a4e6dd','lt-42','node020',11,'cli',NULL,NULL,'2025-02-24 19:54:14.700663055+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ce0f:9f05:96dc:a47d:edcd:1c25:f578:7551]:30363","[cc06:9c56:919a:2341:4ef7:7f28:c8ca:2a5c]:30788","[7b81:52eb:f4e9:e74d:905:79d4:67b1:d359]:13795","81.17.18.155:10091"]','2023-07-10 12:40:34.838579199+02:00','2025-02-24 19:54:14.700825212+01:00',NULL,'100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(21,'mkey:8bc474d6d0d812ab011b7748675802bd9d4af70c2edab0da6c682a0cf1ca34f8','nodekey:2cb4a0ab98e83dafb20621dcfec33cd5fa7fa99b97998546cb6796249bdba88a','discokey:e341e99f352acb61779807aea844516d7e9e220c58699f09232bcee105e88797','lt-43','node021',11,'cli','null',NULL,'2023-11-20 07:19:19.447470862+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["63.3.67.150:22907","[77ac:562:7c4c:438a:6ec:be48:743d:47b1]:11349","[33cd:731c:f110:9b45:66b5:de81:1daa:757f]:5997","[d618:5830:8a37:fbe4:3b37:a35c:fad9:11d1]:57112"]','2023-07-10 12:42:43.290469734+02:00','2024-09-18 16:15:14.03886353+02:00',NULL,'100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(22,'mkey:170eb5e825f19f37d8e8747d888a79962d96acab073459e889d64d906e9a4a7f','nodekey:722321c00084d0152c13e34375b006f3ff2b95507685d13aa2df04093561df8b','discokey:c0463a2785b1741b3ce35422310ccd59f55edee22f5b64fdada2a95abfd0ae74','laptop-89','node022',6,'cli',NULL,NULL,'2025-02-13 18:41:19.151025389+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["194.185.67.128:22758","[722e:3c42:d444:e150:3b32:135c:68:80fa]:3684","132.110.176.16:63801","168.165.127.136:13273"]','2023-08-05 12:08:48.132161695+02:00','2025-02-13 18:41:19.151860126+01:00',NULL,'100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(23,'mkey:0ac434671e1b07546381d5dd36d4e04dbf7a098f226d7173e4b7e766c18283f2','nodekey:dc35ef6da42fbb0f4b90e5cf935b0012ab62fa61016b17d8a3a24240004fa3b4','discokey:5f7118e434c174dbac710b1d088db6213ca894ca3912a92688110ed5f96eb37d','laptop-54','node023',12,'cli','null',NULL,'2024-12-07 19:25:56.935152754+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["146.144.83.178:46323","1.236.14.11:13477","184.41.32.72:1026","[f136:8b69:185a:7ec7:94a1:ca58:5d95:ba9f]:21119","51.158.48.68:23441"]','2023-12-15 08:05:56.592241745+01:00','2024-12-07 19:25:56.935317645+01:00',NULL,'100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(24,'mkey:27effcc5ab9b8bc295f0a76a09e753e7bb6b0c4c33343f59635494e1d717c82c','nodekey:c663007fc1b770065de8303e6bcd9ad7184c345795625591c3e0fe8304b6c29f','discokey:0de43076bf8295b5281d848e1515c304e3f541d5b10b9160fea430a6272ab160','desktop-77','node024',12,'cli',NULL,NULL,'2025-02-25 14:31:30.623705545+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2b5d:522b:8ced:49a8:d0dc:bc0a:81ba:7f84]:30767","212.18.227.41:50735","[f774:e89b:980f:975d:fd3e:93f:a9b5:2034]:46054","[7225:d0ce:d29a:59d8:f596:b945:9a02:29ed]:43419","[5a76:d5b0:b51d:6b56:afaa:3968:277b:192c]:19250"]','2023-12-15 11:14:36.765183054+01:00','2025-02-25 14:31:30.623800675+01:00',NULL,'100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(25,'mkey:247cad9ffd7d108f553e7658db14bbad992332458abb9b4bc5a0c0d3a13ead9f','nodekey:bbfb569ac8a34cf4d59d2bc13d0f03660d24aedf22c61b56510a65d20bdf0812','discokey:61f92520602549b9bc684eeed3186f608a38e13794d06d4b8d165c4efbb69a24','laptop-29','node025',6,'cli',NULL,NULL,'2025-02-25 18:56:13.569853699+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5b7b:e424:ea77:aa8a:f835:d6bb:2e1f:52ea]:19152","[bb06:d322:7cec:426b:ef38:55d0:e7ce:95bc]:31597","[320d:6314:eaa2:a098:8594:977d:27b:8442]:12827","163.235.127.125:61230"]','2024-01-05 17:32:40.940566279+01:00','2025-02-25 18:56:13.57010639+01:00',NULL,'100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(26,'mkey:d623495ccdc12a3f219322cf53458a85c29b8795ceff5cef5338bb9c26e329dc','nodekey:781ad44c939f14168ec1c22c3fa2c5422f5ff1a5b0fc163fa80e6ace4e20c4a2','discokey:c474b4d7b9883e70466b6240b885a2a71dbe6efb0e8c84b85277beb584f25690','email-47','node026',6,'cli',NULL,NULL,'2025-02-25 18:57:44.753081033+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["173.144.3.182:33138","[975a:978:5cfb:5e5a:1b6:d272:a1c1:50dd]:3245","[e6e4:7cfc:9ce:b47:62f5:b64e:d2e4:9015]:42369","[26c6:541b:69af:974a:8ea8:6bd0:7c4d:5a82]:10571","[c898:1525:ebe8:704a:243b:de9d:b8c:ea69]:22747","32.167.123.100:57075","[2c67:a9f3:3163:c675:3386:2447:1cc:ed3a]:42590","64.137.67.1:56198","163.42.128.241:47535","49.160.22.202:42427"]','2024-01-05 17:34:19.811670479+01:00','2025-02-25 18:57:44.753480656+01:00',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
INSERT INTO nodes VALUES(27,'mkey:dc2bfab4553c0294e57f034001e3d575413ee8b0622e788050341c29b702f8e0','nodekey:9fd699021ab41ed4911faade849d0d702debfa1ef735a60eff8c1cae87b820c3','discokey:dc9c5f140c9ab0afaf55756f956a5fb53466ac0480c395aed0a4b481cc775679','srv-61','node027',6,'cli','null',NULL,'2024-01-16 14:32:21.570104175+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a542:b648:e2d9:5461:2ac4:6b34:77a8:ff65]:55609","106.52.35.144:41091","[537d:7a83:c891:ac8:9460:e49:e769:988b]:55062","50.23.199.223:4814","[a2b8:ea55:f9e3:2c00:f423:8c56:7fec:c617]:53793","[ed88:2277:3c9a:4f64:a25e:5b41:a3ca:e904]:27852"]','2024-01-05 17:48:25.466030859+01:00','2024-09-18 16:15:14.040766068+02:00',NULL,'100.64.0.22','fd7a:115c:a1e0::16');
INSERT INTO nodes VALUES(28,'mkey:08347db9fbe8e5e7a968c2ab9ddd1ff530ea98163c0bab7769316307545f4d46','nodekey:b6b03efd7deb52dbe0298708ea37400510ab7589b0b1787eac1a5f9b50aa7c80','discokey:6a0ab2f3329d9fe5f50c76f9f3f1d2e797574af93d823a511df57f45414f647e','srv-42','node028',7,'cli',NULL,NULL,'2025-02-25 17:11:29.962245449+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["42.99.149.47:5231","146.122.164.252:36824","16.15.205.75:58574","82.136.149.34:28707"]','2024-01-15 09:34:54.847632697+01:00','2025-02-25 17:11:29.962361262+01:00',NULL,'100.64.0.23','fd7a:115c:a1e0::17');
INSERT INTO nodes VALUES(29,'mkey:4a6e46330ccd4b3026337cdef37485c27592babda329107565c2a19d97253dcc','nodekey:17de47da1955a8a034788ae671c34fb10083568bf9e2f7494276cb2636065246','discokey:449f5f35a3507974cf03e3ac5c055d890de5122f57a7c2d84a0d3b324998607e','desktop-17','node029',7,'cli',NULL,NULL,'2025-02-11 14:54:59.936098654+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c2f1:82ab:922a:9b9d:f53d:a0b3:bccd:f6af]:299","[d28b:7b33:1f88:7583:7ed7:a923:4c90:9ee0]:62318","[68e3:a070:f02c:708c:a057:b579:aee9:4d25]:11747","[7224:b76a:cd04:e6d2:67fd:fec0:2f14:1837]:29002","173.82.71.57:3159"]','2024-01-15 15:18:12.2871978+01:00','2025-02-11 14:54:59.936147608+01:00',NULL,'100.64.0.24','fd7a:115c:a1e0::18');
INSERT INTO nodes VALUES(30,'mkey:26f1059c45c12a8e56cd57ba6db33dfe104eac76103327af49622cb7810fab7d','nodekey:b157bbdc37aa4634b8d69d6fbc7670780fff69337713176a11f893afafa2a9bc','discokey:4c8c175d0e61ca8f7b2de92a1033cb9be95eaeaf09e9395c767afa5afdf2d9b5','desktop-64','node030',7,'cli','null',NULL,'2024-02-05 12:14:40.065688294+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8a1a:5c17:bb81:bb69:c7db:3513:f14c:ca2d]:52077","123.235.220.59:59925","155.210.184.45:60093","[963:536a:33e9:99fb:c204:d59c:29a8:ac18]:39005","[e84c:35c4:4bd9:a100:c271:8921:ca7:5901]:21828"]','2024-01-15 15:21:43.217136004+01:00','2024-09-18 16:15:14.041757308+02:00',NULL,'100.64.0.25','fd7a:115c:a1e0::19');
INSERT INTO nodes VALUES(31,'mkey:ef048095dd3e937a8617f18797ed42d2c4513d07126dc419a466f257982113d1','nodekey:1c6c367df9b85ab5e1618c70c0a4f8b22e2eeea77523b40059c3ebfef0f4057f','discokey:80fb63a98202437504c700e582eddf800b02dc654577bb95796c60cdf1176793','lt-55','node031',7,'cli','null',NULL,'2024-02-22 08:35:27.098819037+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[cc02:5592:3738:a2ab:8c55:97bf:a5b8:24e6]:41616","129.130.98.189:47833","[99c0:d769:2f38:10e9:c01a:e3d:898e:afc]:17505","[3423:afbf:aa2:e156:81df:bbd3:412a:df65]:5125"]','2024-01-29 16:05:35.338524634+01:00','2024-09-18 16:15:14.042191514+02:00',NULL,'100.64.0.26','fd7a:115c:a1e0::1a');
INSERT INTO nodes VALUES(32,'mkey:5b0e391e12914bcbcc6b415d9dd72937d74f9ce92a22c6ec938eb749962ee6ce','nodekey:4fa73acfb54cb140dad6b02bc853f6360f5ed160f819dc57701ad9a4caae9782','discokey:d3e90723a3b90eea513e7710ccaf25f68c0a2d60a85e3d4b9e4385335fddf8e9','srv-15','node032',7,'cli','null',NULL,'2024-04-09 13:59:43.37062537+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[14bd:ee53:6776:c1c0:124a:efbf:38cc:b312]:62180","85.234.248.186:20429"]','2024-01-30 10:41:58.31917869+01:00','2024-09-18 16:15:14.042506082+02:00',NULL,'100.64.0.27','fd7a:115c:a1e0::1b');
INSERT INTO nodes VALUES(33,'mkey:ba179b51f3540e619eaac9a6d4bc67403daa7c3cf28a6b579087cd6d284501b4','nodekey:246fadfe2a3606f043aca1fc1fa31b79e9eef9c21ec67e72425e05576707b3c6','discokey:5c64c1a08b88425b6e1e2971f950708d38f951d2d5eed2b85df8dd7d1bb88a44','desktop-32','node033',13,'cli',NULL,NULL,'2025-02-25 00:23:14.381890489+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["106.67.113.92:45634","85.199.78.110:6716","[bc29:715c:cdce:f1f6:8630:4929:ea1e:5c03]:10918","[af8:f5e8:32f0:75ee:d351:c0e9:78e:93d9]:12624"]','2024-02-03 16:33:26.706408143+01:00','2025-02-25 00:23:14.38239676+01:00',NULL,'100.64.0.28','fd7a:115c:a1e0::1c');
INSERT INTO nodes VALUES(34,'mkey:6fe02bbbdd40bb09e8aa74cf66b40b5b94f227690fd804a33242f56e18bee64e','nodekey:acc333e66d45e660ff4a31a152340d391547ebef1056f5f046624b629389bfd3','discokey:cf4a1217f85585d74fc5138af6ed9b78a29a9d4f12ad2e1beac660816d8c7b3f','lt-74','node034',13,'cli',NULL,NULL,'2025-02-25 16:49:04.386505728+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[1092:57ce:a60b:141d:ba79:79a3:91ed:66b8]:11037","[f766:14e5:6acc:ba40:8b28:59b7:ef7f:cd51]:46293","[c:e6fc:18ea:2e45:6bef:c1c1:f84e:b1e2]:62296"]','2024-02-03 16:42:32.683785672+01:00','2025-02-25 16:49:04.386771772+01:00',NULL,'100.64.0.29','fd7a:115c:a1e0::1d');
INSERT INTO nodes VALUES(35,'mkey:f95240eb788522b37f5513f0253f8bdab2ccf7594ffbf9bb77945fd67e598c05','nodekey:f5a6f47f5a34b4f4c6883e46fb52c0a5f7ca2ce17397cbba751efa8736e0066d','discokey:4dc728a0c0de0ce87530a47dda426d5bf6ad1b2f6cdefcc819c29c1015c3131e','web-44','node035',5,'cli',NULL,NULL,'2025-02-18 17:59:56.043915212+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["136.113.252.147:325","139.180.210.231:32286","171.29.58.211:2336"]','2024-02-03 16:51:52.010016072+01:00','2025-02-18 17:59:56.044175137+01:00',NULL,'100.64.0.30','fd7a:115c:a1e0::1e');
INSERT INTO nodes VALUES(36,'mkey:8ac09adfe44b8e60665601726c99627216e71b49ef7e8cc58ae6ba4f997c8652','nodekey:62d8af3310a7f27d84b931eaaa7ee110fe7fe46ea3ca8c817e47b9ce456c9b4a','discokey:bd31ae97729ac879d9b57866a69abb521248fb7fd5663d2149857d4dbf023d85','web-93','node036',13,'cli','null',NULL,'2025-01-19 14:01:48.956567669+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7e9e:219a:507d:d3d:cc77:6195:7ce3:b30e]:25018","203.251.190.122:19081","49.144.40.103:7674","[a641:3f06:63bf:b716:4658:1e5b:ac6f:e14]:13490","197.206.147.31:58506","[b1e8:68a0:4017:a243:61d0:b303:7860:18e]:28633","[e5b8:6c78:ce2f:cf6f:13fb:401f:8223:3f04]:54121"]','2024-02-09 12:34:57.879970954+01:00','2025-01-19 14:01:48.956830267+01:00',NULL,'100.64.0.31','fd7a:115c:a1e0::1f');
INSERT INTO nodes VALUES(37,'mkey:c371756901cab84ae432a7d201e47232b008ef55effcf90341f24de7dfc55bb0','nodekey:0f858ae8a6492e1cc63fb502c6453ae90e8723f8b4ea8eba8c67f9f5114dec39','discokey:b6fc59b2a9ec7ddf1ae9573245cd3271259f964cdd730b811fabb019eccb3c81','db-47','node037',5,'cli',NULL,NULL,'2025-02-25 18:57:09.0895949+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b8c2:c792:3329:2c93:f94b:a948:7d11:b9f2]:908","[5925:353c:bd9a:f42e:1916:45b4:c170:e515]:18400","[c2a5:cc2f:e2e8:573f:7b01:4aa:8a1a:fd71]:32146","193.82.125.68:38601","[e9da:1552:e478:f920:c3d6:ff41:9e86:e27e]:48481","[c31d:dd18:321:589:11fa:d85b:695f:1fca]:43064","168.4.78.117:48474","90.45.218.0:29326","90.233.46.138:29846"]','2024-02-27 12:14:40.452601042+01:00','2025-02-25 18:57:09.090070104+01:00',NULL,'100.64.0.32','fd7a:115c:a1e0::20');
INSERT INTO nodes VALUES(38,'mkey:86d359e5681ac6a642788f26d2dfa71c65883af4a1af67a290d46fc3861b221d','nodekey:33aa0fc0fb105997472a1e1024710288ec481753149da6c50d79c9d3c59bef0a','discokey:79d066251321d58c1359edfc9b774b33b2dc46797aeb5b70ee3dc9f1be415a42','web-20','node038',6,'cli',NULL,NULL,'2025-02-25 16:11:28.263125427+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["99.62.182.69:45368","41.96.84.44:45622","[a81d:f0ad:7a29:65e6:2d93:238e:99a2:eb30]:50585"]','2024-05-22 08:08:16.045350656+02:00','2025-02-25 16:11:28.291976461+01:00',NULL,'100.64.0.33','fd7a:115c:a1e0::21');
INSERT INTO nodes VALUES(42,'mkey:10e4ff66fdd37fb54f6dcb0e42f483a15b6340610acc3a4517c24f0f350b5a9a','nodekey:f20786f9c7edc967d0b415bbcce39468441af3b531ff15656c0683d3f328720a','discokey:4e1247022b7ddf4b30d00043fded8b0132f598feeb77dd34d2fc32f97a1d2c2a','lt-05','node042',14,'cli',NULL,NULL,'2025-02-14 10:43:03.67095554+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a393:f17f:6728:82e4:c1e7:2367:82d0:daaf]:18560","[d192:9897:4cd7:bfb5:de36:fc03:8cf4:c60d]:25096","212.199.67.213:11150"]','2024-07-03 11:12:29.418355657+02:00','2025-02-14 10:43:03.671476921+01:00',NULL,'100.64.0.37','fd7a:115c:a1e0::25');
INSERT INTO nodes VALUES(43,'mkey:33e764ae40265089c5e7dbfc8571aa23bb390fc7e1e8bd2f3e0cd6891c308214','nodekey:c444c9ff652ba29181a5f7fdf991f91f704e6698237ee18b0649c81879ec932f','discokey:2e1db3a1eea266673acf7826aa44b5aa6fdd23c6ba41330562b37c5a523ba358','laptop-81','node043',14,'cli',NULL,NULL,'2025-02-23 16:43:04.441516493+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["190.179.215.222:61930","45.131.187.230:22916","[510f:af99:ed4d:f53a:fc21:8640:9ad9:4930]:16050","[5ea4:3410:eaa2:9da:b8d:b61a:2d9d:edaa]:3526","209.107.206.184:46974"]','2024-07-03 14:48:50.263910778+02:00','2025-02-23 16:43:04.441841303+01:00',NULL,'100.64.0.34','fd7a:115c:a1e0::22');
INSERT INTO nodes VALUES(44,'mkey:1099debb0ba187ef1f43f001c75abc118eaf017bf3bd6b48ca333fb046b98de9','nodekey:d49ef9ad4a7ecbdabcd24cae92d9ac32fbb765467cbc20abe61b4bda6ef15f1f','discokey:9f2faf39514eccb7f3d7d66ebcaf804474f75284d8b1aedbf97aee6ccdf47ed5','laptop-84','node044',14,'cli',NULL,NULL,'2025-02-11 14:57:51.787233089+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[183d:f2d6:b80:36c5:318e:64e9:7f4a:b389]:12440","169.173.198.12:15274","[e5df:1889:6ac5:7d21:4dfd:614b:7eb9:d93c]:792","119.123.40.237:58615","[415:97d8:4ecb:2a7d:14ae:64f3:7a01:471f]:15771"]','2024-07-03 15:23:48.066044194+02:00','2025-02-11 14:57:51.796185225+01:00',NULL,'100.64.0.35','fd7a:115c:a1e0::23');
INSERT INTO nodes VALUES(45,'mkey:29eedea8083105a21470a51112b2486ae4c79221e2b6b17e4c3c84f965013513','nodekey:b3249157ebc705f134a366e28beb2d7646a40bc4171bb6d6fece1e750c85379b','discokey:64cb6eaee39eca7e3ad7f1225c216bf2826a8a951b91a631cfacf3b5ec99c2db','web-31','node045',14,'cli',NULL,NULL,'2025-02-11 14:57:51.802536554+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["14.153.231.75:19825","[acd8:3779:7b6c:3a71:c15a:e323:a721:c9a7]:63377","[6816:3377:edb0:3f8e:a65b:bd60:461b:ceb]:24642","147.3.7.139:46940","[7526:4960:73a9:911a:1fbf:92bf:1219:a6bf]:25440","[360:d312:e59c:79e0:a7e4:2295:caa0:946e]:17493"]','2024-07-03 15:54:01.706018896+02:00','2025-02-11 14:57:51.804667794+01:00',NULL,'100.64.0.36','fd7a:115c:a1e0::24');
INSERT INTO nodes VALUES(46,'mkey:05f627f2614a4b7cf260a96650b0c5c62fcbfa993480253fd89771ad3b16ca2f','nodekey:678b922f6004223f9163155c62b8877ca663b1ecb3327b2c64453527f9c0f6a1','discokey:b77917efffd1020f1b03202e74265e308bc18a12e863bb04b94aa814cbc8e9bc','web-60','node046',14,'cli',NULL,NULL,'2025-02-11 14:57:51.964197644+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[89d4:f6c6:ccf6:b19d:3b76:642e:7a36:d229]:930","[ea0e:83e6:309f:c748:3314:72ba:996c:bfdd]:40599","136.29.193.173:47997","6.170.76.62:28497","[5cff:a345:4885:7b07:98a4:bcfb:f622:b94d]:58641"]','2024-07-03 19:38:07.783745318+02:00','2025-02-11 14:57:52.805260039+01:00',NULL,'100.64.0.38','fd7a:115c:a1e0::26');
INSERT INTO nodes VALUES(47,'mkey:bed87b73eea00bf3d74184d911253df54cc7697f2dd023cfd836b801efd82518','nodekey:2146154fd3fb48377f6bf4cbf08f555008471b493a90a0614e5ecf76c338bc99','discokey:c3ea2fb606807d06b1ed3e10219fee70456d1db0208d2e73a081a258992e4316','lt-41','node047',14,'cli',NULL,NULL,'2025-02-11 14:57:51.975754077+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["83.69.120.197:25918","[3f3a:e533:53b0:bf90:95bb:fe47:d61:516b]:2433"]','2024-07-04 10:38:08.344092869+02:00','2025-02-11 14:57:52.006716436+01:00',NULL,'100.64.0.39','fd7a:115c:a1e0::27');
INSERT INTO nodes VALUES(48,'mkey:8fede09a569258fc0fd7ebfbd12b2b4e8c2f4ce95c43ab0d89e41ab3998e6d24','nodekey:63af6498d4fb0e1e8312e3ec6a1639b178c051a271f33f213324e3ac1af53e17','discokey:a1e793aa09c20360cb4ef57e7dc42171a0abbc9f562140609e930ba5b7b12e83','email-92','node048',15,'cli','null',NULL,'2024-10-20 13:53:33.831192385+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[33c0:859c:4a78:8bdb:359e:31e4:1e71:7e39]:50383","[3aab:52a2:b9d3:1816:5627:336:6c60:57d7]:13486","22.83.180.41:14147","26.126.135.206:7777","[8706:d109:5006:f832:dca7:58e4:4451:be15]:15180","177.4.27.29:60895"]','2024-07-26 08:09:56.608302315+02:00','2024-10-20 13:53:33.831387627+02:00',NULL,'100.64.0.40','fd7a:115c:a1e0::28');
INSERT INTO nodes VALUES(49,'mkey:13b8d4cafbdb8e9ab77928219aa57bf778878866ad8e6108b60aaab8dc8cec36','nodekey:17cefd68f8a9cc20b3d4fd93598f77ddfd6bd5a7e6e4b49861f9faad8623e0ef','discokey:939a04ddd2f9a24468e07ee7924dbb7a7662c1e8a1b67426f57fd48c7394448b','desktop-40','node049',16,'cli','null',NULL,'2024-09-19 09:07:18.28136023+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[19b0:8be2:708:d27f:4d3d:3c93:9979:e9e8]:50438","129.0.5.112:19015","[91e2:54c6:93fb:ec32:6ab4:186d:81cb:b815]:37323"]','2024-08-05 17:32:41.937626584+02:00','2024-09-19 09:07:18.281618912+02:00',NULL,'100.64.0.41','fd7a:115c:a1e0::29');
INSERT INTO nodes VALUES(50,'mkey:03979d5446bb3f596bf0234d81ca84482eacb132e874ceda6cc2703422cd728c','nodekey:805c03cada525f14ee90d28ea02b23a3f57b470c793314872ad9daacf6c6484e','discokey:eb4135e1cc73a3c6b513d8cc04ca0c55a2aef7b0009845fa1d2036488aadf0f8','desktop-02','node050',10,'cli','null',NULL,'2024-08-07 10:10:06.595550455+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9175:498d:64ac:4342:2eac:ffa1:99fd:d109]:21202","[5cba:56ef:db08:320c:333a:541f:605c:44d5]:57469","150.211.2.236:50360","203.180.122.83:13344","63.162.234.32:11653","[6b63:f552:f930:e22c:fc42:3b41:c5c6:6d5f]:63162","114.48.12.185:47837","[2964:cc5d:3a1b:7889:acc8:4d8:22c1:398a]:43515"]','2024-08-07 11:50:54.144157179+02:00','2024-09-18 16:15:14.050033969+02:00',NULL,'100.64.0.42','fd7a:115c:a1e0::2a');
INSERT INTO nodes VALUES(51,'mkey:5877139c52c0bf3c0fd054bd046aaf4530dd8946548a7bc1a06733649d1557d8','nodekey:553d9638c8c455e8d1bc811ea3af03db1eb3c586413447c8003e7d905a61d06c','discokey:1da883c9eff402d786362aaac2f478c835308b3acec0993e6293becf4474609f','web-62','node051',14,'cli',NULL,NULL,'2025-02-11 14:57:46.210281474+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["86.215.174.228:26026","93.101.159.155:64005"]','2024-08-07 14:19:31.156780417+02:00','2025-02-11 14:57:46.210762678+01:00',NULL,'100.64.0.43','fd7a:115c:a1e0::2b');
INSERT INTO nodes VALUES(52,'mkey:0e64072dafa5f9e49266b41fc4b21ff7d287be8f4e5f2b6c395487d632f1cf3f','nodekey:2f77bb8cbeb426bcded5ad9fc6da44b0b76b8d6759f10a8db28e634290760ee7','discokey:836558738056edd1fa8d190c7e42f120b365a48a3b1f1c96c87755bb82d7ad0f','desktop-07','node052',17,'cli','null',NULL,'2024-12-25 17:27:58.515851096+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d889:f751:710:257f:977f:5597:9908:14e0]:61162","[f83a:5ebb:911d:ef36:743c:8086:8a4c:a5c7]:23538","[dc45:365c:e426:71d7:fe23:fdd4:d2c2:9409]:57262"]','2024-09-22 15:48:41.385301399+02:00','2024-12-25 17:27:58.517153789+01:00',NULL,'100.64.0.45','fd7a:115c:a1e0::2d');
INSERT INTO nodes VALUES(53,'mkey:a6f93e99a5019b3b6a2941d95dc7fcbfea5a59317a48b99db93b7a3f4f0a65bb','nodekey:1f78a6d76ea4a2135c0da46b202560c86ed30cd7e8239d4508088d0e02ffb961','discokey:1744062452f052aba5320e37fc08aaa37f1430db7c32c94c5626f0f3c858de3d','desktop-82','node053',17,'cli',NULL,NULL,'2025-02-25 17:34:21.764621261+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[6084:ee60:1697:864e:4a61:cf6e:e9b6:4c05]:63961","[fad7:2601:d286:4772:3cce:6e89:f66e:9eeb]:5430","216.60.124.11:45041","[d513:c472:d7a:f316:f610:10d0:9851:4feb]:3955","156.228.105.157:61542","102.126.185.0:50694","[156b:e934:d171:2693:8db4:f193:a58c:17b6]:24190","79.255.179.99:56057","[6369:4412:8cfc:2a5e:7cfb:8b45:e2ac:f98a]:16090","23.0.29.75:24889","[ab0:1193:7bb7:4a4a:c036:b911:994f:3aa4]:5116","[9491:7bd5:3979:414a:d198:a8b:f2e7:29b4]:62795"]','2024-10-28 10:04:50.084492941+01:00','2025-02-25 17:34:21.856390854+01:00',NULL,'100.64.0.44','fd7a:115c:a1e0::2c');
INSERT INTO nodes VALUES(54,'mkey:a6e3c45c81dbefdd09389920767df65c30bc7ff1396806623e7f8e1938b6fcac','nodekey:22e4ac4e25b05db4e94b5211e08ed14d983972f92e192f15e0231ff355fd46bf','discokey:225f907deaffccb674416dc4ba532f0b20304e86d57808eef2d96f15211f2309','db-52','node054',14,'cli',NULL,NULL,'2025-02-11 14:57:51.780134436+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ecbc:a9b6:cbb7:695b:62ad:27cb:36f0:2380]:27992","135.238.213.41:64084"]','2024-12-09 17:10:55.363593066+01:00','2025-02-11 14:57:51.783335437+01:00',NULL,'100.64.0.46','fd7a:115c:a1e0::2e');
INSERT INTO nodes VALUES(55,'mkey:ad967c824d2c235ed17b1437f6756d4354ad76a2d27b575c0257ecac9a3a5fd2','nodekey:6196332e325e3f1d0c58acb182b48b070340dd673247c616a28d60a7669f5a4a','discokey:3a67fc6fdb9288679886c2d45dba4d1e1ba014af2c48f0f942acd39ef0e0ee64','email-56','node055',18,'cli',NULL,NULL,'2025-02-18 13:56:36.97652271+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["122.41.198.69:28824","[5437:6f4:94c1:c6c1:43ce:7a41:e5c2:65d0]:57161"]','2024-12-10 13:56:39.287449662+01:00','2025-02-18 13:56:36.978076326+01:00',NULL,'100.64.0.47','fd7a:115c:a1e0::2f');
INSERT INTO nodes VALUES(56,'mkey:3d9e1a7fc884de338b8391bbc5d3398c7d0ec4c36388b756df5b2304b727fa11','nodekey:9cd5d41c04ae83ade43363dd165c792cbc5386e0d3e005311ca7c79ae7f7acaf','discokey:2d6fad1f43bc97a6d48bcd400c829db2d4f47291b12a59dcbe669d8b1d341c1b','srv-70','node056',19,'cli',NULL,NULL,'2025-02-25 18:57:39.407869706+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a34b:36c0:9f18:1062:2269:92c:1c83:6ec6]:56902","[41e8:60a4:229:a09b:efd3:c73f:b885:d235]:39533"]','2024-12-17 14:58:39.429211911+01:00','2025-02-25 18:57:39.408317173+01:00',NULL,'100.64.0.48','fd7a:115c:a1e0::30');
INSERT INTO nodes VALUES(57,'mkey:1025548b29dc9733e1099fbb6516778e9d8f07eeaa214cd1ef33438e731333eb','nodekey:3f21adc328130ab468ac28ee25b4002974610ddd7b11f586752dec5a151114b2','discokey:605115f1238609b148dff010ca6e04d7b337df4e2b88de7a1f900a2f1de7db42','laptop-79','node057',20,'cli',NULL,NULL,'2025-02-25 10:30:02.978978512+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a329:52fe:45d1:996e:4767:d50c:6513:92ac]:54604","80.29.45.84:8223","178.193.134.41:58563","29.219.180.224:55412","[2ddd:7c1b:a237:41c8:3baf:e9cc:1f31:9057]:62916"]','2024-12-17 15:17:14.26936913+01:00','2025-02-25 10:30:02.979071466+01:00',NULL,'100.64.0.49','fd7a:115c:a1e0::31');
INSERT INTO nodes VALUES(58,'mkey:e2795aaa6a9a19aa8efe47496bd930d8ed32d5feacd49e903ebce90db20101dc','nodekey:1066fbdf7648099fbf06cd5b69e20e80c3422790caee0354e8465520329f7754','discokey:d00b560ef82f566c3171c1a313f25e65b7bc7a2eeb5146cb4c513bfbfe40fdf9','desktop-48','node058',12,'cli',NULL,NULL,'2025-01-25 18:41:03.881898904+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["168.76.222.22:27595","[dc1f:57e3:7842:53ba:b427:8e40:6ebf:5b36]:4136","55.12.42.230:527"]','2025-01-17 10:17:23.455895657+01:00','2025-01-25 18:41:03.882180987+01:00',NULL,'100.64.0.50','fd7a:115c:a1e0::32');
INSERT INTO nodes VALUES(59,'mkey:4de34c0ddff8819b97b39c2f31a2568db15e7c0ac6c1d75879b6c5247a5dd9a5','nodekey:13565579616a60409e411d5406b743f5dcf878da4aa82031350537d41038e09f','discokey:788fe7ffbb2b564852b1b9ec170a4267449c98b17ed51dcdce65942de712918b','lt-29','node059',21,'cli',NULL,NULL,'2025-02-16 03:40:04.156549179+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[32d2:d2f7:d5d2:8e10:507f:3428:b2a0:12b7]:22008","[c493:2a8f:6625:98c3:4f4a:db04:19cb:c7df]:41081","96.25.93.176:21890","219.197.124.83:46550"]','2025-01-29 11:59:27.291048957+01:00','2025-02-16 03:40:04.156814266+01:00',NULL,'100.64.0.54','fd7a:115c:a1e0::36');
INSERT INTO nodes VALUES(60,'mkey:f04e27d229384590995331a3723f7a668443d5e638956102ab37df84529fff40','nodekey:49394e4605a507fd3a121abf6406645648b79c5f07f9f594fd8edc25eb94b04a','discokey:16256cfb6fdbae68d3ee7de3124887892d557512d5f86b5e9f3b4af036c1eb9a','db-54','node060',21,'cli',NULL,NULL,'2025-02-14 16:39:11.521346869+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["168.132.106.166:348","[ac:5c65:da8d:d68c:eb0d:3692:d441:5363]:63612","107.250.166.141:64587","[25cf:5511:50fc:e379:b64c:3a3:ff6f:104f]:22295"]','2025-01-29 12:01:57.48748166+01:00','2025-02-14 16:39:11.521680749+01:00',NULL,'100.64.0.55','fd7a:115c:a1e0::37');
INSERT INTO nodes VALUES(61,'mkey:bdbef72c5f0e479a26353e2fe037cf6dd20719cb4d501f04a88a08571914307a','nodekey:fa24bcb6e340f6b8ea272a0d17ac7b5401e48d2fda056465326f2e1ac4695412','discokey:94ce18576693a7a51d39574aa5c81060355b8ae3f912c78515e525b5e31e5dae','web-59','node061',21,'cli',NULL,NULL,'2025-02-13 11:30:13.272216377+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["112.239.138.73:43954","174.168.204.29:5611","190.0.61.36:13730","33.70.223.181:46561"]','2025-01-29 12:03:01.464646336+01:00','2025-02-13 11:30:13.272621771+01:00',NULL,'100.64.0.56','fd7a:115c:a1e0::38');
INSERT INTO nodes VALUES(62,'mkey:7d5ae8f0478c9a247bd1bb17d30ca742093c245c62ee324252337a170c6693a5','nodekey:9eff4972c9c5ed636f469b7869e5b5a9ffb7ec419d5316958631a72dd0da765b','discokey:124c71c581460affbc538c1c3efef93fa40e2170b4a4e3e08d81847bac150bed','laptop-08','node062',21,'cli',NULL,NULL,'2025-02-21 21:09:17.619738167+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[54b0:31b1:f5d1:bd45:5e99:3951:5dc4:45be]:33239","55.225.129.62:57985","28.93.179.45:19029"]','2025-01-29 19:23:14.092804852+01:00','2025-02-21 21:09:17.620347693+01:00',NULL,'100.64.0.57','fd7a:115c:a1e0::39');
INSERT INTO nodes VALUES(63,'mkey:baeda24b92a15048f28b063ac4e3aa9ffa67b0bfd2a9ceb3b3005f6167e7c846','nodekey:9da3c4c71920a17c6476a51cc658c2d1e8ab167079cd0fab2215fa2e98675e03','discokey:c37813a5ff804ebfbd17ba3c3e030f97e5bacf4bf37c1829f1193b354657974c','web-17','node063',21,'cli',NULL,NULL,'2025-02-25 18:57:46.306411004+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["213.69.213.51:7048","[37a5:a9dd:8b9d:5014:b243:4f4f:6888:713e]:21123","223.252.160.61:32625"]','2025-01-29 19:41:40.535299057+01:00','2025-02-25 18:57:46.306748231+01:00',NULL,'100.64.0.58','fd7a:115c:a1e0::3a');
INSERT INTO nodes VALUES(64,'mkey:194758915fa3a0f4dc51d5c8809c8d34811a2ba691f8286e1281c8733b908ca0','nodekey:3edcebd1bbc810d5df8fe3217eebd41e209d8b62beb09912bd60fe3682006a2c','discokey:89d4a743b38f61254b01454fdaa89e7855966b1beffe363e86c28ce8ada66454','lt-49','node064',21,'cli',NULL,NULL,'2025-02-25 17:53:18.185882601+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["26.157.224.19:39567","54.120.201.209:5659","[1b62:c927:40b:7b50:6285:2eff:280f:4c8c]:58979"]','2025-01-30 18:18:57.519126133+01:00','2025-02-25 17:53:18.186491242+01:00',NULL,'100.64.0.59','fd7a:115c:a1e0::3b');
INSERT INTO nodes VALUES(65,'mkey:270533b0e4234eb9e697ee9e69403551dae192d4b3269a6810c4a0d2a6a55b6e','nodekey:d54cc8d3a12b77589e471e30b6ae4d803e58392b82aff1953974d722f8f1368d','discokey:e6c009756cf69ac7cdaea6c4a725c8766ec8e5a67be080a6ba2c6ed0fc5d7900','laptop-75','node065',21,'cli',NULL,NULL,'2025-02-25 18:58:05.70384565+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["197.205.147.181:38523","[5e11:9ab9:6805:dec0:99aa:65e6:d1fe:6e58]:45247","[34f8:19dc:cc84:1e6a:d280:ac0e:2dd9:6fe5]:39241"]','2025-01-30 18:19:40.354692307+01:00','2025-02-25 18:58:05.704297047+01:00',NULL,'100.64.0.60','fd7a:115c:a1e0::3c');
INSERT INTO nodes VALUES(66,'mkey:de86679045cb8624f1a83852679a58cffd9066814aa8994f4ac0a9213b83175f','nodekey:b62e575e38a00afe79418224f7b954210702ac0a6d450eb8dbf7b5720b1eb5a5','discokey:6492f53782aab503155db83aa2d3a9e7698382da589b8c078d7850373332734b','desktop-65','node066',21,'cli',NULL,NULL,'2025-02-25 18:24:57.136610701+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b84:67b1:28c5:14f:aab8:916c:582c:6917]:24462","51.182.13.145:25726","[3095:7c2f:3784:9955:ebbc:4382:662b:a218]:48812","[c771:8240:30ba:d472:9e15:10c8:b026:2654]:14619"]','2025-01-31 12:05:28.65297301+01:00','2025-02-25 18:24:57.136876179+01:00',NULL,'100.64.0.61','fd7a:115c:a1e0::3d');
INSERT INTO nodes VALUES(67,'mkey:259ea817a2c4d8a4c072db370e8c15ad9667331a63187285aaa4987b023b3e5f','nodekey:f743d054050f294bc1141b11924d8813401a650cc454e68dbfb20067f7d013af','discokey:aeb45bb93e68891487622a4274d9d2cfdbe795681e6f431075ad1aabb7ec1171','lt-70','node067',21,'cli',NULL,NULL,'2025-02-25 18:49:11.272283063+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b3d0:4706:73c5:9035:dd98:af39:b7f5:1311]:15037","[9356:40f8:a98c:a1a9:18e6:e781:f169:4277]:63375","[c733:e842:4621:e95d:6576:9ccf:b2c8:1582]:41668","[8f2:4995:746a:bc2c:84e9:95fa:b236:3c1f]:52788"]','2025-01-31 12:06:30.121464114+01:00','2025-02-25 18:49:11.272545005+01:00',NULL,'100.64.0.62','fd7a:115c:a1e0::3e');
INSERT INTO nodes VALUES(68,'mkey:87dacd4a5bad58d9676d8242fe304668201101da8843faf4991afa597adeeb2c','nodekey:bac278a5ad2db26a926acc26fd63948ba6bd59f251f7cb63189686ce6ab708a1','discokey:24a9b3c24f38b690ca357a9659d7694a2a4fc85da77fb1412eae653c644b3bd2','web-47','node068',22,'cli',NULL,NULL,'2025-02-25 17:56:50.63061982+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["171.134.254.145:45887","[29e:44c9:159f:6692:bdc0:de17:58cb:1908]:58971"]','2025-02-03 14:16:55.56431345+01:00','2025-02-25 17:56:50.630814975+01:00',NULL,'100.64.0.51','fd7a:115c:a1e0::33');
INSERT INTO nodes VALUES(69,'mkey:a3f039c16511f2b68bc8ab68a8d844c2f942aef9a277a1e2b1c3182c9f95b41d','nodekey:4cfd59f8b4bb7c82f7f7fba87ee21d2a0f32ce138d680591e8e0e47df3328ed5','discokey:38bae7e836bfd18b54cd4323709ae713fbd37d12c774cf19a8568bff1a410cb3','srv-80','node069',22,'cli',NULL,NULL,'2025-02-25 18:45:26.655373144+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f2d6:a8f1:727:d9e1:759:3a6c:6aed:d7ea]:22032","[3014:978:1762:1290:b92f:47f5:1dca:d0bf]:16383"]','2025-02-03 15:23:16.312084161+01:00','2025-02-25 18:45:26.655510978+01:00',NULL,'100.64.0.52','fd7a:115c:a1e0::34');
INSERT INTO nodes VALUES(70,'mkey:0b6c7fc5eea73e731daabee34180efedfe9feea3171ba9f64c45e913bd068910','nodekey:6c63bd3c0336e50cb895df6e1fb177d2e6ab7f8e59baac6f4d54a1708324248b','discokey:b594b1893b68cef8d9e8496797bad67eee207093fdb12a9dd08e0b53cb915791','db-86','node070',21,'cli',NULL,NULL,'2025-02-25 18:34:37.1756356+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["99.25.81.82:35202","52.120.18.3:13372","[dc9a:ed1e:f97d:b356:d5f5:5d44:c917:3077]:33994","[dac7:80d0:6b4:2620:3ae4:2936:23a2:eba9]:31156"]','2025-02-03 18:09:35.161109801+01:00','2025-02-25 18:34:37.176092039+01:00',NULL,'100.64.0.53','fd7a:115c:a1e0::35');
INSERT INTO nodes VALUES(71,'mkey:2251ba3534d7e20a28b1b2820ffd1a52a7cdcf60b1779a07d6c760aed6b3fc5b','nodekey:772af8901804b0da90941644bef50afbf67d0414226835865b7078383fc25272','discokey:fe85bbd953fe9294941fdb62ef965ff83bf7b646adec696db3bf889316cfc226','web-09','node071',21,'cli',NULL,NULL,'2025-02-25 01:29:06.614357209+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4d9e:563b:9e58:71a5:24ff:2612:7985:3f81]:20272","[2967:f7fc:b02a:7e75:6842:a146:56:dca1]:14923"]','2025-02-04 12:03:50.32663805+01:00','2025-02-25 01:29:06.674397902+01:00',NULL,'100.64.0.63','fd7a:115c:a1e0::3f');
INSERT INTO nodes VALUES(72,'mkey:b070570c4361b0e9ce2f3afc15c0280c1ccdbdb3cc77f46df24238984e0ec527','nodekey:1b7b5f34a954359091fb9c9f81ded16fb83c96aa793aa08dbfc8e043e9f5378b','discokey:3f7d2271e073c6d51bcaa49e6b040ab689dbf9cde108e1a82d0b3f30c4f2a6a5','db-60','node072',21,'cli',NULL,NULL,'2025-02-24 22:26:45.69683022+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["170.145.88.37:51085","[4556:deae:aed1:6442:1456:5897:f4:12b1]:18138"]','2025-02-04 12:07:36.231437299+01:00','2025-02-24 22:26:45.697080608+01:00',NULL,'100.64.0.64','fd7a:115c:a1e0::40');
INSERT INTO nodes VALUES(73,'mkey:0ec65946fc090054aa5164b3f5cd6f548dfc27b490025b1a190b93d69068c2e3','nodekey:37bda01462c321bf5c22d9f475325184aaff6d156964ef36d3f4638772db608e','discokey:9c15df2e2016b42d1c57c2ce1e3607786ecfcb4c3271991ea8e6abf28e1a1064','web-61','node073',21,'cli',NULL,NULL,'2025-02-24 20:16:59.20339999+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["20.112.75.120:15833","158.67.245.119:11948"]','2025-02-04 12:10:26.50545127+01:00','2025-02-24 20:16:59.203598225+01:00',NULL,'100.64.0.65','fd7a:115c:a1e0::41');
INSERT INTO nodes VALUES(74,'mkey:7352aa9afe2d3372cacf883c2fa2f9faee561f8dd567184909c6d1206156ac7c','nodekey:88b163165d7438eb768e100a617a3850f050f4b7f1a9d26f6a1c6c2cbab2a6df','discokey:a32aac3d9bad0a0557274da524523b2831914a5329307114c9c3abffa0899790','db-43','node074',21,'cli',NULL,NULL,'2025-02-25 17:40:44.888267238+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d05b:3c4f:8402:823f:409f:87b2:4dab:4959]:58420","130.243.34.21:50806","104.255.105.25:5817"]','2025-02-06 17:33:12.557302525+01:00','2025-02-25 17:40:44.88889439+01:00',NULL,'100.64.0.67','fd7a:115c:a1e0::43');
INSERT INTO nodes VALUES(75,'mkey:51f0f5c2b892846f926abf826f5ff56a52fc4a466be7a1073f16028ef2c6aabb','nodekey:0138c27376e8289255c1d505ba8e8d0e9e8e6785198b87984763531273d0c540','discokey:5bbb476ee437efaa55c10931313e35c4c8c6e30015e7f3eb015f4736897abb12','desktop-50','node075',9,'cli',NULL,NULL,'2025-02-25 08:20:55.11942837+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["57.247.45.203:47518","[1709:1d2d:9e92:a2c5:f5a0:fbca:6d9:dcbb]:31824"]','2025-02-06 18:23:55.709687186+01:00','2025-02-25 08:20:55.119891701+01:00',NULL,'100.64.0.66','fd7a:115c:a1e0::42');
INSERT INTO nodes VALUES(76,'mkey:e3ec4d021ea80bdca94d97bc70443b58b6f7c9fa382e4a2cd61b9397cdbefbb7','nodekey:60862d1848548d0816874d83c3d819dd8359869f24e4e0ca0b10ba98fae9aacd','discokey:5265333600c360986c74f93bda288a7adf25d8abb6b5174694dbfbc56e03d488','laptop-97','node076',21,'cli',NULL,NULL,'2025-02-24 22:26:45.695195612+01:00',NULL,'{"fake":"data"}','["140.129.39.90:29397","163.61.27.204:21704","208.72.71.10:23065","[5400:ad99:9af3:c69f:c044:7959:1cbd:d52d]:62818"]','2025-02-14 15:29:45.220999928+01:00','2025-02-24 22:26:45.695391477+01:00',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(77,'mkey:eacc877df3ab3cdbbe20b1784ebeda63fa5058b8dcf69215b7993219e4a9ea94','nodekey:0e46ba129c4fb18195868f1e3b7bb7ad91e882b5e5aeab040692b69036457b67','discokey:6b42741054b0235ac27e649163acff4f6f90e6cdd6c4e587c25cd2a6b9f35aec','lt-44','node077',23,'cli',NULL,NULL,'2025-02-23 16:44:05.007011804+01:00',NULL,'{"fake":"data"}','["[f8c:6efe:aade:2619:9aa8:378e:2365:1ab7]:58269","[de0b:ae5e:4986:c7a0:3d3a:e4f5:afe1:d7d5]:61468","174.113.53.229:41982","[de3:22e3:e882:aeaf:2f2:ca2d:a179:de48]:23754"]','2025-02-14 17:00:54.226657615+01:00','2025-02-23 16:44:05.007327971+01:00',NULL,'100.64.0.68','fd7a:115c:a1e0::44');
INSERT INTO nodes VALUES(78,'mkey:db77190826c814e219de0cd88d82298e7bf6d4fbb67ce8f00c0fd5c060fff85c','nodekey:73f0e887839e84b765d6186f97221d612d79595c119ff885682797991a02652c','discokey:74401b0dd1e1bfbbda82bf25fba18e15a89a30f4c1868cfb8ea81eb35ef4ae98','lt-27','node078',23,'cli',NULL,NULL,'2025-02-17 18:30:50.582229691+01:00',NULL,'{"fake":"data"}','["[5132:fd57:f2d8:8b61:470a:b25:60a6:48a6]:13595","208.34.222.79:35431","[e66d:c35:81d9:5ffd:4ad7:25c6:3ea2:a41f]:49279","[89f2:dc57:80ea:c56a:73b3:2563:1fd3:df17]:57048"]','2025-02-14 18:03:28.401774063+01:00','2025-02-17 18:30:50.635233842+01:00',NULL,'100.64.0.70','fd7a:115c:a1e0::46');
INSERT INTO nodes VALUES(79,'mkey:60cd68f2d9965be36441f2f639e5245d845b7fea90a9325938813fdedf751679','nodekey:783e5ff1eac899d0cb25f2539244aef4c4a46198a4ec8753afe89f00670e29e4','discokey:688d1fb7063cc3e59a7041e64de8d416ab6390f2739a50dcf06d529fd263d28f','desktop-70','node079',25,'cli',NULL,NULL,'2025-02-24 18:37:03.584752527+01:00',NULL,'{"fake":"data"}','["[1e10:11cc:fd29:4681:aaaa:fd21:a79c:bc3d]:57634","78.215.20.31:28892","4.11.131.129:50580","61.47.47.240:57553","107.46.106.255:64756","7.81.60.25:36846"]','2025-02-15 12:49:11.523904469+01:00','2025-02-24 18:37:03.584913585+01:00',NULL,'100.64.0.71','fd7a:115c:a1e0::47');
INSERT INTO nodes VALUES(80,'mkey:1de9a40ca190e9c6da65eecb16d3bb0574bf7757189115dc466299e08915c514','nodekey:de98e4358158b9231331934496db7fab148a8aac11248e4a17df0c4843c3a46a','discokey:cba115a9da4fa05b24b13e1180999612993a0eafb9728c3be13d50dd4458b95f','email-70','node080',23,'cli',NULL,NULL,'2025-02-21 18:58:38.982571563+01:00',NULL,'{"fake":"data"}','["156.169.142.128:42443","178.75.210.129:64679"]','2025-02-15 21:12:05.434304787+01:00','2025-02-21 18:58:38.983040117+01:00',NULL,'100.64.0.72','fd7a:115c:a1e0::48');
INSERT INTO nodes VALUES(81,'mkey:58cf6b62ae7bec2c13af7be13bca5edc03bd7a55d56ebdcb4a43b35adce5ff7c','nodekey:31d2dcb989bc02a1943ea12ad376f2f58cbab06e9761cb1bf4ef4024d310def9','discokey:68b0066f49c936d164f9595ddde2676815501a14bc6df2914cb34de8476acd57','srv-02','node081',23,'cli',NULL,NULL,'2025-02-17 16:28:36.502444963+01:00',NULL,'{"fake":"data"}','["42.226.40.62:27764","[bd66:349c:a29a:4c05:b3ab:dd92:749c:434e]:27566","69.37.34.188:32687","172.43.25.248:19211"]','2025-02-17 16:05:05.921277876+01:00','2025-02-17 16:28:36.502658351+01:00',NULL,'100.64.0.73','fd7a:115c:a1e0::49');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(1,'2023-05-19 07:09:23.387641743+02:00','2023-05-22 09:48:18.908103256+02:00',NULL,3,'192.168.224.0/21',1,0,0);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-05-17 19:36:55.859473496+02:00','2023-05-17 19:36:55.859473496+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(2,'2023-05-17 19:36:57.059073465+02:00','2023-05-17 19:36:57.059073465+02:00',NULL,'user002','','',NULL,NULL,'');
INSERT INTO users VALUES(3,'2023-05-18 10:10:36.248939077+02:00','2023-05-18 10:10:36.248939077+02:00',NULL,'user003','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2023-06-10 09:06:13.920718561+02:00','2023-06-10 09:06:13.920718561+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(5,'2023-06-11 19:58:32.371218434+02:00','2023-06-11 19:58:32.371218434+02:00',NULL,'user005','','',NULL,NULL,'');
INSERT INTO users VALUES(6,'2023-06-17 19:39:53.031565686+02:00','2023-06-17 19:39:53.031565686+02:00',NULL,'user006','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2023-06-20 11:35:09.325846831+02:00','2023-06-20 11:35:09.325846831+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2023-06-21 22:47:48.196234382+02:00','2023-06-21 22:47:48.196234382+02:00',NULL,'user008','','',NULL,NULL,'');
INSERT INTO users VALUES(9,'2023-06-22 08:30:35.068995572+02:00','2023-06-22 08:30:35.068995572+02:00',NULL,'user009','','',NULL,NULL,'');
INSERT INTO users VALUES(10,'2023-07-03 10:18:32.123226+02:00','2023-07-03 10:18:32.123226+02:00',NULL,'user010','','',NULL,NULL,'');
INSERT INTO users VALUES(11,'2023-07-03 10:18:37.130387602+02:00','2023-07-03 10:18:37.130387602+02:00',NULL,'user011','','',NULL,NULL,'');
INSERT INTO users VALUES(12,'2023-12-15 08:05:06.013615212+01:00','2023-12-15 08:05:06.013615212+01:00',NULL,'user012','','',NULL,NULL,'');
INSERT INTO users VALUES(13,'2024-02-03 16:32:42.224977233+01:00','2024-02-03 16:32:42.224977233+01:00',NULL,'user013','','',NULL,NULL,'');
INSERT INTO users VALUES(14,'2024-05-03 10:12:38.220973042+02:00','2024-05-03 10:12:38.220973042+02:00',NULL,'user014','','',NULL,NULL,'');
INSERT INTO users VALUES(15,'2024-07-26 08:08:40.979783263+02:00','2024-07-26 08:08:40.979783263+02:00',NULL,'user015','','',NULL,NULL,'');
INSERT INTO users VALUES(16,'2024-08-05 17:32:02.878091894+02:00','2024-08-05 17:32:02.878091894+02:00',NULL,'user016','','',NULL,NULL,'');
INSERT INTO users VALUES(17,'2024-09-22 15:48:00.287392203+02:00','2024-09-22 15:48:00.287392203+02:00',NULL,'user017','','',NULL,NULL,'');
INSERT INTO users VALUES(18,'2024-12-10 13:55:11.256977421+01:00','2024-12-10 13:55:11.256977421+01:00',NULL,'user018','','',NULL,NULL,'');
INSERT INTO users VALUES(19,'2024-12-17 14:57:58.550971236+01:00','2024-12-17 14:57:58.550971236+01:00',NULL,'user019','','',NULL,NULL,'');
INSERT INTO users VALUES(20,'2024-12-17 15:02:08.053169491+01:00','2024-12-17 15:02:08.053169491+01:00',NULL,'user020','','',NULL,NULL,'');
INSERT INTO users VALUES(21,'2025-01-28 15:57:32.774456057+01:00','2025-02-06 17:43:41.935399542+01:00',NULL,'user021','','',NULL,'','');
INSERT INTO users VALUES(22,'2025-02-03 14:10:50.491924701+01:00','2025-02-03 14:10:50.491924701+01:00',NULL,'user022','','',NULL,'','');
INSERT INTO users VALUES(23,'2025-02-14 16:58:30.250289644+01:00','2025-02-14 16:58:30.250289644+01:00',NULL,'user023','','',NULL,'','');
INSERT INTO users VALUES(25,'2025-02-15 12:48:14.650995528+01:00','2025-02-15 12:48:14.650995528+01:00',NULL,'user025','','',NULL,'','');
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,136 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
INSERT INTO migrations VALUES('202501311657');
INSERT INTO migrations VALUES('202502070949');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'463a8b372963aeaca12400faa0c7ea29e9bfa3b4c59e9622',3,0,0,1,'2023-05-19 05:09:19.66636462+00:00','2023-05-19 05:14:19.664224869+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'77a019cb12c0d0b9347a17ab23fa4c87983814fe36bb2fbb',14,0,0,0,'2024-05-03 08:13:55.8614948+00:00','2024-05-04 08:13:55.85782156+00:00',NULL);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`ipv4` text,`ipv6` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:0ea01e8cd608548a171ebcedc16da73b25ec18d58861be7a6b4274eb17baf6ba','nodekey:0fcf591dc1997c1d7388a3835bd24dae48240e5b03b6a7f5f33b2e813d222bcf','discokey:ed27f0b3c04222f0d05bfbc6fb5787338275ed0e32fd42fe68c669aca0f3d7a4','desktop-54','node001',2,'cli',NULL,NULL,'2025-04-01 16:27:58.397462433+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b8f0:cf44:22c8:82d1:f79:c3eb:9144:c24f]:6142","[8e25:af1:e31a:8fcc:7dcf:be1:a3c9:ed6a]:38766","[37a1:215f:bf3d:3fb1:6399:f7cb:4048:3ca8]:51666","137.242.125.72:25376","86.84.184.63:26062"]','2023-05-17 19:38:13.531518257+02:00','2025-04-01 16:27:58.397628099+02:00',NULL,'100.64.0.1','fd7a:115c:a1e0::1');
INSERT INTO nodes VALUES(2,'mkey:fa994293c516f7166a803edf260ec091b1638547f4ba78aaf0625a4d0cace0a5','nodekey:5b5bb489a68285591c97034325637a7767cea0051fcf19934dc694331137f459','discokey:1743557d49de33b01698e6eea7c6ce383010f3c6b20a56c39defdaccee9c5873','lt-98','node002',1,'cli',NULL,NULL,'2025-04-05 07:56:58.676183973+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["149.96.226.131:35537","84.23.188.83:48876","44.184.117.89:36643","90.223.136.253:7056","[e43c:be7:7f4e:8217:a009:7f9d:a510:1af6]:18872","[3a86:865b:2f4c:f3b7:88a0:4aa2:f05d:c3fd]:47680"]','2023-05-18 10:09:21.757289398+02:00','2025-04-05 07:56:58.749180421+02:00',NULL,'100.64.0.2','fd7a:115c:a1e0::2');
INSERT INTO nodes VALUES(3,'mkey:e44e45bd1656b97e8b328dc927ccab6cbce6c869992f70fb9c6031b980a1bf2b','nodekey:1497e461383f07b4f7cd7c76036b6fcabf23f46ac9f3651e22fd1f67eee22804','discokey:d84cef5408f6a40a7d789abbfdabd99edcd794e066894632f3cbb20d0e90a100','lt-24','node003',3,'authkey','[]',1,'2025-03-31 18:38:46.659409582+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["219.238.10.240:64443","[5e3d:ce1d:284e:9f89:155c:bff2:a65:d667]:51808"]','2023-05-19 07:09:21.399903526+02:00','2025-03-31 18:38:48.354115247+02:00',NULL,'100.64.0.3','fd7a:115c:a1e0::3');
INSERT INTO nodes VALUES(4,'mkey:a2be538ff79403d577686c0ff675e1ec1b0da10902211d25ccf8adb58deaa6be','nodekey:69977d7f034a8ca09f0f08dc2d6410eb2b6f5fd343b6c88124ec37d6bcddb4d9','discokey:2a3fadbffba90bd0d74d432626a92d1ce1cf0297d4ad51cfd2011c4de7e198fa','db-36','node004',4,'cli',NULL,NULL,'2025-04-05 07:55:13.242501536+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8a81:30b8:5d50:73d7:9039:f2ce:c1be:a099]:43373","76.78.238.163:55069"]','2023-06-10 09:31:51.940506933+02:00','2025-04-05 07:55:13.243195188+02:00',NULL,'100.64.0.4','fd7a:115c:a1e0::4');
INSERT INTO nodes VALUES(5,'mkey:d1533206380a3d91fe09ba9aca808b8caada2cb469e9065acdebab13f22a215f','nodekey:961c8e15bdb7e261c0d359f72256c218447c9c007032f102a418d07b0b829b1b','discokey:d6e4dec2b26039771350ddf132dadf1a5d8615608bd99461d267271e7b53269c','srv-09','node005',4,'cli',NULL,NULL,'2025-04-05 07:57:42.002738555+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b12e:af88:3c55:41f8:5fba:2aa3:3248:15c1]:23643","186.84.191.82:2621","[c9d0:4e15:513a:171b:9911:f9a0:cccf:cd83]:24151","66.84.158.199:63451","47.94.115.240:6677"]','2023-06-11 13:56:42.694329408+02:00','2025-04-05 07:57:42.003378098+02:00',NULL,'100.64.0.5','fd7a:115c:a1e0::5');
INSERT INTO nodes VALUES(6,'mkey:4cf09b5d948c6492d0706b7972a9f46f03261dc73244cbd098653461c1426dab','nodekey:dd207345a8cdda46d50803658ab26c0fc7f28283217c6aa616a945885e92fca3','discokey:a0e6dfe46d6380aa0d131816dc0ea3287aad89196690b9bd91224f904816aa06','email-01','node006',4,'cli',NULL,NULL,'2025-04-05 07:56:59.056128983+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f739:43a6:4363:817e:34d9:3cc:1272:dba1]:26597","220.204.45.94:59135","187.96.173.136:34092","[fece:76ed:4c23:1e89:f225:97a1:94be:b5c4]:33472","[e1e6:a14:535a:668b:698:f125:543f:b5b7]:31740"]','2023-06-11 13:57:44.975695604+02:00','2025-04-05 07:56:59.0920878+02:00',NULL,'100.64.0.6','fd7a:115c:a1e0::6');
INSERT INTO nodes VALUES(7,'mkey:5bbbd75488079eda04771e44ddf21c5866640024a947e66cfd3c3bafb19d3e11','nodekey:022306df92cac976efdd1dd5d4454d0e20eb46ac6f7b847dbcc382a399d1c97e','discokey:4980d19a6814405d26c40dee31a93a5f43e18b41f6f6f4908ee59066e04f8179','lt-67','node007',4,'cli',NULL,NULL,'2025-04-05 07:57:44.198576857+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8ddd:4aae:2b94:4c1a:d05f:65d2:2bdb:b400]:42839","[c493:a941:58b6:7634:6221:70ba:20e6:40c4]:35486","[9b54:61a6:c678:edac:956f:741e:5e2c:9ec9]:17930","[cd3f:af1c:fcb4:bcb3:806e:adf4:3f3f:ab36]:58513","[7a83:6a84:9f15:ba1a:9671:3d54:2e31:d5e9]:64893","167.223.65.194:6907"]','2023-06-11 14:16:56.951313537+02:00','2025-04-05 07:57:44.198934821+02:00',NULL,'100.64.0.7','fd7a:115c:a1e0::7');
INSERT INTO nodes VALUES(8,'mkey:1abadbff7c8bdbe7a3104396c70068fa0a7aa30e405ef7d088738a8510877b39','nodekey:1251afbe69b3212ef1137c4bf2ef842409b8440d9ce32470ce4e8fb245480ccb','discokey:4a7b4155015d4cc2418ccb4005d3408b610c37b9f7bffdc625e2823f3e44514b','srv-71','node008',5,'cli',NULL,NULL,'2025-04-05 07:57:27.984224703+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["107.117.104.69:47662","[adea:86d3:b312:f445:d835:6023:f1f:f928]:27483","124.104.237.237:47957"]','2023-06-11 19:59:30.401970393+02:00','2025-04-05 07:57:27.985100444+02:00',NULL,'100.64.0.8','fd7a:115c:a1e0::8');
INSERT INTO nodes VALUES(9,'mkey:9ced3abf3a281d71b6f361a75769c571c4aff9e4cbab5b317f6cf18918f66bbc','nodekey:e533ead6c5b810764db07631d7b9b14434bf66549837d33a6187daac1ab1d7a9','discokey:571a7ba01a8a0fff2af21d0f135caf8ae2ee0e15fd5ab996d2e490cf968d7217','email-22','node009',6,'cli',NULL,NULL,'2025-03-31 18:38:47.329086514+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5b29:3bfe:7aa9:2767:900a:8142:1ae:eb94]:59942","165.200.68.0:39862"]','2023-06-17 19:40:45.468789461+02:00','2025-03-31 18:38:48.935281615+02:00',NULL,'100.64.0.9','fd7a:115c:a1e0::9');
INSERT INTO nodes VALUES(10,'mkey:6cb022f8457bd430cd8ca6e88f1d4e3678965fd0af659ef29c956fbaa81c870c','nodekey:b4dc05758407f598a2cb77f98d5c4fca9dc3820e31976887942b54a4d44e43bf','discokey:fb9dba09bf8b64d2ef3b35d917d41d5208aafb2b013a53da0d2196a152a3cf9f','desktop-07','node010',6,'cli',NULL,NULL,'2025-04-05 06:30:41.564651006+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["2.116.83.236:33635","41.172.94.101:32111","223.204.123.230:38090","[9394:b33d:67e:fde5:21f8:77e8:97a8:bbb7]:47884","14.155.207.231:4806"]','2023-06-20 11:18:35.905417341+02:00','2025-04-05 06:30:41.565251484+02:00',NULL,'100.64.0.10','fd7a:115c:a1e0::a');
INSERT INTO nodes VALUES(11,'mkey:e76a4d43284c0d19fbcf84b38d4bbdc5f978f8922f2ef6dcbe15170a3860a7d8','nodekey:85652faac3a65cb620073e7402506930daa194a7a3555c335741ee65a920530b','discokey:3a6aac7afdc916c9bc84b77b90c521c0e08f3fbf06ce89cfb2281271ec070b1a','lt-86','node011',7,'cli',NULL,NULL,'2025-04-04 21:59:20.16340839+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["22.207.212.228:27547","[2c3e:2260:8c34:275:2287:b721:1bdb:d462]:59540","70.115.64.117:6906","147.25.71.84:48460"]','2023-06-20 11:35:15.063855316+02:00','2025-04-04 21:59:20.295244825+02:00',NULL,'100.64.0.11','fd7a:115c:a1e0::b');
INSERT INTO nodes VALUES(12,'mkey:6dacfe30ad1cab87eb1ef96c1d574cdb59d71aa0695483c7f17aef6b26f446b3','nodekey:b1f007ca3a9d6637fa1388c71397a537d4cc3b94918c280dd9068c3871861c02','discokey:3cf2b60ecdfbf0b633afb7c89de5c05274933adb6a71fdfc28fdd79c0814ee51','lt-86','node012',5,'cli',NULL,NULL,'2025-04-05 07:56:06.898009216+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2e1:2c69:85a7:8894:dfe7:6f6c:a382:4fc]:6426","[e758:c726:ced4:43ea:60fd:3ad8:1b8b:b514]:15200","[314c:5aba:d6ac:63d3:4de3:2c46:5e60:903b]:30789"]','2023-06-20 18:22:35.061914624+02:00','2025-04-05 07:56:06.898660893+02:00',NULL,'100.64.0.12','fd7a:115c:a1e0::c');
INSERT INTO nodes VALUES(18,'mkey:88ef4bda4139c7c09e33bbc866b88e069c51187346d8095238179c82502dffcc','nodekey:7ad274415b296099222e0ca334eb849e0e6595ffa54dbcc94a0fc9ffa69d1747','discokey:388c1077bdd17ce1f86b92936609756ecd3e8b21ab3f4b8a84da7727dd2b2552','web-70','node018',9,'cli',NULL,NULL,'2025-04-04 21:32:36.521819531+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["33.51.84.119:46756","[c844:704e:c3c0:e709:8f94:3564:1b4d:d2d9]:8357","[169:f098:49e9:99af:27bb:802f:fc22:bd59]:63749","[2acf:3f32:1763:5d21:88a:4af:8779:1b1d]:36283"]','2023-06-22 08:30:54.08720463+02:00','2025-04-04 21:32:36.56813156+02:00',NULL,'100.64.0.16','fd7a:115c:a1e0::10');
INSERT INTO nodes VALUES(20,'mkey:338d7e5ca6c5a8c65d7174eb1af312107408a16b7769b7088c8acf64134d9722','nodekey:440bd6fd6eea65489be99a6a95f4b6315ea55fa31fa1d6905a53ba4c046e0817','discokey:80890f521819e60c3778df342a98a9adfe2f46c15b0f55aa14f17df002aaa398','desktop-48','node020',11,'cli',NULL,NULL,'2025-04-04 22:24:36.219266862+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["191.156.96.176:5489","[166e:c30:4d73:440f:456a:22be:71e1:142b]:33036","[6d05:6bb8:3bec:c76c:1890:ca9c:2684:1bbb]:31223","173.218.108.179:51272","143.8.135.130:62709","[1af1:db8a:7b81:52eb:f4e9:e74e:905:79d3]:7418"]','2023-07-10 12:40:34.838579199+02:00','2025-04-04 22:24:36.219367472+02:00',NULL,'100.64.0.14','fd7a:115c:a1e0::e');
INSERT INTO nodes VALUES(21,'mkey:ee8b7cc5b7ece1e1a03fdf355a2356928cc272be6f9570866e8ab7d43c09036c','nodekey:2249e3a64297951858ce623341c49d6ebcfe94a8fb5e4edde4889b8f50deea48','discokey:555c31b79c570eafb2f3be56f01cc73913c4886081fc75b868d14340380e5a42','desktop-87','node021',11,'cli','null',NULL,'2023-11-20 07:19:19.447470862+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["207.187.74.99:12216","63.3.67.150:22907","[77ac:562:7c4c:438a:6ec:be48:743d:47b1]:11349","[33cd:731c:f110:9b45:66b5:de81:1daa:757f]:5997"]','2023-07-10 12:42:43.290469734+02:00','2024-09-18 16:15:14.03886353+02:00',NULL,'100.64.0.15','fd7a:115c:a1e0::f');
INSERT INTO nodes VALUES(22,'mkey:2894a7babdc030bac1e4ec0e14aa4b6b67ebe382a1773e0ff4aa8b16ecd443a3','nodekey:1e219f3cc03eaa868018b9f6870d108317c31760fdc38ad4bec7200d58379f26','discokey:a81e998383baa23adb3e1e6757ef0c4b960095022f00b500b57f53c6147c71e4','laptop-48','node022',6,'cli',NULL,NULL,'2025-03-31 18:38:46.693334487+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[736d:a0a:e343:6b2c:b48b:7510:ace2:edc]:60377","82.193.154.129:23713","[68:80fa:7b30:3a0:d1fb:3e89:2c73:256b]:30308","[ad42:3917:5edb:3e85:732:1c71:a19e:9fe0]:11799"]','2023-08-05 12:08:48.132161695+02:00','2025-03-31 18:38:46.801242352+02:00',NULL,'100.64.0.17','fd7a:115c:a1e0::11');
INSERT INTO nodes VALUES(23,'mkey:9ab69494a274cba5b22cbcf35b3ada57d4b3d2ee03930a456f80fb34dc69064b','nodekey:0345912b4e39cd9d03dec55edec6fba7f8aca631312884b49538550475332182','discokey:a2c1be2ae50af07e5b96b0a3ee2d3a1b0148fbfc5c1a283bc787e31410d6f74c','web-51','node023',12,'cli','null',NULL,'2024-12-07 19:25:56.935152754+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["9.237.225.227:64622","[46a1:e1e6:6b82:6599:acc7:2273:afea:f09f]:38018","93.129.193.97:13477","184.41.32.72:1026","[f136:8b69:185a:7ec7:94a1:ca58:5d95:ba9f]:21119"]','2023-12-15 08:05:56.592241745+01:00','2024-12-07 19:25:56.935317645+01:00',NULL,'100.64.0.18','fd7a:115c:a1e0::12');
INSERT INTO nodes VALUES(24,'mkey:94d0eadf801d88022019f9353b7c29cafdd060a269a0245396e01f1293953cb0','nodekey:1db769d2ca42bc0f8b4e18b5c89a31fb4595edf0592ce1a534b713ba503f07e9','discokey:912056b78049017764c78a047b65feb3c3b934fa26ac62b44f8d7d561711321a','srv-85','node024',12,'cli',NULL,NULL,'2025-04-02 22:03:44.023075093+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["21.107.170.69:30767","212.18.227.41:50735","[f774:e89b:980f:975d:fd3e:93f:a9b5:2034]:46054","[7225:d0ce:d29a:59d8:f596:b945:9a02:29ed]:43419","[5a76:d5b0:b51d:6b56:afaa:3968:277b:192c]:19250"]','2023-12-15 11:14:36.765183054+01:00','2025-04-02 22:03:44.02329052+02:00',NULL,'100.64.0.19','fd7a:115c:a1e0::13');
INSERT INTO nodes VALUES(25,'mkey:247cad9ffd7d108f553e7658db14bbad992332458abb9b4bc5a0c0d3a13ead9f','nodekey:bbfb569ac8a34cf4d59d2bc13d0f03660d24aedf22c61b56510a65d20bdf0812','discokey:61f92520602549b9bc684eeed3186f608a38e13794d06d4b8d165c4efbb69a24','laptop-29','node025',6,'cli',NULL,NULL,'2025-04-05 07:56:00.717501781+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5b7b:e424:ea77:aa8a:f835:d6bb:2e1f:52ea]:19152","[bb06:d322:7cec:426b:ef38:55d0:e7ce:95bc]:31597","[320d:6314:eaa2:a098:8594:977d:27b:8442]:12827","163.235.127.125:61230"]','2024-01-05 17:32:40.940566279+01:00','2025-04-05 07:56:00.718576252+02:00',NULL,'100.64.0.20','fd7a:115c:a1e0::14');
INSERT INTO nodes VALUES(26,'mkey:d623495ccdc12a3f219322cf53458a85c29b8795ceff5cef5338bb9c26e329dc','nodekey:781ad44c939f14168ec1c22c3fa2c5422f5ff1a5b0fc163fa80e6ace4e20c4a2','discokey:c474b4d7b9883e70466b6240b885a2a71dbe6efb0e8c84b85277beb584f25690','email-47','node026',6,'cli',NULL,NULL,'2025-04-05 07:53:33.912069529+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["173.144.3.182:33138","[975a:978:5cfb:5e5a:1b6:d272:a1c1:50dd]:3245","[e6e4:7cfc:9ce:b47:62f5:b64e:d2e4:9015]:42369","[26c6:541b:69af:974a:8ea8:6bd0:7c4d:5a82]:10571","[c898:1525:ebe8:704a:243b:de9d:b8c:ea69]:22747","32.167.123.100:57075","[2c67:a9f3:3163:c675:3386:2447:1cc:ed3a]:42590","64.137.67.1:56198","163.42.128.241:47535","49.160.22.202:42427","[1526:e34a:8857:394e:bbe0:c043:4b37:68d4]:5245"]','2024-01-05 17:34:19.811670479+01:00','2025-04-05 07:53:34.448650057+02:00',NULL,'100.64.0.21','fd7a:115c:a1e0::15');
INSERT INTO nodes VALUES(27,'mkey:d95c13394bdb912ef51f3123fdb0495feef567dc13724efd8dea17b33ce7aa1d','nodekey:fd8be528ea41d74697d46084c8cf560fff1c21b3193bec752ba2d60457396b19','discokey:9ec066ac46492f546a67be34b417eb469dfc95aff8b7be28be3bd8b36bf98653','db-72','node027',6,'cli','null',NULL,'2024-01-16 14:32:21.570104175+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5760:dc4e:eac8:5c38:6c9c:8451:98d6:4e9c]:21573","[e350:bf94:9128:bca7:8c74:ab49:c419:4c50]:18052","222.155.102.116:42746","[e32f:122e:8a:e473:4b83:8ec9:61db:60ce]:37054","154.68.57.163:54048","[c5a0:942c:ed88:2277:3c9a:4f65:a25e:5b40]:27852"]','2024-01-05 17:48:25.466030859+01:00','2024-09-18 16:15:14.040766068+02:00',NULL,'100.64.0.22','fd7a:115c:a1e0::16');
INSERT INTO nodes VALUES(28,'mkey:08347db9fbe8e5e7a968c2ab9ddd1ff530ea98163c0bab7769316307545f4d46','nodekey:b6b03efd7deb52dbe0298708ea37400510ab7589b0b1787eac1a5f9b50aa7c80','discokey:6a0ab2f3329d9fe5f50c76f9f3f1d2e797574af93d823a511df57f45414f647e','srv-42','node028',7,'cli',NULL,NULL,'2025-04-04 14:08:44.348585699+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["42.99.149.47:5231","146.122.164.252:36824","16.15.205.75:58574","82.136.149.34:28707"]','2024-01-15 09:34:54.847632697+01:00','2025-04-04 14:08:44.348711737+02:00',NULL,'100.64.0.23','fd7a:115c:a1e0::17');
INSERT INTO nodes VALUES(29,'mkey:4a6e46330ccd4b3026337cdef37485c27592babda329107565c2a19d97253dcc','nodekey:17de47da1955a8a034788ae671c34fb10083568bf9e2f7494276cb2636065246','discokey:449f5f35a3507974cf03e3ac5c055d890de5122f57a7c2d84a0d3b324998607e','desktop-17','node029',7,'cli',NULL,NULL,'2025-04-04 21:46:12.712212086+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c2f1:82ab:922a:9b9d:f53d:a0b3:bccd:f6af]:299","[d28b:7b33:1f88:7583:7ed7:a923:4c90:9ee0]:62318","[68e3:a070:f02c:708c:a057:b579:aee9:4d25]:11747","[7224:b76a:cd04:e6d2:67fd:fec0:2f14:1837]:29002","173.82.71.57:3159"]','2024-01-15 15:18:12.2871978+01:00','2025-04-04 21:46:12.807613421+02:00',NULL,'100.64.0.24','fd7a:115c:a1e0::18');
INSERT INTO nodes VALUES(30,'mkey:26f1059c45c12a8e56cd57ba6db33dfe104eac76103327af49622cb7810fab7d','nodekey:b157bbdc37aa4634b8d69d6fbc7670780fff69337713176a11f893afafa2a9bc','discokey:4c8c175d0e61ca8f7b2de92a1033cb9be95eaeaf09e9395c767afa5afdf2d9b5','desktop-64','node030',7,'cli','null',NULL,'2024-02-05 12:14:40.065688294+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8a1a:5c17:bb81:bb69:c7db:3513:f14c:ca2d]:52077","123.235.220.59:59925","155.210.184.45:60093","[963:536a:33e9:99fb:c204:d59c:29a8:ac18]:39005","[e84c:35c4:4bd9:a100:c271:8921:ca7:5901]:21828"]','2024-01-15 15:21:43.217136004+01:00','2024-09-18 16:15:14.041757308+02:00',NULL,'100.64.0.25','fd7a:115c:a1e0::19');
INSERT INTO nodes VALUES(31,'mkey:ef048095dd3e937a8617f18797ed42d2c4513d07126dc419a466f257982113d1','nodekey:1c6c367df9b85ab5e1618c70c0a4f8b22e2eeea77523b40059c3ebfef0f4057f','discokey:80fb63a98202437504c700e582eddf800b02dc654577bb95796c60cdf1176793','lt-55','node031',7,'cli','null',NULL,'2024-02-22 08:35:27.098819037+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[cc02:5592:3738:a2ab:8c55:97bf:a5b8:24e6]:41616","129.130.98.189:47833","[99c0:d769:2f38:10e9:c01a:e3d:898e:afc]:17505","[3423:afbf:aa2:e156:81df:bbd3:412a:df65]:5125"]','2024-01-29 16:05:35.338524634+01:00','2024-09-18 16:15:14.042191514+02:00',NULL,'100.64.0.26','fd7a:115c:a1e0::1a');
INSERT INTO nodes VALUES(32,'mkey:5b0e391e12914bcbcc6b415d9dd72937d74f9ce92a22c6ec938eb749962ee6ce','nodekey:4fa73acfb54cb140dad6b02bc853f6360f5ed160f819dc57701ad9a4caae9782','discokey:d3e90723a3b90eea513e7710ccaf25f68c0a2d60a85e3d4b9e4385335fddf8e9','srv-15','node032',7,'cli','null',NULL,'2024-04-09 13:59:43.37062537+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[14bd:ee53:6776:c1c0:124a:efbf:38cc:b312]:62180","85.234.248.186:20429"]','2024-01-30 10:41:58.31917869+01:00','2024-09-18 16:15:14.042506082+02:00',NULL,'100.64.0.27','fd7a:115c:a1e0::1b');
INSERT INTO nodes VALUES(33,'mkey:ba179b51f3540e619eaac9a6d4bc67403daa7c3cf28a6b579087cd6d284501b4','nodekey:246fadfe2a3606f043aca1fc1fa31b79e9eef9c21ec67e72425e05576707b3c6','discokey:5c64c1a08b88425b6e1e2971f950708d38f951d2d5eed2b85df8dd7d1bb88a44','desktop-32','node033',13,'cli',NULL,NULL,'2025-04-04 21:35:50.079412269+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["106.67.113.92:45634","85.199.78.110:6716","[bc29:715c:cdce:f1f6:8630:4929:ea1e:5c03]:10918","[af8:f5e8:32f0:75ee:d351:c0e9:78e:93d9]:12624"]','2024-02-03 16:33:26.706408143+01:00','2025-04-04 21:35:50.07986885+02:00',NULL,'100.64.0.28','fd7a:115c:a1e0::1c');
INSERT INTO nodes VALUES(34,'mkey:6fe02bbbdd40bb09e8aa74cf66b40b5b94f227690fd804a33242f56e18bee64e','nodekey:acc333e66d45e660ff4a31a152340d391547ebef1056f5f046624b629389bfd3','discokey:cf4a1217f85585d74fc5138af6ed9b78a29a9d4f12ad2e1beac660816d8c7b3f','lt-74','node034',13,'cli',NULL,NULL,'2025-04-05 07:35:41.145084059+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[1092:57ce:a60b:141d:ba79:79a3:91ed:66b8]:11037","[f766:14e5:6acc:ba40:8b28:59b7:ef7f:cd51]:46293","[c:e6fc:18ea:2e45:6bef:c1c1:f84e:b1e2]:62296"]','2024-02-03 16:42:32.683785672+01:00','2025-04-05 07:35:41.16521778+02:00',NULL,'100.64.0.29','fd7a:115c:a1e0::1d');
INSERT INTO nodes VALUES(35,'mkey:f95240eb788522b37f5513f0253f8bdab2ccf7594ffbf9bb77945fd67e598c05','nodekey:f5a6f47f5a34b4f4c6883e46fb52c0a5f7ca2ce17397cbba751efa8736e0066d','discokey:4dc728a0c0de0ce87530a47dda426d5bf6ad1b2f6cdefcc819c29c1015c3131e','web-44','node035',5,'cli',NULL,NULL,'2025-04-01 19:27:16.8887994+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["136.113.252.147:325","139.180.210.231:32286","171.29.58.211:2336"]','2024-02-03 16:51:52.010016072+01:00','2025-04-01 19:27:16.890057487+02:00',NULL,'100.64.0.30','fd7a:115c:a1e0::1e');
INSERT INTO nodes VALUES(36,'mkey:8ac09adfe44b8e60665601726c99627216e71b49ef7e8cc58ae6ba4f997c8652','nodekey:62d8af3310a7f27d84b931eaaa7ee110fe7fe46ea3ca8c817e47b9ce456c9b4a','discokey:bd31ae97729ac879d9b57866a69abb521248fb7fd5663d2149857d4dbf023d85','web-93','node036',13,'cli','null',NULL,'2025-01-19 14:01:48.956567669+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7e9e:219a:507d:d3d:cc77:6195:7ce3:b30e]:25018","203.251.190.122:19081","49.144.40.103:7674","[a641:3f06:63bf:b716:4658:1e5b:ac6f:e14]:13490","197.206.147.31:58506","[b1e8:68a0:4017:a243:61d0:b303:7860:18e]:28633","[e5b8:6c78:ce2f:cf6f:13fb:401f:8223:3f04]:54121"]','2024-02-09 12:34:57.879970954+01:00','2025-01-19 14:01:48.956830267+01:00',NULL,'100.64.0.31','fd7a:115c:a1e0::1f');
INSERT INTO nodes VALUES(37,'mkey:c371756901cab84ae432a7d201e47232b008ef55effcf90341f24de7dfc55bb0','nodekey:0f858ae8a6492e1cc63fb502c6453ae90e8723f8b4ea8eba8c67f9f5114dec39','discokey:b6fc59b2a9ec7ddf1ae9573245cd3271259f964cdd730b811fabb019eccb3c81','db-47','node037',5,'cli',NULL,NULL,'2025-04-05 07:56:56.882618261+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b8c2:c792:3329:2c93:f94b:a948:7d11:b9f2]:908","[5925:353c:bd9a:f42e:1916:45b4:c170:e515]:18400","[c2a5:cc2f:e2e8:573f:7b01:4aa:8a1a:fd71]:32146","193.82.125.68:38601","[e9da:1552:e478:f920:c3d6:ff41:9e86:e27e]:48481","[c31d:dd18:321:589:11fa:d85b:695f:1fca]:43064","168.4.78.117:48474","90.45.218.0:29326","90.233.46.138:29846","8.137.133.59:22781","[cb5c:f8d4:ccb0:8333:8ec:170c:a2b0:941d]:26248","[5802:df5c:8853:4851:6dcf:cb83:8208:d143]:24568"]','2024-02-27 12:14:40.452601042+01:00','2025-04-05 07:56:56.896138732+02:00',NULL,'100.64.0.32','fd7a:115c:a1e0::20');
INSERT INTO nodes VALUES(38,'mkey:465de79eadf29db3136d0b230c481876edbe7e05a803281a523618c586fd3c01','nodekey:01614d4aa1bb0be1f6b41e10aa9ea1c7af206ef9a2571bb68c24e85bea697216','discokey:d3eea5725d8408db2ffc560d74c70da0a70c3f3dc40a0d6a6fad9afaaadee9f2','srv-59','node038',6,'cli',NULL,NULL,'2025-04-04 10:17:46.472491162+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8125:ebe4:83e1:4806:f061:5bd9:a08a:8ccc]:6467","114.199.17.195:52817","[de36:fc02:8cf4:c60d:824a:9963:2440:5b5d]:39343"]','2024-05-22 08:08:16.045350656+02:00','2025-04-04 10:17:46.473325907+02:00',NULL,'100.64.0.33','fd7a:115c:a1e0::21');
INSERT INTO nodes VALUES(42,'mkey:ff2ce8eb04d99e45d7babacacc758ec8e031474fcf494b4c0349c7084cc62365','nodekey:660bae997d6da1efccc0135ed712176a379f59ec9ca7a02eddea607a8855cebe','discokey:66ca4169c6be68079a1244ec506d8c922af4133187e0117a1800ed4791ed9a67','web-21','node042',14,'cli',NULL,NULL,'2025-04-03 14:18:40.656342991+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[3a3f:717c:1ea3:7c82:81e4:5d9d:765f:7da4]:6540","[bc95:459c:aab:499d:4354:d239:ef14:dcb]:14429","[f673:7912:6d5e:7244:62ca:9500:78f5:31c0]:27677"]','2024-07-03 11:12:29.418355657+02:00','2025-04-03 14:18:40.709062776+02:00',NULL,'100.64.0.37','fd7a:115c:a1e0::25');
INSERT INTO nodes VALUES(43,'mkey:df2afe1643d44e7b5d2b4fe1b78e8b0c8c7871b50b1b580048cf6b184cc99143','nodekey:4512e240f89db2671db1ad974c151afad41491d7d11486b644aa2cf66bc3410e','discokey:f4b10325d44499f510cf0bd61d7c9d116b10c14434b8fab4559f0797f033936a','lt-12','node043',14,'cli',NULL,NULL,'2025-03-31 18:38:47.400103948+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c91c:4366:d3bd:a993:b5e:75c7:ef8e:8166]:46974","191.185.253.85:37427","17.31.200.70:26794","[183d:f2d6:b80:36c5:318e:64e9:7f4a:b389]:12440","169.173.198.12:15274"]','2024-07-03 14:48:50.263910778+02:00','2025-03-31 18:38:48.06470771+02:00',NULL,'100.64.0.34','fd7a:115c:a1e0::22');
INSERT INTO nodes VALUES(44,'mkey:7d71974b3095c1ae476074cf0e7e5628088873768b2a24b827c50699dc9d61d5','nodekey:bf967004b398b7634581159dae489f4f6f9ab3a56b35d5c5bbf5751b2ac73bc8','discokey:5be6e1d98febe4e50f1b907d23635c2bd342e9d5ec9524df24c4349c752ac923','db-53','node044',14,'cli',NULL,NULL,'2025-03-31 18:38:49.196820572+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8dab:7bad:415:97d8:4ecb:2a7e:14ae:64f2]:15771","[b501:efaa:c73b:b492:c3cf:865:d55b:9557]:26172","162.210.141.106:52036","[84ef:a164:d1c:d20d:797c:753e:f8fb:3108]:5767","[c15a:e322:a721:c9a7:a662:ccb8:26b8:e1c4]:63192"]','2024-07-03 15:23:48.066044194+02:00','2025-03-31 18:38:49.528314036+02:00',NULL,'100.64.0.35','fd7a:115c:a1e0::23');
INSERT INTO nodes VALUES(45,'mkey:3f3fa2155a168125fd4d22d58f30d1d101796d67dfbe317a3808721019282ce0','nodekey:edccaae68a3381b0f736db6a23a9d45a8747caf1a8427ac5d680205cc4fed415','discokey:7a91312730081d203379ecdf264707a4325fdf272e1338b0abf770f0050e33ae','email-63','node045',14,'cli',NULL,NULL,'2025-03-31 18:38:48.272123393+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["161.33.154.107:16255","[caa0:946e:b130:39aa:31b0:8f9:7526:4960]:1729","120.102.247.255:41936","28.177.95.32:7841","[fb23:5998:c63d:b6c4:e86a:96b2:61c:e110]:51902"]','2024-07-03 15:54:01.706018896+02:00','2025-03-31 18:38:48.790175394+02:00',NULL,'100.64.0.36','fd7a:115c:a1e0::24');
INSERT INTO nodes VALUES(46,'mkey:d084c15ae8c10c1de1d625c7292df7da48e4fcfd1ad860ca140ce9259254a1fa','nodekey:6ea87964a36dfb6e359a0721fee4e988461cbf585410fd2a49321d49e215eecc','discokey:bc27f1168519c55a34986345caeb0f666d18990faa74a8b84b317d33058987b5','lt-93','node046',14,'cli',NULL,NULL,'2025-03-31 18:38:46.808546326+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2077:6b7:927e:5e5c:a0f0:3352:1490:e1e1]:47997","6.170.76.62:28497"]','2024-07-03 19:38:07.783745318+02:00','2025-03-31 18:38:47.865608242+02:00',NULL,'100.64.0.38','fd7a:115c:a1e0::26');
INSERT INTO nodes VALUES(47,'mkey:6a001dd5eed681d035dc3235ead186e6722d92e80695430ec542664659a82b68','nodekey:4a2155f4fac513f7382187a6bced77ab0a1a1c8fc4bfa93f31eb3236bdeb0308','discokey:76377c4b4a67de97ad3ec8af288ef68b7c917da1845351f9e49f7b588bed2b3d','email-54','node047',14,'cli',NULL,NULL,'2025-03-31 18:38:47.867863816+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d722:f972:c192:4cff:3916:e1e7:6d02:236b]:55695","101.58.151.244:39467"]','2024-07-04 10:38:08.344092869+02:00','2025-03-31 18:38:48.178140996+02:00',NULL,'100.64.0.39','fd7a:115c:a1e0::27');
INSERT INTO nodes VALUES(48,'mkey:479cd91a3b16f2636c609f67817778a3ba3f35a33c5f3a6fad9ef86166ccae38','nodekey:5bf0038573184bd6031b88e9412f42eda5a8ddd2ec5761e1f22b9125b3c349c3','discokey:c7e977fadfc1bbd63183a2a2d82f1fb1f1700aa1b36c03b8c1754d46560fdfd0','lt-53','node048',15,'cli','null',NULL,'2024-10-20 13:53:33.831192385+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["60.228.0.149:54791","45.103.140.120:38129","59.24.21.245:44110","[def3:2f58:1a57:4620:9775:7f2c:3aab:52a2]:50978","[9236:c0c2:b9b4:e60b:99ff:582e:50ee:92b9]:25915","84.253.15.156:7777"]','2024-07-26 08:09:56.608302315+02:00','2024-10-20 13:53:33.831387627+02:00',NULL,'100.64.0.40','fd7a:115c:a1e0::28');
INSERT INTO nodes VALUES(49,'mkey:4d5f9a38fce205b2dfb62f42464172a1408e00221317b01332714a4db55e6ebb','nodekey:415009b46e40247f7a60d9e0f53c938b6a032fd4c11ae70d824e2d95cf170957','discokey:280e5896d458bd63044265484d38ad711ef52a68981f83281ff693e837421a13','web-11','node049',16,'cli','null',NULL,'2024-09-19 09:07:18.28136023+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[475b:3641:5abe:b0a8:8a68:dd51:8e80:3efa]:574","153.151.233.195:41734","[19b0:8be2:708:d27f:4d3d:3c93:9979:e9e8]:50438"]','2024-08-05 17:32:41.937626584+02:00','2024-09-19 09:07:18.281618912+02:00',NULL,'100.64.0.41','fd7a:115c:a1e0::29');
INSERT INTO nodes VALUES(50,'mkey:a35a00c69e2fa10d442ae03a4d9312ee61e56caaa030d1303a4ebab2b26c27eb','nodekey:39bf208ba118345630aecd3c6ed042d40b1e6b4897c9548a21a473c28352ba95','discokey:437f4dda6cfd2d269543f32dfaac1333b8660cec03b279728e296f6cbc67ca69','db-28','node050',10,'cli','null',NULL,'2024-08-07 10:10:06.595550455+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["150.170.146.70:3311","139.117.239.209:33788","[2eac:ffa0:99fd:d109:c120:a35d:ed48:eea3]:51544","[7644:c348:2969:b90:e84f:94d4:b629:f266]:49336","169.247.3.239:36225","[5b4c:bb2:d43f:6ff4:d494:8616:a66a:d059]:50360","203.180.122.83:13344","63.162.234.32:11653"]','2024-08-07 11:50:54.144157179+02:00','2024-09-18 16:15:14.050033969+02:00',NULL,'100.64.0.42','fd7a:115c:a1e0::2a');
INSERT INTO nodes VALUES(51,'mkey:38d8adcfb8f6217b6dce62c89e816da260f1b0747a9a980e0ede5de9412aab4b','nodekey:98cb6a87bfa7cd614051008583e5f0904552b44d98854a0fb5d8e0e3c3115949','discokey:104eda6ea8f8fbeae20617662e601bd0acf102511d17ffc829c08db6a7f78872','laptop-32','node051',14,'cli',NULL,NULL,'2025-03-31 18:38:45.515173008+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["33.182.22.166:13283","181.10.243.176:14596"]','2024-08-07 14:19:31.156780417+02:00','2025-03-31 18:38:46.360795928+02:00',NULL,'100.64.0.43','fd7a:115c:a1e0::2b');
INSERT INTO nodes VALUES(52,'mkey:3a83699597e3bee8b15df3733dfb54b1d7af3ff9ccc7a4b65df4b0feb4a3f25c','nodekey:86cf80f0bd8bef4888116f2bab1b5ac4b11bd6fa637f7ef0886cd0aa265b2bec','discokey:28e2d745a5216bdaaeb83b4483b19d1c2ae0c149b97c08c06a4b90ca2c742a00','srv-53','node052',17,'cli','null',NULL,'2024-12-25 17:27:58.515851096+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["72.183.239.155:49891","167.46.143.131:51781","[9e9f:93d:a8cf:c86f:17e3:9e2b:dc42:efa6]:3616"]','2024-09-22 15:48:41.385301399+02:00','2024-12-25 17:27:58.517153789+01:00',NULL,'100.64.0.45','fd7a:115c:a1e0::2d');
INSERT INTO nodes VALUES(53,'mkey:d1fda0c437a79b121817c1c24e88bce18fdab566d5e74678b8730cb48c1dd574','nodekey:1463eab453b78867448baaae38b88547334df5070c30e77a08cd3410bd721d8a','discokey:4688405d194600e9c1a783e71e274c3e42976a5021d81db4ba4a0506a768cbca','srv-86','node053',17,'cli',NULL,NULL,'2025-04-05 07:53:50.501049438+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["69.219.0.37:43476","[6084:ee60:1697:864e:4a61:cf6e:e9b6:4c05]:63961","[fad7:2601:d286:4772:3cce:6e89:f66e:9eeb]:5430","216.60.124.11:45041","[d513:c472:d7a:f316:f610:10d0:9851:4feb]:3955","156.228.105.157:61542","102.126.185.0:50694","[156b:e934:d171:2693:8db4:f193:a58c:17b6]:24190","79.255.179.99:56057"]','2024-10-28 10:04:50.084492941+01:00','2025-04-05 07:53:50.501509322+02:00',NULL,'100.64.0.44','fd7a:115c:a1e0::2c');
INSERT INTO nodes VALUES(54,'mkey:4eee40f0117b3b8580f4cf3ec7be063bb4d82173cfa3c015c8932431940d9c92','nodekey:4241ffb9768a0e31f38cc0c5b2f240c1de72b8810e7ff3705964316e63c1a055','discokey:3ad8f2ebea95d15109a0adfc69b3a6b566ce02ce82df7a32e68f278538bc05a2','lt-15','node054',14,'cli',NULL,NULL,'2025-03-31 18:38:45.793020142+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9fe:6ddd:ab0:1193:7bb7:4a4b:c036:b910]:63516","158.169.112.249:5480"]','2024-12-09 17:10:55.363593066+01:00','2025-03-31 18:38:45.816484332+02:00',NULL,'100.64.0.46','fd7a:115c:a1e0::2e');
INSERT INTO nodes VALUES(55,'mkey:22e4ac4e25b05db4e94b5211e08ed14d983972f92e192f15e0231ff355fd46bf','nodekey:225f907deaffccb674416dc4ba532f0b20304e86d57808eef2d96f15211f2309','discokey:e695b849380f698178e7457311dca3cc10ae13a79b0a71d22130e7c401c4f246','web-26','node055',18,'cli',NULL,NULL,'2025-04-04 15:19:04.171978054+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[ecbc:a9b6:cbb7:695b:62ad:27cb:36f0:2380]:27992","135.238.213.41:64084"]','2024-12-10 13:56:39.287449662+01:00','2025-04-04 15:19:04.174839842+02:00',NULL,'100.64.0.47','fd7a:115c:a1e0::2f');
INSERT INTO nodes VALUES(56,'mkey:ad967c824d2c235ed17b1437f6756d4354ad76a2d27b575c0257ecac9a3a5fd2','nodekey:6196332e325e3f1d0c58acb182b48b070340dd673247c616a28d60a7669f5a4a','discokey:3a67fc6fdb9288679886c2d45dba4d1e1ba014af2c48f0f942acd39ef0e0ee64','email-56','node056',19,'cli',NULL,NULL,'2025-04-05 07:53:56.457113205+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["122.41.198.69:28824","[5437:6f4:94c1:c6c1:43ce:7a41:e5c2:65d0]:57161"]','2024-12-17 14:58:39.429211911+01:00','2025-04-05 07:53:56.457486062+02:00',NULL,'100.64.0.48','fd7a:115c:a1e0::30');
INSERT INTO nodes VALUES(57,'mkey:3d9e1a7fc884de338b8391bbc5d3398c7d0ec4c36388b756df5b2304b727fa11','nodekey:9cd5d41c04ae83ade43363dd165c792cbc5386e0d3e005311ca7c79ae7f7acaf','discokey:2d6fad1f43bc97a6d48bcd400c829db2d4f47291b12a59dcbe669d8b1d341c1b','srv-70','node057',20,'cli',NULL,NULL,'2025-03-29 11:27:16.332745436+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a34b:36c0:9f18:1062:2269:92c:1c83:6ec6]:56902","[41e8:60a4:229:a09b:efd3:c73f:b885:d235]:39533","44.230.54.249:64083","29.229.203.183:13","153.68.228.171:36559","138.154.192.66:772"]','2024-12-17 15:17:14.26936913+01:00','2025-03-29 11:27:16.556356179+01:00',NULL,'100.64.0.49','fd7a:115c:a1e0::31');
INSERT INTO nodes VALUES(58,'mkey:97bc215b57ea30368b04727189d5a09f60e682171b2b05355d046f86cd4aa30d','nodekey:33c0e1c36d9762397b6406cba0f71c77dc7d11b8838911c7ce1a1cb632751e1a','discokey:f8394e6be895b3c2261fab8cd62d1f28124d377df6b4b17dac4b9f18c54a3e00','desktop-11','node058',12,'cli',NULL,NULL,'2025-01-25 18:41:03.881898904+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[2ddd:7c1b:a237:41c8:3baf:e9cc:1f31:9057]:62916","[9c34:190d:7bf0:c940:18d6:f96c:9aca:8c0a]:8787","181.226.177.82:63703"]','2025-01-17 10:17:23.455895657+01:00','2025-01-25 18:41:03.882180987+01:00',NULL,'100.64.0.50','fd7a:115c:a1e0::32');
INSERT INTO nodes VALUES(59,'mkey:4d690637aa5cdd6575d9dbb7fa0b55c83bece3e82bc689e73122c9120f871772','nodekey:8733914d48b0c34a0111ec5f633123ae4ec7de39e597077d659ab8f2354270b9','discokey:ff25bf692a69cc0e79101e1cc1b926ca97b6e3897e65c55e5bd3f09ca1ea6d16','lt-20','node059',21,'cli',NULL,NULL,'2025-04-05 02:21:31.304172899+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[57a6:fde1:814:36cd:f8de:668c:f5fb:4f60]:39714","[f08d:aeaa:107:fc17:5c30:ab9a:e31e:3147]:55879","80.27.167.78:21548","[536b:bf65:da86:c7ca:ecc4:c84a:1811:334e]:24087"]','2025-01-29 11:59:27.291048957+01:00','2025-04-05 02:21:31.304988854+02:00',NULL,'100.64.0.54','fd7a:115c:a1e0::36');
INSERT INTO nodes VALUES(60,'mkey:552ca0e4c611df54a38bd150d7f6c4ef77c66625435073b3751718e44884b92a','nodekey:7b4b25d90935b79af2efc7f0499d3f16a49d5078997314de57b65fb5ce01cf1c','discokey:2118ebb5a0b1c12de379802db2b247fcbf516de56216c4d0ee7a0489dde05071','laptop-14','node060',21,'cli',NULL,NULL,'2025-03-31 18:38:47.60389811+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["67.131.191.86:14533","45.142.234.80:30901","58.251.220.64:42364","[d9a7:5288:3427:e52b:4eb5:794f:11d2:5d6b]:33898"]','2025-01-29 12:01:57.48748166+01:00','2025-03-31 18:38:48.228181117+02:00',NULL,'100.64.0.55','fd7a:115c:a1e0::37');
INSERT INTO nodes VALUES(61,'mkey:f5eaa64ce3d0dbd7539fd9c3f9a494688a4a64b9a3d1fc0b9f40dedc14192ba8','nodekey:ccd6aadf68fdcc95d0d15f6654a0c6bfd5ebbf282491539ee63e5b0848de9ef5','discokey:a492c6d1d0b9de44f6adcf7ac919d49c269058d301b4be21fbb5bf4203b2fa8b','db-97','node061',21,'cli',NULL,NULL,'2025-03-31 18:38:47.847511392+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d002:74d:2b8b:87bb:25cf:5512:50fc:e379]:46829","206.194.47.198:21677","22.203.32.217:28664","112.239.138.73:43954"]','2025-01-29 12:03:01.464646336+01:00','2025-03-31 18:38:48.152116326+02:00',NULL,'100.64.0.56','fd7a:115c:a1e0::38');
INSERT INTO nodes VALUES(62,'mkey:4cbd491b0977f3a8cc92ef9f20a7726b3984f3c0699429ae46a0bceec5febee4','nodekey:66a7e77700fb0f4bae5b282413bdb5ff7c375549dd85c4300c73ff3d8029b4a4','discokey:2e9034fc43993eaa0cf2bc21118d378bb02afb3d197a33cf9f0dd201d176b23c','web-06','node062',21,'cli',NULL,NULL,'2025-03-31 18:38:48.069494509+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["81.51.60.60:63220","12.64.198.119:51541","[5e99:3950:5dc4:45be:bab7:e7ba:2476:14e8]:43360"]','2025-01-29 19:23:14.092804852+01:00','2025-03-31 18:38:48.161442612+02:00',NULL,'100.64.0.57','fd7a:115c:a1e0::39');
INSERT INTO nodes VALUES(63,'mkey:70cc01dc48021a01c44ab1a4bed313bb8270640ef7317fd983019c4b5e593cf3','nodekey:bfff30bca701176ec3b45b2991810cc437e3995207d924c896c4250e0efdb782','discokey:91eb7d9fa7688e3ed641adfae83be298c1ab261fd00dc2b4ad9cb4c269b623fa','laptop-27','node063',21,'cli',NULL,NULL,'2025-04-05 07:46:04.800277542+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["105.95.65.117:11546","[68bb:e8d1:72d8:8b02:608b:2284:c9b3:184d]:20876","[5c17:4014:ea6a:5528:b1a:61b7:5cda:5c5e]:21597"]','2025-01-29 19:41:40.535299057+01:00','2025-04-05 07:46:04.80130455+02:00',NULL,'100.64.0.58','fd7a:115c:a1e0::3a');
INSERT INTO nodes VALUES(64,'mkey:ac14ce6b1ecd1a0d79bbf60d279f19d09baf0ebd409f099a401816516953eb30','nodekey:a711e6a5750ec7cceac6a771396b000766d9af8a34327bf5efec3216316e8afc','discokey:0b370e73e9970987dad3fd00317f51c68e4273fbc11b754ef7e84d4d6880002a','srv-33','node064',21,'cli',NULL,NULL,'2025-04-05 07:53:41.648931109+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["145.91.193.5:37126","[2fb6:ea0a:3639:a1cd:9075:a258:6a79:4f5c]:13944","[2384:3000:4d47:a9e7:54ef:99:52c0:e920]:39358"]','2025-01-30 18:18:57.519126133+01:00','2025-04-05 07:53:41.649324054+02:00',NULL,'100.64.0.59','fd7a:115c:a1e0::3b');
INSERT INTO nodes VALUES(65,'mkey:899a5048a327c15cade8ca854986909ed306f37b2a7655785bbf838c99285ded','nodekey:11b61191a3fc660e078ddc10a65c29c51459b5d67351d99967a504ac6c791f23','discokey:124857d5d0233a30c595fab8e1e5ca8659c9c3c5164fbd084582e7d697c5f580','srv-60','node065',21,'cli',NULL,NULL,'2025-04-05 07:56:55.874050704+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["167.46.40.4:60291","102.143.230.113:46288","[b341:3259:c5dd:9f91:fd70:c616:3033:2b3b]:59081"]','2025-01-30 18:19:40.354692307+01:00','2025-04-05 07:56:55.875106342+02:00',NULL,'100.64.0.60','fd7a:115c:a1e0::3c');
INSERT INTO nodes VALUES(66,'mkey:547a8b97c8c8227d9ba40174ce4d28d0e64f10fae3f39797c60e29742ed59e62','nodekey:cb4a9d1dee6f581036b7c262348cf2c4a96be8b2eea78f7805097e3f7b1a9fcf','discokey:c233a42a4afb5fbf921bf7b3fb4330e6c46273d18570aaf6b7254dbf3c67614f','desktop-82','node066',21,'cli',NULL,NULL,'2025-04-05 07:57:45.102165038+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["21.197.131.68:13997","6.193.99.72:20874","181.248.237.50:21695","171.59.96.217:25726"]','2025-01-31 12:05:28.65297301+01:00','2025-04-05 07:57:45.169550808+02:00',NULL,'100.64.0.61','fd7a:115c:a1e0::3d');
INSERT INTO nodes VALUES(67,'mkey:eb72ad359958c98e28f93485b720b6edef80d1bc33c4f99d772fc17c766039e9','nodekey:9122bd587ae90984e3231e0f48e15aa8abcfbc1b3324becd1f3622bbbe534da1','discokey:7610d45f8d2d3d4d7774c43288a6d50cd798a832732613647caa15e96621a3e3','laptop-93','node067',21,'cli',NULL,NULL,'2025-04-05 07:53:21.399420055+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[3022:fc47:6534:7fe3:9d1e:8d49:75b:984b]:10998","60.241.100.13:15037","[9356:40f8:a98c:a1a9:18e6:e781:f169:4277]:63375","[c733:e842:4621:e95d:6576:9ccf:b2c8:1582]:41668"]','2025-01-31 12:06:30.121464114+01:00','2025-04-05 07:53:21.744746916+02:00',NULL,'100.64.0.62','fd7a:115c:a1e0::3e');
INSERT INTO nodes VALUES(68,'mkey:18580a8353c2c11c364849a9b45141ad99c22e2052de3b07c0a3e095ef6ee9cc','nodekey:d375fbb50d508e31b73b4d960272b0d886df1973e1c00b71723d5dcd7c658b5d','discokey:905bd1003c6e9822d22177c87108107c8a84c9f4f99d0f6e452457b7fdc2f23f','email-60','node068',22,'cli',NULL,NULL,'2025-04-05 07:52:45.084976072+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[d89b:6894:a590:e3f7:d152:3a19:3826:ee28]:40749","99.13.253.35:45887"]','2025-02-03 14:16:55.56431345+01:00','2025-04-05 07:52:45.085842656+02:00',NULL,'100.64.0.51','fd7a:115c:a1e0::33');
INSERT INTO nodes VALUES(69,'mkey:9562166c366f1968a5f82aca83bd8152d893541eed4d8682da0a540825cd44e9','nodekey:93ef8b713afeffc4324b0f9a99e185be61dbff43d6e5769efac6d82481b425c9','discokey:9aa3fe84188c317d17132a26604380ec4aaf7aed94b4b759bb6b643dbd53f8d9','desktop-61','node069',22,'cli',NULL,NULL,'2025-04-05 07:49:17.983292316+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["56.191.25.57:54747","74.194.16.233:59572"]','2025-02-03 15:23:16.312084161+01:00','2025-04-05 07:49:17.983430933+02:00',NULL,'100.64.0.52','fd7a:115c:a1e0::34');
INSERT INTO nodes VALUES(70,'mkey:50329891edd2948b53a0905245386567c98b46bc0d566e39e1763768d51cd638','nodekey:e4ebfcbd1e1d653bda175a62b765c6a646b7844b3d6bd49a9955f96a9b284c6a','discokey:f59cb75bac53aef739bbd5be676808891ebb55550aa0560396dc0532658ed893','web-53','node070',21,'cli',NULL,NULL,'2025-04-05 07:51:00.943197398+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["200.133.152.206:14119","28.101.69.72:35202","52.120.18.3:13372","[dc9a:ed1e:f97d:b356:d5f5:5d44:c917:3077]:33994"]','2025-02-03 18:09:35.161109801+01:00','2025-04-05 07:51:00.943819644+02:00',NULL,'100.64.0.53','fd7a:115c:a1e0::35');
INSERT INTO nodes VALUES(71,'mkey:9845e32e5bdac3fde9276125068f931ea329c65dd136081ddad62a644f41a795','nodekey:9a927389db6eb337e83a82882b5d4dc56667d1f1b2b774122f7e907a5511a95b','discokey:9dd163c600f6a522255812bce48ff492eb56771f74a9e40af7514375b221b86f','email-32','node071',21,'cli',NULL,NULL,'2025-04-05 02:20:31.545698826+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a57e:a4c2:c889:ff09:e17e:a0a0:2623:282f]:2539","137.63.201.132:39740"]','2025-02-04 12:03:50.32663805+01:00','2025-04-05 02:20:31.578007599+02:00',NULL,'100.64.0.63','fd7a:115c:a1e0::3f');
INSERT INTO nodes VALUES(72,'mkey:e91a507e388c22494ec286192de1d6f5943c88a7084fbe1f0274f1d1f6169c06','nodekey:341a90749469a79de31683b37038f0bfad8aa8dceb80ad6850ed148f8fdef655','discokey:a2143d31409f3645542e4ec1c2982e6cb4cfaacbe7cb99111ef112afff1907da','laptop-21','node072',21,'cli',NULL,NULL,'2025-04-03 11:30:24.373825692+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["93.35.202.238:41314","212.130.175.245:30054"]','2025-02-04 12:07:36.231437299+01:00','2025-04-03 11:30:24.376835622+02:00',NULL,'100.64.0.64','fd7a:115c:a1e0::40');
INSERT INTO nodes VALUES(73,'mkey:575f781bb36f7c93cde4d9808e3dedef2c8999864ea1d4e5ee73fdd3d53ac217','nodekey:00e3275941e7a0a73a1e5c44cea638a411c60bb2e257812e0f39152ec0c5a21b','discokey:69a8791ea090c8867078eba807d456ce8363aab46f0c998b327f4c7aaed091a7','db-48','node073',21,'cli',NULL,NULL,'2025-03-31 18:38:46.80095927+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["74.253.132.228:65062","20.112.75.120:15833"]','2025-02-04 12:10:26.50545127+01:00','2025-03-31 18:38:47.215533873+02:00',NULL,'100.64.0.65','fd7a:115c:a1e0::41');
INSERT INTO nodes VALUES(74,'mkey:8a4990c19c547da50875ad00613118d5382717652b4ef9897a1d1c060c40a976','nodekey:4894fef93c5af5094e3f9d18b0c7c822b66ade3221829502c95d2e0ae88ae3c4','discokey:fbe18283aa4bc599c8dd8c82c5fe7b236f1f059bf0344ce9a28e1196258811a1','srv-48','node074',21,'cli',NULL,NULL,'2025-03-31 18:39:34.600462031+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["114.141.127.86:11858","[d05b:3c4f:8402:823f:409f:87b2:4dab:4959]:58420"]','2025-02-06 17:33:12.557302525+01:00','2025-03-31 18:39:34.632063451+02:00',NULL,'100.64.0.67','fd7a:115c:a1e0::43');
INSERT INTO nodes VALUES(75,'mkey:fb413a3831a1db1639197bf6eb887a913ff044346d9fc07eeadc50aa96ae196f','nodekey:763f78cdd841a2859c2a7e1b00129ed1a527e97afc193da93d864263fb048c0e','discokey:1c658f44f2e30f60cd35d6d730625710bb86ca1873f0cc55f6a08f0fc62bd814','srv-20','node075',9,'cli',NULL,NULL,'2025-04-05 07:55:19.031501504+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["147.221.39.105:29051","146.211.135.172:35153"]','2025-02-06 18:23:55.709687186+01:00','2025-04-05 07:55:19.031893003+02:00',NULL,'100.64.0.66','fd7a:115c:a1e0::42');
INSERT INTO nodes VALUES(76,'mkey:7a392b19fffc82a338a4a9e640b63b474c918db933a38bb72dc8957dc95fffb8','nodekey:29a892ef6ca08c4691db5272b310b98a0abd3c2f40372702323afc30909517b9','discokey:4ae873b73a87e7282a9275c3d5e9c68227934f68c6601567d92ddfe202d2cd31','laptop-09','node076',21,'cli',NULL,NULL,'2025-04-03 03:19:15.701019816+02:00',NULL,'{"fake":"data"}','["[9768:8d0:63fc:993c:bab0:4be6:571e:9579]:64245","205.167.26.141:5100","140.129.39.90:29397","163.61.27.204:21704"]','2025-02-14 15:29:45.220999928+01:00','2025-04-03 03:19:15.701454834+02:00',NULL,'100.64.0.13','fd7a:115c:a1e0::d');
INSERT INTO nodes VALUES(77,'mkey:3c49826dc55bc0e0e4643777d4950888452791b9f41b4cdcbce633551c7e4586','nodekey:8c5b96984a77dfba9d9ab0da01c4834e27b4c5e8add2aa9e22be59fa675b58e9','discokey:3f25a8ba8632b6e6dc3148ae42fd90ec433e9c47a98dfcf2f65d326fd030a47c','srv-81','node077',23,'cli',NULL,NULL,'2025-03-31 18:38:48.332406555+02:00',NULL,'{"fake":"data"}','["[734f:219f:40f0:ea33:47c3:ab48:b4f6:a239]:37955","[aade:2619:9aa8:378d:2365:1ab8:8920:a86]:7960","[71ce:8ddc:ec8a:58eb:d01e:2951:a8a7:dff]:31349","209.201.158.153:40013"]','2025-02-14 17:00:54.226657615+01:00','2025-03-31 18:38:48.558712405+02:00',NULL,'100.64.0.68','fd7a:115c:a1e0::44');
INSERT INTO nodes VALUES(78,'mkey:a89496b608c3a9a479a8adcbeac38dd6a856ac638d3ce35c715abb10ef0c278a','nodekey:04e6629fb5fbadb92b0ab1d2c2fa9f77f0b212890b491ddd7913b0d540a346b8','discokey:cd9e6272edc39d50afc27080316aae91de105df7e4f09b27a4301f219217b460','srv-30','node078',23,'cli',NULL,NULL,'2025-03-31 18:38:46.90455425+02:00',NULL,'{"fake":"data"}','["[8dc1:48a1:2e5e:8c45:131e:9d7a:2d85:61ef]:1654","[dbf5:5aac:6a5a:f73c:a62e:69bc:c227:1180]:49484","200.106.54.69:19053","145.76.224.52:32069"]','2025-02-14 18:03:28.401774063+01:00','2025-03-31 18:38:47.149620162+02:00',NULL,'100.64.0.70','fd7a:115c:a1e0::46');
INSERT INTO nodes VALUES(79,'mkey:31e2f2e88d77ea01fc3f7869f672d015dc76b0a12b46829aa1b344fdc0827aae','nodekey:124fde6d53a012efc7626136b2c32df231f87c92aff2c4fe9596c4d79a0c0db1','discokey:796b737943327a0b25ce400e70a628eca55747e61546e6a8a3c84ae8d0a7b491','laptop-17','node079',25,'cli',NULL,NULL,'2025-02-24 18:37:03.584752527+01:00',NULL,'{"fake":"data"}','["61.30.74.244:1071","[4587:514f:e01d:e13b:768f:6402:862c:f470]:52999","105.225.1.28:57634","78.215.20.31:28892","4.11.131.129:50580","61.47.47.240:57553"]','2025-02-15 12:49:11.523904469+01:00','2025-02-24 18:37:03.584913585+01:00',NULL,'100.64.0.71','fd7a:115c:a1e0::47');
INSERT INTO nodes VALUES(80,'mkey:f9c7fccb40e5f809fce3149d8643d3b5459b882837487e19da72f0ec8e9b36c4','nodekey:1fff3539a6acf0e9b8cbb0427824179491ac293b7c0092cd320ff48071eff4a5','discokey:7067ea828bcc4e1e5ee41152c79ea50cdf583a5aca0115cdfe9e2161271e9807','desktop-82','node080',23,'cli',NULL,NULL,'2025-03-31 18:39:08.617771904+02:00',NULL,'{"fake":"data"}','["207.204.17.116:6826","121.94.132.177:17160","[35d1:7781:52e5:8550:72a6:3a02:104e:9380]:34711"]','2025-02-15 21:12:05.434304787+01:00','2025-03-31 18:39:08.727340814+02:00',NULL,'100.64.0.72','fd7a:115c:a1e0::48');
INSERT INTO nodes VALUES(81,'mkey:d089a5917a4b469009a451f834bd93870888f18afd170ef9d7558abcbf7f56e6','nodekey:5c55b563d9796cf68da579cf8fb195a3bfb0d1e80f81d74359ca65b5367b1638','discokey:41a15fa481076c161c6b7bf8120e90ad4e73f3300d711eb81e31b7301d512b83','web-42','node081',23,'cli',NULL,NULL,'2025-03-31 18:38:46.169280974+02:00',NULL,'{"fake":"data"}','["[2b88:a0fa:7305:9a44:6c1f:65d9:5ece:8f1c]:27764","[bd66:349c:a29a:4c05:b3ab:dd92:749c:434e]:27566","69.37.34.188:32687","172.43.25.248:19211"]','2025-02-17 16:05:05.921277876+01:00','2025-03-31 18:38:47.081362641+02:00',NULL,'100.64.0.73','fd7a:115c:a1e0::49');
INSERT INTO nodes VALUES(82,'mkey:9c853f04d1bfe9d438a8719160628329d7bbe56df8dcdb74fbdc4a6570af701b','nodekey:b4a22d5a8c9fad2e1fcc6b5f1693528974a38859285fd67b64bab7e6d3122710','discokey:8cc24fcbe0e6a7fdf36a0cedcbbdc4295194c821cac4a30d5c449cdc4d8723ee','srv-08','node082',23,'cli',NULL,NULL,'2025-04-05 07:04:44.68803226+02:00',NULL,'{"fake":"data"}','["[3c46:906c:ac3:7713:f36c:eef7:3764:7844]:57048","59.217.231.119:10496","[be71:9d1a:fa93:361b:4d94:fbdf:bb45:5421]:15076","[3238:dbe9:f89d:91e1:6338:993d:3e76:8561]:32795"]','2025-02-28 09:21:23.143225002+01:00','2025-04-05 07:04:44.688660094+02:00',NULL,'100.64.0.69','fd7a:115c:a1e0::45');
INSERT INTO nodes VALUES(83,'mkey:0ec54480d16ae9c954b21852540a7e669caf0b1df2ebc3192353058b191d4732','nodekey:981dfbabf258ac252cb4470040b425696d40c15ae9bd70cdbb6541ff47a4f99a','discokey:f77ff65615d1ec4afefd1accd883bfdcad5daf3810a72604fc0a95df2214a1e3','srv-36','node083',26,'cli',NULL,NULL,'2025-04-05 07:53:06.561831453+02:00',NULL,'{"fake":"data"}','["195.8.172.201:53059","[ed13:96e3:daf2:3df4:c6f:3b8d:af9f:eb5b]:10689"]','2025-03-18 09:09:50.849674955+01:00','2025-04-05 07:53:06.562851054+02:00',NULL,'100.64.0.74','fd7a:115c:a1e0::4a');
INSERT INTO nodes VALUES(84,'mkey:911d47d2e7518087e6e43d47074cb58739880e9dfd3912467b8b7d618458f93f','nodekey:87e6089fc13207cdb034bb83d3361be25faca6d35a4a12c1d195d7b5607d726a','discokey:172772172f52d6a3033debe69654f8c9fbd823a7876e36cd890a5a2990eda884','laptop-89','node084',23,'cli',NULL,NULL,'2025-04-01 19:26:08.705667279+02:00',NULL,'{"fake":"data"}','["172.116.24.79:64278","26.140.212.195:18107","[8ea5:bf8c:6205:76f0:a23e:8ac8:f856:f091]:26017","25.10.147.197:36132"]','2025-03-25 10:04:37.147174393+01:00','2025-04-01 19:26:08.706193488+02:00',NULL,'100.64.0.75','fd7a:115c:a1e0::4b');
INSERT INTO nodes VALUES(85,'mkey:0d5a6cbee59cef0dfb24e410466777da40ac48b308d5387c7118371da4dd66c0','nodekey:a3c2435fbaddbe915301fd294f6f7d787f18ea7938b468d0dbc2373585c6e153','discokey:3f4fad81a23a9b13308d6b2e84a217c00a73088d2a31ce5eb15be9192dc7aebb','laptop-35','node085',23,'cli',NULL,NULL,'2025-04-01 23:16:37.04412104+02:00',NULL,'{"fake":"data"}','["[f54b:3eec:1a3d:2bec:d025:cfbb:b951:6e47]:10751","169.51.234.97:16861","16.142.13.19:36771","[ad8a:a3fa:8d4d:c659:5e32:45dd:d95f:abc8]:43118"]','2025-03-25 10:08:52.471661925+01:00','2025-04-01 23:16:37.044513666+02:00',NULL,'100.64.0.76','fd7a:115c:a1e0::4c');
INSERT INTO nodes VALUES(86,'mkey:6e91fa8345d4795f579da2e0c8672463bfdc4035eb5f31fd0a511722e6986ca4','nodekey:0064d45bc62c00ddf68241741547493ef6a6d0f4ead224d963500ea42fb90ae4','discokey:3d63df2a68aa3ac1fd33e0bb8eabc59a5f7f03eec4c8d1e2e3693f69f2fe90ee','laptop-84','node086',27,'cli',NULL,NULL,'2025-04-03 21:56:30.423789526+02:00',NULL,'{"fake":"data"}','["36.19.57.186:49366","[cf88:94d3:5835:2356:c48a:6f91:dafc:9c5d]:24503","[83c:82b4:9941:dec8:30fa:4c7f:de12:fd5c]:60355"]','2025-03-26 10:24:31.473595709+01:00','2025-04-03 21:56:30.424301457+02:00',NULL,'100.64.0.77','fd7a:115c:a1e0::4d');
INSERT INTO nodes VALUES(87,'mkey:ecdf9b138473ce9d2b2b4861bf2a358bfda62032572e1474a9726f45f24e3702','nodekey:69ad63020724d64042e91204bbd382fe4f8e838d2eca106709dc2b61592462a9','discokey:f574c20bb2f8558f787798b4b89918e5bbfc8d3001ef41ab155d8adb4ceda4e0','lt-76','node087',27,'cli',NULL,NULL,'2025-04-05 06:05:53.807723942+02:00',NULL,'{"fake":"data"}','["8.73.3.103:62847","[fd18:384b:ef76:f4b7:6983:bd4e:70af:ce35]:42618","7.111.70.18:4634","85.240.97.0:21327"]','2025-03-26 14:30:57.179694234+01:00','2025-04-05 06:05:53.808074341+02:00',NULL,'100.64.0.78','fd7a:115c:a1e0::4e');
INSERT INTO nodes VALUES(88,'mkey:a4a50964463b8a2bb0778291c014c4ffc1de4b45140278723879e3afd7ad3b53','nodekey:7befe9b0bd2e08bc976c08e2b199069d0fc42d0ea8dbb346ccd706f1771c6d74','discokey:fc3a7797bd83d5c4109b33fb7c52cd4fca772e91d31787f7bb09ddf9d5d8df17','db-62','node088',27,'cli',NULL,NULL,'2025-04-05 06:45:42.584225511+02:00',NULL,'{"fake":"data"}','["48.12.29.120:59556","146.247.211.102:6983","212.18.134.205:41528","190.153.32.51:23708","33.50.209.62:29699"]','2025-03-26 14:37:55.198097806+01:00','2025-04-05 06:45:42.585458518+02:00',NULL,'100.64.0.79','fd7a:115c:a1e0::4f');
INSERT INTO nodes VALUES(89,'mkey:7c3f129f0eb0f541a270bd8d4236991cbcfc984d5fbc422e0f227401b3e33fcb','nodekey:9e8eac7d23ec974e4170fb5437c80c773c8f93b5d99fa479f0a7a92660423f4d','discokey:436409c6a1b9a7e50e2e7b7a07861f6d29f1d1a1f0934f8145d2d7a959b0daeb','srv-64','node089',28,'cli',NULL,NULL,'2025-04-03 21:12:36.172240418+02:00',NULL,'{"fake":"data"}','["165.160.173.41:62002","[d35d:30be:3c0a:c5f2:40ca:40f4:9b64:de92]:54562","[e40f:e89b:a9f5:d5cd:d553:b6:17f3:3d88]:21519","102.217.166.61:13721"]','2025-03-31 18:34:22.574460539+02:00','2025-04-03 21:12:36.172550446+02:00',NULL,'100.64.0.80','fd7a:115c:a1e0::50');
INSERT INTO nodes VALUES(90,'mkey:3aedbb5b71c6de73eeb59138b920c4c5a62debd4f738d4856115412e5f8f9318','nodekey:d7d143dc5680d770fe0ba2273eb3b01004593c2b187edafde8f89709de3d0078','discokey:7c45bed52e4d175be90c88784a39adcd765627238691aa9963191e0acef41624','srv-73','node090',27,'cli',NULL,NULL,'2025-04-05 07:31:24.445741627+02:00',NULL,'{"fake":"data"}','["[bf19:5560:9254:d556:e834:573e:63a8:92f1]:57176","[48b1:5eba:7dda:918d:19ac:f3da:239a:72f8]:6265","104.240.254.212:44730"]','2025-04-03 17:52:02.130025013+02:00','2025-04-05 07:31:24.473509723+02:00',NULL,'100.64.0.81','fd7a:115c:a1e0::51');
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "routes" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`node_id` integer NOT NULL,`prefix` text,`advertised` numeric,`enabled` numeric,`is_primary` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_routes` FOREIGN KEY (`node_id`) REFERENCES `nodes`(`id`) ON DELETE CASCADE);
INSERT INTO routes VALUES(1,'2023-05-19 07:09:23.387641743+02:00','2023-05-22 09:48:18.908103256+02:00',NULL,3,'192.168.224.0/21',1,0,0);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-05-17 19:36:55.859473496+02:00','2023-05-17 19:36:55.859473496+02:00',NULL,'user001','','',NULL,NULL,'');
INSERT INTO users VALUES(2,'2023-05-17 19:36:57.059073465+02:00','2023-05-17 19:36:57.059073465+02:00',NULL,'user002','','',NULL,NULL,'');
INSERT INTO users VALUES(3,'2023-05-18 10:10:36.248939077+02:00','2023-05-18 10:10:36.248939077+02:00',NULL,'user003','','',NULL,NULL,'');
INSERT INTO users VALUES(4,'2023-06-10 09:06:13.920718561+02:00','2023-06-10 09:06:13.920718561+02:00',NULL,'user004','','',NULL,NULL,'');
INSERT INTO users VALUES(5,'2023-06-11 19:58:32.371218434+02:00','2023-06-11 19:58:32.371218434+02:00',NULL,'user005','','',NULL,NULL,'');
INSERT INTO users VALUES(6,'2023-06-17 19:39:53.031565686+02:00','2023-06-17 19:39:53.031565686+02:00',NULL,'user006','','',NULL,NULL,'');
INSERT INTO users VALUES(7,'2023-06-20 11:35:09.325846831+02:00','2023-06-20 11:35:09.325846831+02:00',NULL,'user007','','',NULL,NULL,'');
INSERT INTO users VALUES(8,'2023-06-21 22:47:48.196234382+02:00','2023-06-21 22:47:48.196234382+02:00',NULL,'user008','','',NULL,NULL,'');
INSERT INTO users VALUES(9,'2023-06-22 08:30:35.068995572+02:00','2023-06-22 08:30:35.068995572+02:00',NULL,'user009','','',NULL,NULL,'');
INSERT INTO users VALUES(10,'2023-07-03 10:18:32.123226+02:00','2023-07-03 10:18:32.123226+02:00',NULL,'user010','','',NULL,NULL,'');
INSERT INTO users VALUES(11,'2023-07-03 10:18:37.130387602+02:00','2023-07-03 10:18:37.130387602+02:00',NULL,'user011','','',NULL,NULL,'');
INSERT INTO users VALUES(12,'2023-12-15 08:05:06.013615212+01:00','2023-12-15 08:05:06.013615212+01:00',NULL,'user012','','',NULL,NULL,'');
INSERT INTO users VALUES(13,'2024-02-03 16:32:42.224977233+01:00','2024-02-03 16:32:42.224977233+01:00',NULL,'user013','','',NULL,NULL,'');
INSERT INTO users VALUES(14,'2024-05-03 10:12:38.220973042+02:00','2024-05-03 10:12:38.220973042+02:00',NULL,'user014','','',NULL,NULL,'');
INSERT INTO users VALUES(15,'2024-07-26 08:08:40.979783263+02:00','2024-07-26 08:08:40.979783263+02:00',NULL,'user015','','',NULL,NULL,'');
INSERT INTO users VALUES(16,'2024-08-05 17:32:02.878091894+02:00','2024-08-05 17:32:02.878091894+02:00',NULL,'user016','','',NULL,NULL,'');
INSERT INTO users VALUES(17,'2024-09-22 15:48:00.287392203+02:00','2024-09-22 15:48:00.287392203+02:00',NULL,'user017','','',NULL,NULL,'');
INSERT INTO users VALUES(18,'2024-12-10 13:55:11.256977421+01:00','2024-12-10 13:55:11.256977421+01:00',NULL,'user018','','',NULL,NULL,'');
INSERT INTO users VALUES(19,'2024-12-17 14:57:58.550971236+01:00','2024-12-17 14:57:58.550971236+01:00',NULL,'user019','','',NULL,NULL,'');
INSERT INTO users VALUES(20,'2024-12-17 15:02:08.053169491+01:00','2024-12-17 15:02:08.053169491+01:00',NULL,'user020','','',NULL,NULL,'');
INSERT INTO users VALUES(21,'2025-01-28 15:57:32.774456057+01:00','2025-02-06 17:43:41.935399542+01:00',NULL,'user021','','',NULL,'','');
INSERT INTO users VALUES(22,'2025-02-03 14:10:50.491924701+01:00','2025-02-03 14:10:50.491924701+01:00',NULL,'user022','','',NULL,'','');
INSERT INTO users VALUES(23,'2025-02-14 16:58:30.250289644+01:00','2025-02-14 16:58:30.250289644+01:00',NULL,'user023','','',NULL,'','');
INSERT INTO users VALUES(25,'2025-02-15 12:48:14.650995528+01:00','2025-02-15 12:48:14.650995528+01:00',NULL,'user025','','',NULL,'','');
INSERT INTO users VALUES(26,'2025-03-18 09:09:00.456523573+01:00','2025-03-18 09:09:00.456523573+01:00',NULL,'user026','','',NULL,'','');
INSERT INTO users VALUES(27,'2025-03-26 10:23:51.960113834+01:00','2025-03-26 10:23:51.960113834+01:00',NULL,'user027','','',NULL,'','');
INSERT INTO users VALUES(28,'2025-03-31 18:25:26.535133091+02:00','2025-03-31 18:25:26.535133091+02:00',NULL,'user028','','',NULL,'','');
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_routes_deleted_at` ON `routes`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,146 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `migrations` (`id` text,PRIMARY KEY (`id`));
INSERT INTO migrations VALUES('202312101416');
INSERT INTO migrations VALUES('202312101430');
INSERT INTO migrations VALUES('202402151347');
INSERT INTO migrations VALUES('2024041121742');
INSERT INTO migrations VALUES('202406021630');
INSERT INTO migrations VALUES('202409271400');
INSERT INTO migrations VALUES('202407191627');
INSERT INTO migrations VALUES('202408181235');
INSERT INTO migrations VALUES('202501221827');
INSERT INTO migrations VALUES('202501311657');
INSERT INTO migrations VALUES('202502070949');
INSERT INTO migrations VALUES('202502131714');
INSERT INTO migrations VALUES('202502171819');
INSERT INTO migrations VALUES('202505091439');
INSERT INTO migrations VALUES('202505141324');
CREATE TABLE IF NOT EXISTS "pre_auth_keys" (`id` integer,`key` text,`user_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime, `tags` text,PRIMARY KEY (`id`),CONSTRAINT `fk_pre_auth_keys_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE);
INSERT INTO pre_auth_keys VALUES(1,'463a8b372963aeaca12400faa0c7ea29e9bfa3b4c59e9622',3,0,0,1,'2023-05-19 05:09:19.66636462+00:00','2023-05-19 05:14:19.664224869+00:00',NULL);
INSERT INTO pre_auth_keys VALUES(2,'77a019cb12c0d0b9347a17ab23fa4c87983814fe36bb2fbb',14,0,0,0,'2024-05-03 08:13:55.8614948+00:00','2024-05-04 08:13:55.85782156+00:00',NULL);
CREATE TABLE IF NOT EXISTS "api_keys" (`id` integer,`prefix` text UNIQUE,`hash` blob,`created_at` datetime,`expiration` datetime,`last_seen` datetime,PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS "nodes" (`id` integer,`machine_key` text,`node_key` text,`disco_key` text,`hostname` text,`given_name` varchar(63),`user_id` integer,`register_method` text,`forced_tags` text,`auth_key_id` integer,`last_seen` datetime,`expiry` datetime,`host_info` text,`endpoints` text,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`ipv4` text,`ipv6` text, `approved_routes` text,PRIMARY KEY (`id`),CONSTRAINT `fk_nodes_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,CONSTRAINT `fk_nodes_auth_key` FOREIGN KEY (`auth_key_id`) REFERENCES `pre_auth_keys`(`id`) ON DELETE SET NULL);
INSERT INTO nodes VALUES(1,'mkey:38315e39aa0f0ac09b49850ace14a9bffab27d4258daf52bedfcca5d3045cd0c','nodekey:5b55d8314717137fc190e4b42811f5eff1241cf32cd24d768c1e710962884db4','discokey:ac65232fe17445944990c9532faec80c27081443997d02b1d3586e7b481261b3','laptop-74','node001',2,'cli',NULL,NULL,'2025-06-22 07:21:58.271483603+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[bab2:a8b9:e00d:9655:f397:9a5e:c6bb:2300]:9564","[b8f0:cf44:22c8:82d1:f79:c3eb:9144:c24f]:6142","[8e25:af1:e31a:8fcc:7dcf:be1:a3c9:ed6a]:38766","[37a1:215f:bf3d:3fb1:6399:f7cb:4048:3ca8]:51666","137.242.125.72:25376"]','2023-05-17 19:38:13.531518257+02:00','2025-06-22 07:21:58.271647152+02:00',NULL,'100.64.0.1','fd7a:115c:a1e0::1',NULL);
INSERT INTO nodes VALUES(2,'mkey:1e274f40556282a5bbab04b6754985233ccdf971b663e5b38fc027035e833e9a','nodekey:5b16c7e14191ca2e57eccd86ec636db605fa5dc2c8856be5fa7f9b087cf24890','discokey:5fd2f116700fd48ce06e35e8dd11c847ccd7694e01ec4b3f6ef25f67c14ee197','email-21','node002',1,'cli',NULL,NULL,'2025-04-17 20:26:48.332385788+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5aae:55d1:7b5d:628d:bc07:b3e0:eca2:836d]:13912","[5583:8a0e:1564:ac5b:98ab:59a3:126:cba2]:35537","84.23.188.83:48876","44.184.117.89:36643","90.223.136.253:7056","[e43c:be7:7f4e:8217:a009:7f9d:a510:1af6]:18872"]','2023-05-18 10:09:21.757289398+02:00','2025-04-17 20:26:49.018604197+02:00',NULL,'100.64.0.2','fd7a:115c:a1e0::2',NULL);
INSERT INTO nodes VALUES(3,'mkey:5b57ab9712ce9587cd887a650ba629d2aeceb57d83a0bcadf9fa19a33e141a07','nodekey:788dce6f52985afca7b36ad6961dd93b7cd6d102574e243c1f39b14804b370a9','discokey:8b7c85ead8a9e7225cda4c5d1975dc426aefe919b4153f4653228e325c015bfb','desktop-51','node003',3,'authkey','[]',1,'2025-06-20 23:54:25.334614243+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[fdbe:7908:805e:6c8f:47c2:2c87:b1c4:44]:48470","188.237.187.170:7622"]','2023-05-19 07:09:21.399903526+02:00','2025-06-20 23:54:25.335360998+02:00',NULL,'100.64.0.3','fd7a:115c:a1e0::3',NULL);
INSERT INTO nodes VALUES(4,'mkey:538f91fe9e485697ce13f9444ee0dadf2aaaed712fdfa03ba102113c6505db37','nodekey:1936bdc567d6758b11b2cc06ea7ff74bb933a44421fb17323965d5a402e39783','discokey:e8b762a384d644175f3b4e4fd36867b2c435e03eb0bf6b9e7ebd4f0ce83c13ef','lt-57','node004',4,'cli',NULL,NULL,'2025-06-28 12:23:20.734405211+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f6d5:e904:28e7:a5a4:12a3:96d8:9391:b22c]:37336","113.59.7.205:48432"]','2023-06-10 09:31:51.940506933+02:00','2025-06-28 12:23:20.735270748+02:00',NULL,'100.64.0.4','fd7a:115c:a1e0::4',NULL);
INSERT INTO nodes VALUES(5,'mkey:12afa721b0310fd9cf7501a19e5f23a2d33c87f989a9b0233bc09e8eb9e5eaa2','nodekey:83e8f99465cfd0ef79190bfb341bb742b39d9ddd7cfeab237153b58858a2fed2','discokey:d4fdc314c7b73e21589efef171f10158379ade1adbdc281482a62c6c20fc2ed8','lt-50','node005',4,'cli',NULL,NULL,'2025-06-28 12:20:57.298589096+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[8105:c5c2:647f:e97e:85b7:577b:20b0:e4f]:16947","1.79.159.39:34092","[b12e:af88:3c55:41f8:5fba:2aa3:3248:15c1]:23643","186.84.191.82:2621","[c9d0:4e15:513a:171b:9911:f9a0:cccf:cd83]:24151"]','2023-06-11 13:56:42.694329408+02:00','2025-06-28 12:20:57.298996156+02:00',NULL,'100.64.0.5','fd7a:115c:a1e0::5',NULL);
INSERT INTO nodes VALUES(6,'mkey:229f561cff2994f922e02f0e286f6afacdb603245fa1a9c234ddb81f79674fd2','nodekey:edde606fce52c6196c994a72eb0f24ee4d4b8047d22e16dfef3f6531a8eaeb4f','discokey:2814289eb6e7bbd6093798f51410a2babab3f6a0d9ca105136d1ed387cb2ceb6','srv-66','node006',4,'cli',NULL,NULL,'2025-06-28 12:22:36.34542317+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["128.160.129.121:10590","48.173.178.104:58309","102.207.203.66:23963","153.152.90.188:59135","187.96.173.136:34092"]','2023-06-11 13:57:44.975695604+02:00','2025-06-28 12:22:36.364369698+02:00',NULL,'100.64.0.6','fd7a:115c:a1e0::6',NULL);
INSERT INTO nodes VALUES(7,'mkey:1634b8df4138ea0986578531f3be5bc398d11c83b226674d9b4b0d6daade5268','nodekey:9fa6e75dec8ed3e22a1f201fe661e67fe03de2583bb2e16ec1e97ec8b34a1ede','discokey:d4408013dd173b024ca49301592fd89d89260615f83253780b6d2c9af652f75d','web-46','node007',4,'cli',NULL,NULL,'2025-06-28 12:23:01.214171138+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["189.17.47.14:59833","[fa71:f70b:e65d:59b5:f599:8597:2bc9:56b6]:12277","[8ddd:4aae:2b94:4c1a:d05f:65d2:2bdb:b400]:42839","[c493:a941:58b6:7634:6221:70ba:20e6:40c4]:35486","[9b54:61a6:c678:edac:956f:741e:5e2c:9ec9]:17930","[cd3f:af1c:fcb4:bcb3:806e:adf4:3f3f:ab36]:58513"]','2023-06-11 14:16:56.951313537+02:00','2025-06-28 12:23:01.214662148+02:00',NULL,'100.64.0.7','fd7a:115c:a1e0::7',NULL);
INSERT INTO nodes VALUES(8,'mkey:c841efdb3731e5e826ebfecbcb50460016e7020a2b73ac202aaffc69f1260ca4','nodekey:9bbd9e2ed99a94a3284391ef3e949806578fe58f5c7e5f444cfd72e1068c7252','discokey:c763a94031000944026c3243e175a7dde5ec85ad92dffadf2ba365b8d6b4fdf4','email-75','node008',5,'cli',NULL,NULL,'2025-06-28 12:23:04.274230621+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[dd24:c2dc:debd:ad2f:ae50:cd15:9cd2:b296]:24266","[489b:6c59:1877:6215:ddc8:57f8:78dc:321c]:3025","77.213.161.20:47662"]','2023-06-11 19:59:30.401970393+02:00','2025-06-28 12:23:04.275091119+02:00',NULL,'100.64.0.8','fd7a:115c:a1e0::8',NULL);
INSERT INTO nodes VALUES(9,'mkey:b1e7fb42e35b0219c318fee0717c988ab851714c6f487bb26a184b8340920d87','nodekey:da9ddc2fadd4a47eefa8a541e9c3e316353a5650a26d30d258d60ee9fce9c899','discokey:c52edf1d688d73febbc73c977c723a638da546afcb3813de4e716c1e013404ba','lt-35','node009',6,'cli',NULL,NULL,'2025-06-22 06:38:00.485835142+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b9f9:eec0:d656:cd83:8595:46fc:b677:6ade]:17494","126.251.133.86:44347"]','2023-06-17 19:40:45.468789461+02:00','2025-06-22 06:38:00.486219076+02:00',NULL,'100.64.0.9','fd7a:115c:a1e0::9',NULL);
INSERT INTO nodes VALUES(10,'mkey:dc84e5b1cf58ec8f7200ec0a655c1d5843c520ea59aa7ddd111ad5c9beba9bd8','nodekey:3c06f5a6d7f267023044ab632892b51f5af1ce4d84f0739e88823bc22cda6c57','discokey:3c1aa008a7811012038cd6658b6f290b3d252074c47d23cf1766f878340a30bf','desktop-75','node010',6,'cli',NULL,NULL,'2025-06-24 15:38:08.972653514+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["187.166.20.165:11208","78.47.168.253:34957","[1d14:fb12:d0a0:ad7a:ad7d:496b:154a:7042]:33635","41.172.94.101:32111","223.204.123.230:38090"]','2023-06-20 11:18:35.905417341+02:00','2025-06-24 15:38:08.973364357+02:00',NULL,'100.64.0.10','fd7a:115c:a1e0::a',NULL);
INSERT INTO nodes VALUES(11,'mkey:94da5084f8fc1cfe7671b94a0d7ef767719bd0fed89f16bc2726728db4cd9d25','nodekey:e6527563ef7a2647b6c719e0c9c95c1ab2a2eeef7fbb3f46a108ee0fbca026f0','discokey:f76230afd20bfcce74fd0d689b35e82cab5bfdf4cd1530073e87b1acae513c2b','web-50','node011',7,'cli',NULL,NULL,'2025-06-27 16:44:35.818823257+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[bed5:a4c2:8547:c044:9956:2566:d794:c918]:56801","113.147.88.203:61138","22.207.212.228:27547","[2c3e:2260:8c34:275:2287:b721:1bdb:d462]:59540"]','2023-06-20 11:35:15.063855316+02:00','2025-06-27 16:44:35.81914126+02:00',NULL,'100.64.0.11','fd7a:115c:a1e0::b',NULL);
INSERT INTO nodes VALUES(12,'mkey:4d2ff8526b10e056a5d073d5640fd28002ca21b561c55407175712a98e37ada7','nodekey:a1835798e4fefbece3000abb9afdd3cb01e5a4eebafc1218ed627cde2175c1f1','discokey:24b8f6da3ef9e024e273918de8869fdfebc45f789d14c4a50a592cc27259f1c1','db-64','node012',5,'cli',NULL,NULL,'2025-06-28 12:22:57.399153574+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f1ba:2aea:9e9e:2802:ebb9:ba04:a564:7998]:52919","[ede2:462a:f99c:24c3:b1b5:8b97:abe2:3ddb]:65141","[dfe7:6f6b:a382:4fc:a3f6:eb9:9ebc:5798]:1474"]','2023-06-20 18:22:35.061914624+02:00','2025-06-28 12:22:57.400249031+02:00',NULL,'100.64.0.12','fd7a:115c:a1e0::c',NULL);
INSERT INTO nodes VALUES(18,'mkey:5e192b1b323439fcc3b921c4f523ce9b7cce867220bd092d23be2451ce93a4a5','nodekey:1452cb2c8f26c8988cd8d8ed42957c78e3ab922bdf9773978c853e4254e23fbb','discokey:b7b41dc5de1fdcc4bd609dc72f79d27269367dbf72ab73ab61e998aa31eac6a2','web-19','node018',9,'cli',NULL,NULL,'2025-06-27 21:23:45.610301586+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["60.5.210.145:1193","[5698:e318:b38c:4331:5152:c2df:743f:8ead]:34839","33.51.84.119:46756","[c844:704e:c3c0:e709:8f94:3564:1b4d:d2d9]:8357"]','2023-06-22 08:30:54.08720463+02:00','2025-06-27 21:23:45.610590171+02:00',NULL,'100.64.0.16','fd7a:115c:a1e0::10',NULL);
INSERT INTO nodes VALUES(20,'mkey:29574231af6530b1386ebe61550e3b14263500b7a70395e7b540a54ddc3fc777','nodekey:c1d6f11f1bdc2756be5836e556e2a8c10f50aed84c969662b67ebd942db8b8ce','discokey:dd5d8c17120e8560f2698b44d571ca1b0bb90e012dd34be9d31ae169d26ca344','laptop-98','node020',11,'cli',NULL,NULL,'2025-06-27 12:57:39.754859479+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["26.88.253.147:32968","[3138:83c6:ae09:a073:7888:71e0:494:3863]:59700","191.156.96.176:5489","[166e:c30:4d73:440f:456a:22be:71e1:142b]:33036","[6d05:6bb8:3bec:c76c:1890:ca9c:2684:1bbb]:31223","173.218.108.179:51272"]','2023-07-10 12:40:34.838579199+02:00','2025-06-27 12:57:39.755061411+02:00',NULL,'100.64.0.14','fd7a:115c:a1e0::e',NULL);
INSERT INTO nodes VALUES(21,'mkey:94ebb2a00b9bbfe15d9a19a85409c5af01aa1b518319fbb394421888fa9fb7f9','nodekey:9109c5a733073fe487b72a328742f98f4e6e71748f1380562c46b1aaa2aa3f7e','discokey:1f11ce0393834879b2b9bd10b5fe034c85615ce94b30f67fe6153747b65653dc','laptop-07','node021',11,'cli','null',NULL,'2023-11-20 07:19:19.447470862+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["85.50.19.51:63246","[cff3:24ee:4692:f8a0:842b:c26b:e549:1f3a]:31064","207.187.74.99:12216","63.3.67.150:22907"]','2023-07-10 12:42:43.290469734+02:00','2024-09-18 16:15:14.03886353+02:00',NULL,'100.64.0.15','fd7a:115c:a1e0::f',NULL);
INSERT INTO nodes VALUES(22,'mkey:ec629722edab9383e9f816b50c2221486d52a55dd0735be575d20441b6e0c0cd','nodekey:8fc1644973c6614621da30be00b52f277c5e57f80032c681ac084354e7974665','discokey:286e95bbaca154ac900767ecd1f028764528a176cdc7c6e0bd3e0d2fff71207c','laptop-16','node022',6,'cli',NULL,NULL,'2025-06-26 08:55:27.018436146+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[fc33:9337:6f8c:253d:d87e:2d45:d618:5830]:33733","[6f37:bdc3:19c5:7d22:190e:a9d4:1ca1:e1cc]:59098","[4b06:6a05:94bd:4bca:676:93a4:2e20:b923]:23713","[68:80fa:7b30:3a0:d1fb:3e89:2c73:256b]:30308"]','2023-08-05 12:08:48.132161695+02:00','2025-06-26 08:55:27.028290638+02:00',NULL,'100.64.0.17','fd7a:115c:a1e0::11',NULL);
INSERT INTO nodes VALUES(23,'mkey:0323ca3e9858de1b53d0e3750e441d4da9a63f7e526be63b98430dbb51c66ebb','nodekey:8cd1023d1cdebd18f0f05d30852cde076e87cda3d6bc8a2785ef8f7ef37df099','discokey:0dd0075a712979849441f180da7e62bc73069050a4d25789e6f6afbcd4acb072','db-17','node023',12,'cli',NULL,NULL,'2025-06-08 16:50:57.344745353+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[f371:f639:cf31:c836:19ec:b41f:f0cd:4487]:36912","27.211.232.205:36366","[e83e:63c5:7e37:2195:1ede:1e3b:f549:85d0]:56150","[92ea:991a:46a1:e1e6:6b82:659a:acc7:2272]:38018","93.129.193.97:13477"]','2023-12-15 08:05:56.592241745+01:00','2025-06-08 16:50:57.344868501+02:00',NULL,'100.64.0.18','fd7a:115c:a1e0::12',NULL);
INSERT INTO nodes VALUES(24,'mkey:f24720736968f27b5c78d9c7734a083464275b63b50662adfce0d0ad5304e4d3','nodekey:b254e68666635d7fdae5c391f6ce81b802e018cf431408646f604c5ca8dbdb8c','discokey:498b9f4eca5fb3725cec3570d70c768660e124d3e88a85949706bc7384109de6','db-59','node024',12,'cli',NULL,NULL,'2025-06-27 21:59:35.663631021+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["43.114.58.145:47143","[758f:df49:401f:abcb:57ff:c04b:79e6:8519]:62313","[2458:76c5:7d48:c26f:34e:1663:6911:ff6e]:22202","66.66.46.14:16686","[fd3e:93e:a9b5:2034:a98e:4ab1:6317:f13a]:46054"]','2023-12-15 11:14:36.765183054+01:00','2025-06-27 21:59:35.663899525+02:00',NULL,'100.64.0.19','fd7a:115c:a1e0::13',NULL);
INSERT INTO nodes VALUES(25,'mkey:f10b7f9f385e48dc99ec0944b8a04ec4d3e5613587419c134440121fa747ee75','nodekey:9559349d25dd3fa88b9595cb4ccebeeb4712338757a209e936afe37ec2643dbc','discokey:b9a07315c1eb2e074871feebe899bd2ecae64d98a8edf08883785130ef386728','laptop-25','node025',6,'cli',NULL,NULL,'2025-06-28 12:22:37.905312423+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9e60:1bb7:b542:2f50:269f:5ef:72b6:f4ba]:34677","159.52.2.200:7205","[5b7b:e424:ea77:aa8a:f835:d6bb:2e1f:52ea]:19152","[bb06:d322:7cec:426b:ef38:55d0:e7ce:95bc]:31597"]','2024-01-05 17:32:40.940566279+01:00','2025-06-28 12:22:37.906446459+02:00',NULL,'100.64.0.20','fd7a:115c:a1e0::14',NULL);
INSERT INTO nodes VALUES(26,'mkey:b07183e67f21f2d1b4f7f4eccb393c57257683629a59758f393c47b759f5da81','nodekey:b246eeb06f7aa31c0f92aa63a6836e6ecde5cccb73d0c03e103601a7cded51b6','discokey:30fbedab81413cac0736dcd7b473511905658726861a326a556bb2df80bf15b6','db-13','node026',6,'cli',NULL,NULL,'2025-06-28 12:23:07.762159769+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[769:97e6:7060:f428:ee55:f77:43a7:8d18]:61446","[630f:7c1f:d48b:ea66:23d7:1ab9:8bd1:10f3]:25600","160.27.109.39:47606","[62f5:b64d:d2e4:9015:b03a:c64e:656:8c59]:5020","3.166.190.93:19852","[243b:de9c:b8c:ea69:b66d:b3ce:14a5:9671]:22747","32.167.123.100:57075","[2c67:a9f3:3163:c675:3386:2447:1cc:ed3a]:42590","64.137.67.1:56198","163.42.128.241:47535","49.160.22.202:42427","[1526:e34a:8857:394e:bbe0:c043:4b37:68d4]:5245"]','2024-01-05 17:34:19.811670479+01:00','2025-06-28 12:23:07.762465037+02:00',NULL,'100.64.0.21','fd7a:115c:a1e0::15',NULL);
INSERT INTO nodes VALUES(27,'mkey:d95c13394bdb912ef51f3123fdb0495feef567dc13724efd8dea17b33ce7aa1d','nodekey:fd8be528ea41d74697d46084c8cf560fff1c21b3193bec752ba2d60457396b19','discokey:9ec066ac46492f546a67be34b417eb469dfc95aff8b7be28be3bd8b36bf98653','db-72','node027',6,'cli','null',NULL,'2024-01-16 14:32:21.570104175+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5760:dc4e:eac8:5c38:6c9c:8451:98d6:4e9c]:21573","[e350:bf94:9128:bca7:8c74:ab49:c419:4c50]:18052","222.155.102.116:42746","[e32f:122e:8a:e473:4b83:8ec9:61db:60ce]:37054","154.68.57.163:54048","[c5a0:942c:ed88:2277:3c9a:4f65:a25e:5b40]:27852"]','2024-01-05 17:48:25.466030859+01:00','2024-09-18 16:15:14.040766068+02:00',NULL,'100.64.0.22','fd7a:115c:a1e0::16',NULL);
INSERT INTO nodes VALUES(28,'mkey:08347db9fbe8e5e7a968c2ab9ddd1ff530ea98163c0bab7769316307545f4d46','nodekey:b6b03efd7deb52dbe0298708ea37400510ab7589b0b1787eac1a5f9b50aa7c80','discokey:6a0ab2f3329d9fe5f50c76f9f3f1d2e797574af93d823a511df57f45414f647e','srv-42','node028',7,'cli',NULL,NULL,'2025-06-23 17:14:19.693135279+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["42.99.149.47:5231","146.122.164.252:36824","16.15.205.75:58574","82.136.149.34:28707"]','2024-01-15 09:34:54.847632697+01:00','2025-06-23 17:14:19.693240007+02:00',NULL,'100.64.0.23','fd7a:115c:a1e0::17',NULL);
INSERT INTO nodes VALUES(29,'mkey:4a6e46330ccd4b3026337cdef37485c27592babda329107565c2a19d97253dcc','nodekey:17de47da1955a8a034788ae671c34fb10083568bf9e2f7494276cb2636065246','discokey:449f5f35a3507974cf03e3ac5c055d890de5122f57a7c2d84a0d3b324998607e','desktop-17','node029',7,'cli',NULL,NULL,'2025-06-27 14:00:54.026931428+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c2f1:82ab:922a:9b9d:f53d:a0b3:bccd:f6af]:299","[d28b:7b33:1f88:7583:7ed7:a923:4c90:9ee0]:62318","[68e3:a070:f02c:708c:a057:b579:aee9:4d25]:11747","[7224:b76a:cd04:e6d2:67fd:fec0:2f14:1837]:29002"]','2024-01-15 15:18:12.2871978+01:00','2025-06-27 14:00:54.02708773+02:00',NULL,'100.64.0.24','fd7a:115c:a1e0::18',NULL);
INSERT INTO nodes VALUES(30,'mkey:6472928030d718e6e2802fb3bceba7c14b4716d994be1b3562a1d03104fd37a9','nodekey:78bd59aba83429486e0ed2d50873211974650b2e2ad8f79dbc07c5d13d00c5a5','discokey:86ead449e1be5a300287e690fb9522ba4da3e5bdeb593d6261e4117708fe3ade','lt-82','node030',7,'cli','null',NULL,'2024-02-05 12:14:40.065688294+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[fd0d:f112:f642:c343:ac14:8ede:dc04:e2d9]:58412","[8a1a:5c17:bb81:bb69:c7db:3513:f14c:ca2d]:52077","123.235.220.59:59925","155.210.184.45:60093","[963:536a:33e9:99fb:c204:d59c:29a8:ac18]:39005"]','2024-01-15 15:21:43.217136004+01:00','2024-09-18 16:15:14.041757308+02:00',NULL,'100.64.0.25','fd7a:115c:a1e0::19',NULL);
INSERT INTO nodes VALUES(31,'mkey:212b1ffd20a790e4f3fccc87a3f2d76a0c6149d4f2472f4eba76b40671f500af','nodekey:7b88563747cd8ad8526dd795e1dc858d84b4a9fabf3b009ad2ec5f6e7cecdfd6','discokey:660bda5c0e80a6bb18ed7d69dc80de790fc3f4a64bf5a6bebb69ce73ff3d6755','email-99','node031',7,'cli','null',NULL,'2024-02-22 08:35:27.098819037+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[7016:b48d:8bcf:4ccd:8679:8c47:1c66:cd1e]:41980","22.231.20.85:41616","129.130.98.189:47833","[99c0:d769:2f38:10e9:c01a:e3d:898e:afc]:17505"]','2024-01-29 16:05:35.338524634+01:00','2024-09-18 16:15:14.042191514+02:00',NULL,'100.64.0.26','fd7a:115c:a1e0::1a',NULL);
INSERT INTO nodes VALUES(32,'mkey:c4853fdd63bed5a98baaf74df437eff743f8a968fda613fdf1f2a111e7c1b100','nodekey:9fc3f32ce92ab7f8ab987f16258b11265037a47cd9a1a68ac0e07bd3c279c183','discokey:e52f22aa8e170b6a031e682b5ed6e5f790f2d6ae1eecb752de1b362a1cce7bd4','web-89','node032',7,'cli','null',NULL,'2024-04-09 13:59:43.37062537+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["133.177.207.78:47765","[d1b1:653:cd17:f39c:8a89:85d0:c7aa:b53]:5279"]','2024-01-30 10:41:58.31917869+01:00','2024-09-18 16:15:14.042506082+02:00',NULL,'100.64.0.27','fd7a:115c:a1e0::1b',NULL);
INSERT INTO nodes VALUES(33,'mkey:805d05918a94047740c914235c3c614042b05d18458f331ba0a46ee22d2187e6','nodekey:ebc009009bc015bc45f6499b04b7af9ff2ceff22c0f9676749b10c92f422a8ad','discokey:b6d83e1f6f0e86c3808cffb227cb6649bffcf5d4ba1596f6fd58f41b8b727133','db-70','node033',13,'cli',NULL,NULL,'2025-06-27 21:25:43.528971537+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a1ed:3568:9b48:6735:e553:a273:ea02:7271]:46613","90.225.231.207:5490","176.14.56.16:22127","[6224:9e4:5921:7fda:2437:15c6:a1b1:adf4]:15557"]','2024-02-03 16:33:26.706408143+01:00','2025-06-27 21:25:43.529881502+02:00',NULL,'100.64.0.28','fd7a:115c:a1e0::1c',NULL);
INSERT INTO nodes VALUES(34,'mkey:a404e578d3edd3e3d879e9f1946c859b5982c59f5e528bf6b987bd55de00b25b','nodekey:ad3013f116c370866fc9134b66999bb05e2dc10a8e2944230c3d9893c0a94c67','discokey:4fc6b881a4f170158e94336444d2cf0dea6a387b06dfc5fde08ed15d0f391c90','lt-08','node034',13,'cli',NULL,NULL,'2025-06-28 11:18:54.787303405+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["172.87.199.175:12624","71.151.27.31:51063","[f0d6:21dc:48f5:63f4:daff:a3c4:7d60:51ea]:17286"]','2024-02-03 16:42:32.683785672+01:00','2025-06-28 11:18:54.78775904+02:00',NULL,'100.64.0.29','fd7a:115c:a1e0::1d',NULL);
INSERT INTO nodes VALUES(35,'mkey:06f7b17a75e55b445cc41ad693565fd93da6f4d690a305f8e207d69b028bf859','nodekey:0f4a7ade77ba260d9b318ac18c6c1f2f0606af7edc29128a33984558b6a047b1','discokey:e3cc18eacc630c61f2a2ad6a4152ee2af4b93f0ff767122676a6e02f58f5f01e','lt-11','node035',5,'cli',NULL,NULL,'2025-06-28 09:59:51.80761163+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["94.107.22.1:45906","68.64.112.147:37449","175.25.134.28:16830"]','2024-02-03 16:51:52.010016072+01:00','2025-06-28 09:59:51.808121221+02:00',NULL,'100.64.0.30','fd7a:115c:a1e0::1e',NULL);
INSERT INTO nodes VALUES(36,'mkey:37a68d32b77a701b08f9aab0e407525cad61a79aae25512a47e834e67070caa4','nodekey:ac40d87508d60cd5ffa0c21bc569b85685667e418434e5d83cee138ef1552ac0','discokey:dc90acbf7b156f6a5dd8e2f0a36638a99994148f16138230269ced79ff89fb8b','db-19','node036',13,'cli','null',NULL,'2025-01-19 14:01:48.956567669+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["68.209.122.217:6048","[edcb:62c0:3e8f:3a8c:93dd:1672:b477:ce1a]:18240","[bbb7:5b4d:218d:55ff:ac9b:1fb6:c933:9a55]:63943","18.156.132.228:63356","122.50.5.12:7674","[a641:3f06:63bf:b716:4658:1e5b:ac6f:e14]:13490","197.206.147.31:58506"]','2024-02-09 12:34:57.879970954+01:00','2025-01-19 14:01:48.956830267+01:00',NULL,'100.64.0.31','fd7a:115c:a1e0::1f',NULL);
INSERT INTO nodes VALUES(37,'mkey:2a302116eb66f119bc13369abf20be603cc433e83e4607480a6731e38ba9e8bf','nodekey:9f97afa1f234c491e12dbf3e613e4f4525d64aaa90cd40dba2919e8d315cbd27','discokey:7470aa5ff096df380fc115e26326342355093e00a5b1c7d9e6a6e91228bd2e19','srv-81','node037',5,'cli',NULL,NULL,'2025-06-28 12:21:12.129795624+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[5071:881b:75ae:d129:45ec:cfba:1a25:63df]:48282","[f94b:a947:7d11:b9f2:7758:640d:478a:1da8]:26194","[6b8d:8778:d67a:4cb3:1c6:1986:f223:15a9]:12844","[e1b5:d8f1:23f0:93f:bf72:7b6a:5925:353c]:52615","[3ec9:71d2:c2a5:cc2f:e2e8:5740:7b01:4a9]:29794","[4b64:fce2:293e:a24a:9995:b0fa:ff27:5401]:58695","[5eb0:a5cb:e9da:1552:e478:f921:c3d6:ff40]:57647","[8c40:dd59:c31d:dd18:321:58a:11fa:d85a]:43064","168.4.78.117:48474","90.45.218.0:29326"]','2024-02-27 12:14:40.452601042+01:00','2025-06-28 12:21:12.130426228+02:00',NULL,'100.64.0.32','fd7a:115c:a1e0::20',NULL);
INSERT INTO nodes VALUES(38,'mkey:0cb7a61e162c150a2397b17feaa98b86ecd8eb2cb899f406f9cffc5f94bed186','nodekey:aaf8f2337e0809d347caec27b07a8a5ffbb41110569b50a386ed852b61a4b1d1','discokey:b8c6a5277eeb27573ce8647557540773904cd4559a9b2fc38c8ed0fe0c9d3b01','srv-58','node038',6,'cli',NULL,NULL,'2025-06-28 12:22:38.364224551+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["189.185.249.112:45061","117.137.197.148:33075","165.145.180.67:23334"]','2024-05-22 08:08:16.045350656+02:00','2025-06-28 12:22:38.364913686+02:00',NULL,'100.64.0.33','fd7a:115c:a1e0::21',NULL);
INSERT INTO nodes VALUES(42,'mkey:08032558a6f70b2a3125f92860e4e3261cb87d9fa5507ad75b00d14d506e42ed','nodekey:d7a05dda88f80df694090cfdd8c5e0fccead6014378741fdc8166bce304eac7b','discokey:adecd0e23ec16e2ad50c7df1d855cc7d2ac016adf103f4d9373ab4d9da6d38dc','lt-88','node042',14,'cli',NULL,NULL,'2025-06-06 20:55:32.708129231+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[a393:f17f:6728:82e4:c1e7:2367:82d0:daaf]:18560","[d192:9897:4cd7:bfb5:de36:fc03:8cf4:c60d]:25096","212.199.67.213:11150"]','2024-07-03 11:12:29.418355657+02:00','2025-06-06 20:55:32.710128529+02:00',NULL,'100.64.0.37','fd7a:115c:a1e0::25',NULL);
INSERT INTO nodes VALUES(43,'mkey:33e764ae40265089c5e7dbfc8571aa23bb390fc7e1e8bd2f3e0cd6891c308214','nodekey:c444c9ff652ba29181a5f7fdf991f91f704e6698237ee18b0649c81879ec932f','discokey:2e1db3a1eea266673acf7826aa44b5aa6fdd23c6ba41330562b37c5a523ba358','laptop-81','node043',14,'cli',NULL,NULL,'2025-06-06 20:55:32.888930994+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["190.179.215.222:61930","45.131.187.230:22916","[510f:af99:ed4d:f53a:fc21:8640:9ad9:4930]:16050","[5ea4:3410:eaa2:9da:b8d:b61a:2d9d:edaa]:3526","209.107.206.184:46974"]','2024-07-03 14:48:50.263910778+02:00','2025-06-06 20:55:32.892202297+02:00',NULL,'100.64.0.34','fd7a:115c:a1e0::22',NULL);
INSERT INTO nodes VALUES(44,'mkey:1099debb0ba187ef1f43f001c75abc118eaf017bf3bd6b48ca333fb046b98de9','nodekey:d49ef9ad4a7ecbdabcd24cae92d9ac32fbb765467cbc20abe61b4bda6ef15f1f','discokey:9f2faf39514eccb7f3d7d66ebcaf804474f75284d8b1aedbf97aee6ccdf47ed5','laptop-84','node044',14,'cli',NULL,NULL,'2025-06-06 20:55:32.852055717+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[183d:f2d6:b80:36c5:318e:64e9:7f4a:b389]:12440","169.173.198.12:15274","[e5df:1889:6ac5:7d21:4dfd:614b:7eb9:d93c]:792","119.123.40.237:58615","[415:97d8:4ecb:2a7d:14ae:64f3:7a01:471f]:15771"]','2024-07-03 15:23:48.066044194+02:00','2025-06-06 20:55:32.876004334+02:00',NULL,'100.64.0.35','fd7a:115c:a1e0::23',NULL);
INSERT INTO nodes VALUES(45,'mkey:29eedea8083105a21470a51112b2486ae4c79221e2b6b17e4c3c84f965013513','nodekey:b3249157ebc705f134a366e28beb2d7646a40bc4171bb6d6fece1e750c85379b','discokey:64cb6eaee39eca7e3ad7f1225c216bf2826a8a951b91a631cfacf3b5ec99c2db','web-31','node045',14,'cli',NULL,NULL,'2025-06-06 20:55:32.853701621+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["14.153.231.75:19825","[acd8:3779:7b6c:3a71:c15a:e323:a721:c9a7]:63377","[6816:3377:edb0:3f8e:a65b:bd60:461b:ceb]:24642","147.3.7.139:46940","[7526:4960:73a9:911a:1fbf:92bf:1219:a6bf]:25440"]','2024-07-03 15:54:01.706018896+02:00','2025-06-06 20:55:32.862645337+02:00',NULL,'100.64.0.36','fd7a:115c:a1e0::24',NULL);
INSERT INTO nodes VALUES(46,'mkey:8c948629fd6a1b66977db7f1c6f11c30f1ef99da371f2f88f6bb77d79a3fd157','nodekey:af7e300b7119ffd77488c76a756660fec6ce7b4036c9e6c5159e1dca503dbb3a','discokey:a266b60014f0798c0e31f9e11ad5eb09082bd1178e3a2a0d5791801c1f2fc415','srv-47','node046',14,'cli',NULL,NULL,'2025-06-06 20:55:32.644737833+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["57.87.213.13:62573","160.29.16.50:26152","217.233.117.213:34230"]','2024-07-03 19:38:07.783745318+02:00','2025-06-06 20:55:32.659793776+02:00',NULL,'100.64.0.38','fd7a:115c:a1e0::26',NULL);
INSERT INTO nodes VALUES(47,'mkey:bfd4f59c7df7a9f7c3ed7736b35aff1895318a2ba2de7dbeb8c5911a9fdab6c2','nodekey:18f4f5a2905ba4ddd20ab6fc31945f78cc312cf8b453a544cc6c5d7456a1f8e0','discokey:dc5f0a3318228e929379c1b82984b0b955988131f3cf1522f547680420acf39d','web-50','node047',14,'cli',NULL,NULL,'2025-06-06 20:55:32.624765906+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["55.20.245.10:37304","98.38.29.194:12660"]','2024-07-04 10:38:08.344092869+02:00','2025-06-06 20:55:32.642819932+02:00',NULL,'100.64.0.39','fd7a:115c:a1e0::27',NULL);
INSERT INTO nodes VALUES(48,'mkey:5bbb77092f21b4835b0ae1af3871fc48445819c9b6e5ff9c46ad4a623b662ae8','nodekey:191c7cc089ee160c07b63e2b6b5ef0701d76d914009420baddad9bfce13e3f2d','discokey:712cadffd23f106abeea82ae70bbae8e06c2a58f3db617afd0d149b3012c64fb','web-61','node048',15,'cli','null',NULL,'2024-10-20 13:53:33.831192385+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["186.118.23.242:32373","[5bd8:a5a8:1b3:5e41:3c4d:5fc:4c0:c6cc]:24847","193.95.63.195:40587","166.176.60.55:23674","[33c0:859c:4a78:8bdb:359e:31e4:1e71:7e39]:50383","[3aab:52a2:b9d3:1816:5627:336:6c60:57d7]:13486"]','2024-07-26 08:09:56.608302315+02:00','2024-10-20 13:53:33.831387627+02:00',NULL,'100.64.0.40','fd7a:115c:a1e0::28',NULL);
INSERT INTO nodes VALUES(49,'mkey:0aeb63f409c65f5e3fb88049d610c3b58476d4d9ffa41502e928b526888f937b','nodekey:39c2ec4b5e9e4ffabfbf2b0e77e12d71b281e75945e80ab2318b600cb7a2794a','discokey:36e41b77ca844d02104807b6ad0eabe3b14252fe06b0e4c3ee6d0ecb51abbbeb','lt-93','node049',16,'cli','null',NULL,'2024-09-19 09:07:18.28136023+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[4451:be15:8bc9:696f:fced:a453:f30:99db]:40973","[ff9c:d2f4:d4ae:92b3:1da6:15b:cb40:b9a7]:10893","[76ef:e160:820:d8ed:de32:25f4:7874:de94]:23150"]','2024-08-05 17:32:41.937626584+02:00','2024-09-19 09:07:18.281618912+02:00',NULL,'100.64.0.41','fd7a:115c:a1e0::29',NULL);
INSERT INTO nodes VALUES(50,'mkey:f368047f0ade97d2e85be32da245e474ebdceb640b35947a5403ea4ec17dba20','nodekey:fb33e7e55c17bc7ddfc809cf37470a044cbdae049633f8e2f77009205685a318','discokey:17b46a4dd1b090347f47ff0f980521faf4cab279f97133bc03cbe0f1750187e3','desktop-00','node050',10,'cli','null',NULL,'2024-08-07 10:10:06.595550455+00:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["220.80.110.172:44100","[2523:fe65:400:15c0:a5a1:b955:1454:70c7]:54632","[a8a7:bda:7d93:b992:48e5:f2c1:91e2:54c6]:19368","150.170.146.70:3311","139.117.239.209:33788","[2eac:ffa0:99fd:d109:c120:a35d:ed48:eea3]:51544","[7644:c348:2969:b90:e84f:94d4:b629:f266]:49336","169.247.3.239:36225"]','2024-08-07 11:50:54.144157179+02:00','2024-09-18 16:15:14.050033969+02:00',NULL,'100.64.0.42','fd7a:115c:a1e0::2a',NULL);
INSERT INTO nodes VALUES(51,'mkey:735ea22d4d96ae83e77aa73b97a50a1b34636cd05384bad6a9b9256ca20d7290','nodekey:7fa08d819358ea2114540aca2eb712f6a85f7610e888e9e34d1e40e2900114cc','discokey:330eb26ff5d9403bd755091b57a42aedb2c3b46583576ca6d979f9a703234cd2','web-65','node051',14,'cli',NULL,NULL,'2025-06-06 20:55:30.776282094+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[c5c6:6d5f:96bc:5d51:16c2:9fb8:d390:bea8]:54983","[2300:cb9f:25a7:8450:3dd7:1ed5:6362:63d0]:47837"]','2024-08-07 14:19:31.156780417+02:00','2025-06-06 20:55:30.792088043+02:00',NULL,'100.64.0.43','fd7a:115c:a1e0::2b',NULL);
INSERT INTO nodes VALUES(52,'mkey:a1c649017ddbb4dcd4554acf5286329de306c9053b6ba103684683bc4b825b9c','nodekey:2676428ddde9161b1de90dc62ac99f436c3ac780e43719bed6313c680743ac06','discokey:f16bd3d12b57ee652bf20e358a184111d2be864bee16195053b68d21b5357384','email-01','node052',17,'cli','null',NULL,'2024-12-25 17:27:58.515851096+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[1c82:2ff1:f85f:9c4c:9bef:6197:b9b0:5e38]:29991","[2fd4:63f:f9f:ec1d:1ad9:621a:4155:8a19]:46781","[32:2239:56ed:558:32d5:7b03:dcdb:e5d0]:53865"]','2024-09-22 15:48:41.385301399+02:00','2024-12-25 17:27:58.517153789+01:00',NULL,'100.64.0.45','fd7a:115c:a1e0::2d',NULL);
INSERT INTO nodes VALUES(53,'mkey:3b2b622721b0c64d215283349a2df3b86a2a4e107b92e6ca4450204061ce53d4','nodekey:0e64072dafa5f9e49266b41fc4b21ff7d287be8f4e5f2b6c395487d632f1cf3f','discokey:2f77bb8cbeb426bcded5ad9fc6da44b0b76b8d6759f10a8db28e634290760ee7','srv-65','node053',17,'cli',NULL,NULL,'2025-06-28 12:20:35.189820653+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[977f:5596:9908:14e0:8983:810e:9e9f:93d]:3616","[911d:ef36:743c:8085:8a4c:a5c8:9f35:27fc]:23538"]','2024-10-28 10:04:50.084492941+01:00','2025-06-28 12:20:35.190401013+02:00',NULL,'100.64.0.44','fd7a:115c:a1e0::2c',NULL);
INSERT INTO nodes VALUES(54,'mkey:a996b2df08089ba5a36bf00f4f0a337aa876a58f3214114862f76cf570c317f1','nodekey:241d83b165073dfebc00ef12480032b008e7d305957fe3e7b14938125b7fd788','discokey:1c36d23ccdc5d359c1f4b0626c27e0df4be0b8165553005771b638effc36249a','lt-94','node054',14,'cli',NULL,NULL,'2025-06-06 20:55:32.691473004+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["69.219.0.37:43476","[6084:ee60:1697:864e:4a61:cf6e:e9b6:4c05]:63961"]','2024-12-09 17:10:55.363593066+01:00','2025-06-06 20:55:32.700659203+02:00',NULL,'100.64.0.46','fd7a:115c:a1e0::2e',NULL);
INSERT INTO nodes VALUES(55,'mkey:ad8d2836fc3e281ea45c14de854da61abc9ab333e94ebe3de2435e9c4c7f5ea0','nodekey:30b87abf366b736d7e782d74536382f1853f9de785d2bd532b63c5efb3d7c6cc','discokey:2ecc9071b240d067246a96ba329af5d3385cf430708f93a8aaa553e49ae225ac','web-20','node055',18,'cli',NULL,NULL,'2025-06-23 17:13:34.971389477+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["172.87.149.191:59171","[1fae:4025:aab6:7bd4:33bb:9306:1e8f:991b]:50694"]','2024-12-10 13:56:39.287449662+01:00','2025-06-23 17:16:24.577468282+02:00',NULL,'100.64.0.47','fd7a:115c:a1e0::2f',NULL);
INSERT INTO nodes VALUES(56,'mkey:7ad9c5af6111cc3286256127e6b6a939f1fb87e08c9018bd7bd8671c4b9cefc2','nodekey:84fec35781c2032d05c7e8524bada9f7242165e9ab5df5d66f993266cc6f090d','discokey:ad9158862b9c58848c37b519543415166938b6be3dfe3a8463842ebbd09eb00e','srv-14','node056',19,'cli',NULL,NULL,'2025-06-28 12:22:44.430647515+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[e669:9684:b8bf:9a64:8ec7:bec:6369:4412]:16090","23.0.29.75:24889"]','2024-12-17 14:58:39.429211911+01:00','2025-06-28 12:22:44.431119935+02:00',NULL,'100.64.0.48','fd7a:115c:a1e0::30',NULL);
INSERT INTO nodes VALUES(57,'mkey:ae8c967065558f9f03a95979d2181b3aa2b3537c25a894046a65554beaf553e7','nodekey:bc9cbaeb5cd70e708b5a23565ffb1fb6e1c18f35b1861083196209dcc1e0e20c','discokey:f8647d1a8ab876931f49a8abf785d429f7f21bd1fe6317528bfbf78e38d7aafe','db-73','node057',20,'cli',NULL,NULL,'2025-06-28 12:22:11.086950088+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[caa3:7372:5199:2416:357:7b48:3127:85f1]:21026","[e2a5:db96:e7e3:6335:8bdc:90b4:40ff:920d]:28128","163.106.192.242:30271","[7d2a:9d5:1fbb:54a7:fe7a:bc40:5ea2:ca20]:3534","[f630:8bb5:a4ff:95b1:6d95:decb:a5d2:373b]:42456","[6cc8:4fca:c46e:ed25:e9ef:43e:f0ea:121a]:60965"]','2024-12-17 15:17:14.26936913+01:00','2025-06-28 12:22:11.087909892+02:00',NULL,'100.64.0.49','fd7a:115c:a1e0::31',NULL);
INSERT INTO nodes VALUES(58,'mkey:5bb86c2f730c0b247b01634f73a4f67a19bf271de3ee39cf13f879db671da5b1','nodekey:64f016a04093cc91f7d2ca3639a07a17ae8f95f246a7ad759141d598136bd060','discokey:066b4845ec135e6251d6ef6119c832b46e2bc310332d3ea836c5f39896538b38','lt-49','node058',12,'cli',NULL,NULL,'2025-01-25 18:41:03.881898904+01:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["128.102.246.147:15968","[d0d3:beb7:361b:71d1:af88:4105:6b5f:343e]:14598","155.200.222.111:64410"]','2025-01-17 10:17:23.455895657+01:00','2025-01-25 18:41:03.882180987+01:00',NULL,'100.64.0.50','fd7a:115c:a1e0::32',NULL);
INSERT INTO nodes VALUES(59,'mkey:86289561abe2eff47dd9c23c0bd1e076c0ff7b4306569d6c2ab63aa2ae5096a1','nodekey:1ac8d1434fe581284ae297cc9063685fc2afd854c45ed3cf0809c95b6ecbc037','discokey:44567ca0878c3505bb078f76a993fe3b381f17325a3c0f3df1125bba5eca1a92','desktop-26','node059',21,'cli',NULL,NULL,'2025-06-06 20:55:38.816110199+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[9875:c11c:289c:3b14:dc40:d7af:6:8372]:51751","125.170.153.154:21718","68.3.248.154:42390","[f621:b605:bd04:a964:160c:314a:141a:2e8d]:58563"]','2025-01-29 11:59:27.291048957+01:00','2025-06-06 20:55:38.890138267+02:00',NULL,'100.64.0.54','fd7a:115c:a1e0::36',NULL);
INSERT INTO nodes VALUES(60,'mkey:06bd440cb68a2856dcab4ae09ba4c4e7969b78a99a1d06bbacebc9d1fba037b7','nodekey:c0a2b88f5f4b9aee6a50df28b6ff5e5c495053c26d969100ef23f13a51349bec','discokey:4023ff7bfd754262fe36745731a9d1175cc0b49d7acac56123cfbf0c633fa0c6','db-32','node060',21,'cli',NULL,NULL,'2025-06-06 20:55:32.690648751+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["50.133.88.187:24107","[ed61:9d51:b21f:7096:32fa:e473:f6d4:9f69]:17106","110.235.245.179:61572","[57a6:fde1:814:36cd:f8de:668c:f5fb:4f60]:39714"]','2025-01-29 12:01:57.48748166+01:00','2025-06-06 20:55:32.699638826+02:00',NULL,'100.64.0.55','fd7a:115c:a1e0::37',NULL);
INSERT INTO nodes VALUES(61,'mkey:6841756817cebda15bcacc15dc8e13134d3189a709a4b01cfe7f140a0ff928f4','nodekey:c9ad34579c8f83c989958c188d366b58bddfcfc8623f0ed478e86ae9ad9001c6','discokey:4de34c0ddff8819b97b39c2f31a2568db15e7c0ac6c1d75879b6c5247a5dd9a5','desktop-04','node061',21,'cli',NULL,NULL,'2025-06-06 20:55:32.705457818+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[507f:3427:b2a0:12b7:abaf:dd7d:2f0b:9a7b]:26021","51.210.182.192:52299","[2e30:4d2d:4925:201f:e845:2a12:503c:9524]:34552","105.198.43.87:48215"]','2025-01-29 12:03:01.464646336+01:00','2025-06-06 20:55:32.706102582+02:00',NULL,'100.64.0.56','fd7a:115c:a1e0::38',NULL);
INSERT INTO nodes VALUES(62,'mkey:f5a8d012556138cec4b6a6dbd5f36669d16e025962edf3367789b24a01cd54ab','nodekey:4ed3e288b9820dab0f68f070d6b36cb71e969d35804fdca8692c66b68538e8f0','discokey:0d6aa1b3942712032ff7936507a5eb7df01e40d068092e717d1469c3e683e8d7','web-15','node062',21,'cli',NULL,NULL,'2025-06-27 21:55:15.517052697+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["48.141.84.207:348","[ac:5c65:da8d:d68c:eb0d:3692:d441:5363]:63612"]','2025-01-29 19:23:14.092804852+01:00','2025-06-27 21:55:15.518034318+02:00',NULL,'100.64.0.57','fd7a:115c:a1e0::39','[]');
INSERT INTO nodes VALUES(63,'mkey:4be52a5e6b73a19d10d6cb424f776651633802f78caff3e2f6a45cf23eb529ae','nodekey:d4881065396d3d9b479137f2fa50504da55869d3b03120f991dcf3a9d7c733ab','discokey:77289acf81d715492dcbf00468f6297621efc9abb9d7934426babfde0c41206e','lt-52','node063',21,'cli',NULL,NULL,'2025-06-28 12:17:33.005602929+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[912a:9b6c:5845:f8d4:f476:491f:cdef:8b7d]:21677","22.203.32.217:28664","112.239.138.73:43954"]','2025-01-29 19:41:40.535299057+01:00','2025-06-28 12:17:33.174275791+02:00',NULL,'100.64.0.58','fd7a:115c:a1e0::3a',NULL);
INSERT INTO nodes VALUES(64,'mkey:4cbd491b0977f3a8cc92ef9f20a7726b3984f3c0699429ae46a0bceec5febee4','nodekey:66a7e77700fb0f4bae5b282413bdb5ff7c375549dd85c4300c73ff3d8029b4a4','discokey:2e9034fc43993eaa0cf2bc21118d378bb02afb3d197a33cf9f0dd201d176b23c','web-06','node064',21,'cli',NULL,NULL,'2025-06-28 12:00:16.139095833+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["81.51.60.60:63220","12.64.198.119:51541","[5e99:3950:5dc4:45be:bab7:e7ba:2476:14e8]:43360"]','2025-01-30 18:18:57.519126133+01:00','2025-06-28 12:00:16.139426752+02:00',NULL,'100.64.0.59','fd7a:115c:a1e0::3b',NULL);
INSERT INTO nodes VALUES(65,'mkey:70cc01dc48021a01c44ab1a4bed313bb8270640ef7317fd983019c4b5e593cf3','nodekey:bfff30bca701176ec3b45b2991810cc437e3995207d924c896c4250e0efdb782','discokey:91eb7d9fa7688e3ed641adfae83be298c1ab261fd00dc2b4ad9cb4c269b623fa','laptop-27','node065',21,'cli',NULL,NULL,'2025-06-28 12:20:11.981310509+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["105.95.65.117:11546","[68bb:e8d1:72d8:8b02:608b:2284:c9b3:184d]:20876","[5c17:4014:ea6a:5528:b1a:61b7:5cda:5c5e]:21597"]','2025-01-30 18:19:40.354692307+01:00','2025-06-28 12:20:11.982409032+02:00',NULL,'100.64.0.60','fd7a:115c:a1e0::3c',NULL);
INSERT INTO nodes VALUES(66,'mkey:ac14ce6b1ecd1a0d79bbf60d279f19d09baf0ebd409f099a401816516953eb30','nodekey:a711e6a5750ec7cceac6a771396b000766d9af8a34327bf5efec3216316e8afc','discokey:0b370e73e9970987dad3fd00317f51c68e4273fbc11b754ef7e84d4d6880002a','srv-33','node066',21,'cli',NULL,NULL,'2025-06-28 11:59:14.080155658+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["145.91.193.5:37126","[2fb6:ea0a:3639:a1cd:9075:a258:6a79:4f5c]:13944","[2384:3000:4d47:a9e7:54ef:99:52c0:e920]:39358","130.195.116.24:53838"]','2025-01-31 12:05:28.65297301+01:00','2025-06-28 11:59:14.080969357+02:00',NULL,'100.64.0.61','fd7a:115c:a1e0::3d',NULL);
INSERT INTO nodes VALUES(67,'mkey:fe494a29de4149025e3c41744cabfaaa2ae9a95795bdb6425e3beee27048e0f6','nodekey:2b078ccb547dc8b01f19749735f5fc43e65e4d468357a08a880fa54dc0a1e00d','discokey:cb991d6c0a14b0213e6f807e9c37a837b181c889a1e2d25e10d65d4a7e8b2b05','laptop-33','node067',21,'cli',NULL,NULL,'2025-06-28 12:16:35.347217701+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["54.154.28.86:64790","197.205.147.181:38523","[5e11:9ab9:6805:dec0:99aa:65e6:d1fe:6e58]:45247","[34f8:19dc:cc84:1e6a:d280:ac0e:2dd9:6fe5]:39241"]','2025-01-31 12:06:30.121464114+01:00','2025-06-28 12:16:35.34788428+02:00',NULL,'100.64.0.62','fd7a:115c:a1e0::3e',NULL);
INSERT INTO nodes VALUES(68,'mkey:de86679045cb8624f1a83852679a58cffd9066814aa8994f4ac0a9213b83175f','nodekey:b62e575e38a00afe79418224f7b954210702ac0a6d450eb8dbf7b5720b1eb5a5','discokey:6492f53782aab503155db83aa2d3a9e7698382da589b8c078d7850373332734b','desktop-65','node068',22,'cli',NULL,NULL,'2025-06-28 12:23:23.107075566+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[b84:67b1:28c5:14f:aab8:916c:582c:6917]:24462","51.182.13.145:25726"]','2025-02-03 14:16:55.56431345+01:00','2025-06-28 12:23:23.107666016+02:00',NULL,'100.64.0.51','fd7a:115c:a1e0::33',NULL);
INSERT INTO nodes VALUES(69,'mkey:eb72ad359958c98e28f93485b720b6edef80d1bc33c4f99d772fc17c766039e9','nodekey:9122bd587ae90984e3231e0f48e15aa8abcfbc1b3324becd1f3622bbbe534da1','discokey:7610d45f8d2d3d4d7774c43288a6d50cd798a832732613647caa15e96621a3e3','laptop-93','node069',22,'cli',NULL,NULL,'2025-05-22 19:56:30.861469961+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[3022:fc47:6534:7fe3:9d1e:8d49:75b:984b]:10998","60.241.100.13:15037"]','2025-02-03 15:23:16.312084161+01:00','2025-05-22 19:56:30.892062591+02:00',NULL,'100.64.0.52','fd7a:115c:a1e0::34',NULL);
INSERT INTO nodes VALUES(70,'mkey:8c5837a59e69539df974f244ee29ea29968a617072d4fdc6dfef564eea6a4061','nodekey:05ebbe5cdc96a19feb16211d4a62a2318e9448e15e1a3a90f0aa556fccba8142','discokey:cf7b3319a18ac04f588e2c5a95de9a24a37f5545338c3532d9703b861a43e3fc','laptop-86','node070',21,'cli',NULL,NULL,'2025-06-28 11:26:01.538093141+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[abf1:9c06:f1de:eef4:f14a:d431:8f2:4995]:52788","[8ac8:a469:4cc:90b5:c84b:f4f:5cb:49e1]:35646","[d152:3a18:3826:ee28:a323:74d6:7140:ca5]:40749","99.13.253.35:45887"]','2025-02-03 18:09:35.161109801+01:00','2025-06-28 11:26:01.539046342+02:00',NULL,'100.64.0.53','fd7a:115c:a1e0::35',NULL);
INSERT INTO nodes VALUES(71,'mkey:9562166c366f1968a5f82aca83bd8152d893541eed4d8682da0a540825cd44e9','nodekey:93ef8b713afeffc4324b0f9a99e185be61dbff43d6e5769efac6d82481b425c9','discokey:9aa3fe84188c317d17132a26604380ec4aaf7aed94b4b759bb6b643dbd53f8d9','desktop-61','node071',21,'cli',NULL,NULL,'2025-06-27 07:45:53.640560103+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["56.191.25.57:54747","74.194.16.233:59572"]','2025-02-04 12:03:50.32663805+01:00','2025-06-27 07:45:53.64117544+02:00',NULL,'100.64.0.63','fd7a:115c:a1e0::3f',NULL);
INSERT INTO nodes VALUES(72,'mkey:50329891edd2948b53a0905245386567c98b46bc0d566e39e1763768d51cd638','nodekey:e4ebfcbd1e1d653bda175a62b765c6a646b7844b3d6bd49a9955f96a9b284c6a','discokey:f59cb75bac53aef739bbd5be676808891ebb55550aa0560396dc0532658ed893','web-53','node072',21,'cli',NULL,NULL,'2025-06-06 20:55:32.885806537+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["200.133.152.206:14119","28.101.69.72:35202"]','2025-02-04 12:07:36.231437299+01:00','2025-06-06 20:55:32.902608355+02:00',NULL,'100.64.0.64','fd7a:115c:a1e0::40',NULL);
INSERT INTO nodes VALUES(73,'mkey:fc9d5a1c4658644beeb3130cf62b19042698652298ef36899d41f588bec371ab','nodekey:d44ef585e416773d29e627cf9a6e590af9b676d23a0a816865d05d775517ab4b','discokey:0c87d487f7a4f4ec5e045ff0c83c1b6c54453f7afe0e5f13c7ce90746e18da49','lt-48','node073',21,'cli',NULL,NULL,'2025-06-06 20:55:32.909812195+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["126.19.171.233:19526","[91e1:a8d7:5c43:b695:4f5:b147:b5f7:9f75]:62218"]','2025-02-04 12:10:26.50545127+01:00','2025-06-06 20:55:32.911837947+02:00',NULL,'100.64.0.65','fd7a:115c:a1e0::41',NULL);
INSERT INTO nodes VALUES(74,'mkey:a46b92cea88a9bac37dcb612a4a50dee75684f736c8c7f2aab812fa5fb9d463f','nodekey:1bbfdddf7b2a929a3da1e69236aa8b8fbd4b25d1839e57aaecf2ab910592bc78','discokey:c2188df6632aded7862de4b5d07c3993b3e908c59ce38f9d481f4840d85448c7','srv-06','node074',21,'cli',NULL,NULL,'2025-06-27 12:16:51.183868148+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["[99f:9853:60cd:a4c5:e9d7:2a40:f86:742b]:782","[99cd:c956:e0f9:b633:5f8b:5c6a:50b1:571]:18474"]','2025-02-06 17:33:12.557302525+01:00','2025-06-27 12:16:51.184524169+02:00',NULL,'100.64.0.67','fd7a:115c:a1e0::43',NULL);
INSERT INTO nodes VALUES(75,'mkey:2c018031737bb172064fe31674acafe1b8b4d62d2b82db835e2c38061c5bfdbb','nodekey:575f781bb36f7c93cde4d9808e3dedef2c8999864ea1d4e5ee73fdd3d53ac217','discokey:00e3275941e7a0a73a1e5c44cea638a411c60bb2e257812e0f39152ec0c5a21b','lt-01','node075',9,'cli',NULL,NULL,'2025-06-28 12:12:54.498870123+02:00','0001-01-01 00:00:00+00:00','{"fake":"data"}','["56.80.126.49:13907","95.196.223.110:47343"]','2025-02-06 18:23:55.709687186+01:00','2025-06-28 12:12:54.499413173+02:00',NULL,'100.64.0.66','fd7a:115c:a1e0::42',NULL);
INSERT INTO nodes VALUES(76,'mkey:a5a8194cef984a1cc2081212405c10c8cc1061d3d00e6aa7e1415c854e3ded72','nodekey:ca37a131e58c14ebec3a6e179549d7c8742a31b42ed0e6e52aed138ecc176907','discokey:8a4990c19c547da50875ad00613118d5382717652b4ef9897a1d1c060c40a976','laptop-71','node076',21,'cli',NULL,NULL,'2025-06-21 21:24:09.453652526+02:00',NULL,'{"fake":"data"}','["114.141.127.86:11858","[d05b:3c4f:8402:823f:409f:87b2:4dab:4959]:58420","130.243.34.21:50806","104.255.105.25:5817"]','2025-02-14 15:29:45.220999928+01:00','2025-06-21 21:24:09.453999154+02:00',NULL,'100.64.0.13','fd7a:115c:a1e0::d',NULL);
INSERT INTO nodes VALUES(77,'mkey:51f0f5c2b892846f926abf826f5ff56a52fc4a466be7a1073f16028ef2c6aabb','nodekey:0138c27376e8289255c1d505ba8e8d0e9e8e6785198b87984763531273d0c540','discokey:5bbb476ee437efaa55c10931313e35c4c8c6e30015e7f3eb015f4736897abb12','desktop-50','node077',23,'cli',NULL,NULL,'2025-06-25 09:52:57.106038118+02:00',NULL,'{"fake":"data"}','["57.247.45.203:47518","[1709:1d2d:9e92:a2c5:f5a0:fbca:6d9:dcbb]:31824","59.75.44.185:44605","[1294:31c8:7d7a:efc5:9768:8d1:63fc:993c]:62533"]','2025-02-14 17:00:54.226657615+01:00','2025-06-25 09:52:57.123618657+02:00',NULL,'100.64.0.68','fd7a:115c:a1e0::44',NULL);
INSERT INTO nodes VALUES(78,'mkey:138104bf35231052caaaf0f55c18b5c3beb552669360dbdc4a5246a25d3ef8f5','nodekey:c4ae5fe468012696b6a85e95b23e1391f472b17ca834efe8d61578c186efb9d9','discokey:32d79e04d128c17209805e7641c0c4f3415690430afb344699f4cdaabb2ab28e','lt-38','node078',23,'cli',NULL,NULL,'2025-06-26 08:56:45.225612029+02:00',NULL,'{"fake":"data"}','["107.221.8.103:1156","[1cbd:d52d:8b7f:a698:2d0c:98f5:bbef:4d38]:43009","[6d9d:7cf0:440e:2ee6:8dc8:fdfe:3e87:f2f9]:6993","[734f:219f:40f0:ea33:47c3:ab48:b4f6:a239]:37955"]','2025-02-14 18:03:28.401774063+01:00','2025-06-26 08:56:45.232919473+02:00',NULL,'100.64.0.70','fd7a:115c:a1e0::46',NULL);
INSERT INTO nodes VALUES(79,'mkey:8dda457abd80238812f15bbc816248c5477f1c7f2a31b180e6d1917bb4cda3dd','nodekey:bee17b81a1b62eb551d672bbc6ab5c7900cc39951a3eb1be98b05e813c7a5671','discokey:aafde40e00db7577b135254c85e37e76348876996bd5b5e5b93cd9cf994cabff','email-79','node079',25,'cli',NULL,NULL,'2025-02-24 18:37:03.584752527+01:00',NULL,'{"fake":"data"}','["32.188.178.139:7110","177.149.150.247:56583","[e188:6623:d389:230b:a467:ab3b:2883:5196]:59813","[8dc1:48a1:2e5e:8c45:131e:9d7a:2d85:61ef]:1654","[dbf5:5aac:6a5a:f73c:a62e:69bc:c227:1180]:49484","200.106.54.69:19053"]','2025-02-15 12:49:11.523904469+01:00','2025-02-24 18:37:03.584913585+01:00',NULL,'100.64.0.71','fd7a:115c:a1e0::47',NULL);
INSERT INTO nodes VALUES(80,'mkey:94a77d61756e11d471ee47d55a1cb2eae0c0faacbe5b94ed8256ee68efabf715','nodekey:0b13795cf68e3a5adb091b3b97e0c2ac4884f8295245011f60c074693fe1d3f7','discokey:5ee7570d8f70a4078d7b9afe0cadc5441cb77ef9e2f849301e1082411e04c0f7','srv-48','node080',23,'cli',NULL,NULL,'2025-06-24 13:47:09.058273693+02:00',NULL,'{"fake":"data"}','["[231a:c601:4e16:b5a3:aafd:6b2a:8d59:33b6]:51062","194.8.95.111:60702","42.58.107.175:62253","[90eb:ca6c:1e10:11cc:fd29:4682:aaaa:fd20]:57634"]','2025-02-15 21:12:05.434304787+01:00','2025-06-24 13:47:09.058652899+02:00',NULL,'100.64.0.72','fd7a:115c:a1e0::48',NULL);
INSERT INTO nodes VALUES(81,'mkey:c63e8e0bd19c1d1433056fbffb0d8b66387fec012a75060189fe896296834a81','nodekey:fa2e09d0c11508bfef7f3b63cf2f0aa752a092565cc28a1a7007cfe1d44addae','discokey:37c9fd82db6d47f8dfeec0ed6d764f8b604fb06ddf8f2cdf44eea45a840b16ff','srv-28','node081',23,'cli',NULL,NULL,'2025-06-06 20:55:32.713163573+02:00',NULL,'{"fake":"data"}','["175.165.229.254:57553","107.46.106.255:64756","7.81.60.25:36846","[16f5:5847:5615:9f6f:b38a:e4eb:d340:c800]:62212"]','2025-02-17 16:05:05.921277876+01:00','2025-06-26 08:56:46.063988329+02:00',NULL,'100.64.0.73','fd7a:115c:a1e0::49',NULL);
INSERT INTO nodes VALUES(82,'mkey:9cff47309a04474303f70c020f06f8bb795bccfc71b2ebee64b5d2c5fa862f97','nodekey:538480654e054ac4e41a1249cf3a7780a48681ac2ed5c7f758fb5d1abe750389','discokey:9511b469afd6ac8c4644f6464873d440c6c4e4fc706e53d799bf7819556962e4','web-22','node082',23,'cli',NULL,NULL,'2025-06-28 11:30:16.497956346+02:00',NULL,'{"fake":"data"}','["[8c86:53d3:80d7:bd12:aa96:5eb6:7e53:dfbe]:39629","177.106.74.193:23401","153.144.178.85:48541","[a7b3:18ce:8c59:ff04:2b88:a0fb:7305:9a44]:27764"]','2025-02-28 09:21:23.143225002+01:00','2025-06-28 11:30:16.498254852+02:00',NULL,'100.64.0.69','fd7a:115c:a1e0::45',NULL);
INSERT INTO nodes VALUES(83,'mkey:619cc5464a91d8f554d47b641eb33921721d77cc277d1d4e662cb9a7e9a52b48','nodekey:8494fd062128da2a0b6cde389888fffe2e7384b5ea4f254c23392e62f7dc6962','discokey:4efe7a6440876724d36fa7380d9c73c43eb5d11a2b7c244628f878406fb166b3','db-00','node083',26,'cli',NULL,NULL,'2025-06-28 11:33:20.425827891+02:00',NULL,'{"fake":"data"}','["[f57a:5d73:f1b4:e8ff:6b9:ae85:1d9:244]:19001","3.20.49.173:50146"]','2025-03-18 09:09:50.849674955+01:00','2025-06-28 11:33:20.426570852+02:00',NULL,'100.64.0.74','fd7a:115c:a1e0::4a',NULL);
INSERT INTO nodes VALUES(84,'mkey:57b63829d09076ea08e0bacc6c66e99112804d4d05804fcd142550188928efc3','nodekey:f4506c8002304d533a91c84d4b8b450f0ead78a853dd1d962421d09f7fe323b5','discokey:e8b549a18c4ad009efe91b011ec3992d86cadb5fdc5838668835035d9442add7','srv-03','node084',23,'cli',NULL,NULL,'2025-06-06 20:55:32.855833618+02:00',NULL,'{"fake":"data"}','["195.54.83.239:15076","[3238:dbe9:f89d:91e1:6338:993d:3e76:8561]:32795","[b501:f57f:99da:e5f1:65fa:1d84:7d10:7d66]:24427","186.27.91.14:37325"]','2025-03-25 10:04:37.147174393+01:00','2025-06-06 20:55:32.866553475+02:00',NULL,'100.64.0.75','fd7a:115c:a1e0::4b',NULL);
INSERT INTO nodes VALUES(85,'mkey:569dd1b12fb2b9920f0366c57bdbf359f0e0239e6ef62cf7a1f29554f3e3ffe5','nodekey:94d32c5d5da99b19bd320ec4b7fe883e2d5bf137ede9262d035880f36610a39f','discokey:d25d5f42aee8b5d8e22b9ba1fa40e7295ad0f2b00c466d03c267ac9c0e00d152','email-49','node085',23,'cli',NULL,NULL,'2025-06-06 20:55:32.134989319+02:00',NULL,'{"fake":"data"}','["[b0bf:223c:e0af:4993:14e0:acb1:936e:4db2]:39578","222.45.50.133:6908","223.57.18.237:24236","172.116.24.79:64278"]','2025-03-25 10:08:52.471661925+01:00','2025-06-06 20:55:32.135474025+02:00',NULL,'100.64.0.76','fd7a:115c:a1e0::4c',NULL);
INSERT INTO nodes VALUES(86,'mkey:41dcb7bf690ffde927829637a6fc7c98b2600a504561ce7b0667f0f2aa1f3ab2','nodekey:633596e036705ce9ba03ce044cb7b5cd008f7045caee57fa594803a3b95c564a','discokey:9d96b830729e50d763debfefcd3af6f91ee9bb9daf53d6890652a25f3263f823','srv-96','node086',27,'cli',NULL,NULL,'2025-06-20 08:34:16.969649646+02:00',NULL,'{"fake":"data"}','["[a09b:5970:b127:fdfc:e68e:e496:bdee:6f12]:36132","51.12.68.23:57633","33.175.40.132:2790"]','2025-03-26 10:24:31.473595709+01:00','2025-06-20 08:34:16.970146755+02:00',NULL,'100.64.0.77','fd7a:115c:a1e0::4d',NULL);
INSERT INTO nodes VALUES(87,'mkey:3944556a65c99ee2890a8bd572dc3001f71f1eeebc580a026146eaa8def09009','nodekey:11966e544db141f610b5a1a864bd4be18373952b3a8ced40214105ef7371127f','discokey:a77a4b657a9ac80ad760d1e7348065578555373d8843162326e6366b0c54e444','web-11','node087',27,'cli',NULL,NULL,'2025-06-20 08:29:06.936731549+02:00',NULL,'{"fake":"data"}','["16.142.13.19:36771","[ad8a:a3fa:8d4d:c659:5e32:45dd:d95f:abc8]:43118","[797c:a12f:a521:102b:e357:ad81:247:fdcf]:61479","[5f8:a29a:bcab:9a90:4bdc:7d00:46bc:a69e]:16041"]','2025-03-26 14:30:57.179694234+01:00','2025-06-20 08:29:10.787309705+02:00',NULL,'100.64.0.78','fd7a:115c:a1e0::4e',NULL);
INSERT INTO nodes VALUES(88,'mkey:8ba458a88b40b125982bf763462a8f252fc3e80fdf8f472ab1545842af53494f','nodekey:09e6884692ec3f7f53bcc16bea60e1d4dfab44dd459af7dc42ab263e1d78920b','discokey:a09ed63f785315ae2ab524c3b34aad6f12d23a96771def70a3e0fb2de7ae7416','laptop-52','node088',27,'cli',NULL,NULL,'2025-06-19 08:39:43.92787588+02:00',NULL,'{"fake":"data"}','["54.165.39.252:59066","[127c:b334:8ae3:358c:4178:fae4:9f31:521c]:33026","104.73.3.103:62847","[fd18:384b:ef76:f4b7:6983:bd4e:70af:ce35]:42618","7.111.70.18:4634"]','2025-03-26 14:37:55.198097806+01:00','2025-06-19 08:39:48.020920495+02:00',NULL,'100.64.0.79','fd7a:115c:a1e0::4f',NULL);
INSERT INTO nodes VALUES(89,'mkey:3a17d7f9a8e51885b842e63fffad7374b06e1804f3a48e9362c2cc3e46df0af7','nodekey:4c771b227735fcb0f7e6cef27350852bffa406ad446fd37cf60f98ecbacc04a7','discokey:6a2091fd8a448626ad02024b66216b22ed02926807c2b7a18877f300e1d1d632','srv-52','node089',28,'cli',NULL,NULL,'2025-06-28 07:45:05.917078332+02:00',NULL,'{"fake":"data"}','["[3769:2186:2b73:8e38:b9bb:54c6:e48a:6e65]:33253","[460c:9b85:4ea7:ea85:e205:aa7:210e:c098]:44172","222.138.65.141:16368","[4bdf:4d9a:f0d3:2bea:deb9:33d4:c163:513]:6983","212.18.134.205:41528","190.153.32.51:23708"]','2025-03-31 18:34:22.574460539+02:00','2025-06-28 07:45:05.917342923+02:00',NULL,'100.64.0.80','fd7a:115c:a1e0::50',NULL);
INSERT INTO nodes VALUES(90,'mkey:3b2445a4e3d1c6cf3d909493530eecf8bff85ef8a440ba467d32bf6f1b64d24b','nodekey:298e7d97f1d1289dff2249401d706813c0d89121fab70e2cc514f3a53dbf14c7','discokey:3cca67ae4c540ceb6a8a7b552fdd8eddb54db6a1c082e290a4c0aa638c5c5efe','srv-72','node090',27,'cli',NULL,NULL,'2025-06-20 23:20:42.928064133+02:00',NULL,'{"fake":"data"}','["[262b:3b74:f0ee:1ea9:9099:5c3d:f9a2:22]:46101","[40ca:40f3:9b64:de92:c1af:a19d:f7e0:1dbc]:30741","[a9f5:d5cd:d553:b5:17f3:3d89:8617:46a5]:21519","102.217.166.61:13721","46.95.71.249:58007","168.186.124.250:51025"]','2025-04-03 17:52:02.130025013+02:00','2025-06-20 23:20:42.928708477+02:00',NULL,'100.64.0.81','fd7a:115c:a1e0::51',NULL);
INSERT INTO nodes VALUES(91,'mkey:2eb9cfef2ed45380bbb4043e4aa79257b50ed4575489fb5c789469283f31610a','nodekey:b09c411a584f487513bdbebd8fb50f91ca57c0f544c0649b155ba892bc9173b3','discokey:e95823238298c4f5554dd2c69e1f62ef05cae05dcd1bd95045b582f2136a7757','db-74','node091',27,'cli',NULL,NULL,'2025-06-28 03:30:33.869801917+02:00',NULL,'{"fake":"data"}','["[575d:4099:ec56:8209:f0f:ed49:b6d9:f75b]:27401","[a35b:63a2:51a7:81a6:eb0b:5e72:f82e:bdec]:54393","84.160.88.244:21712"]','2025-04-05 18:49:13.742268632+02:00','2025-06-28 03:30:33.870261795+02:00',NULL,'100.64.0.82','fd7a:115c:a1e0::52',NULL);
INSERT INTO nodes VALUES(92,'mkey:51551f7bcfb7e10f052439502541e9c00c37a8f3de91ed0fe01e5c3c47dea5a3','nodekey:6975b5ed6c0cfa85e0cdf6152f2d6c0c273109bfcaa76860637de5f1dc9e40ac','discokey:dba4f8059d89090a2e198367bbd04d6c5475abca7ae3731b7aa29c382131af27','lt-17','node092',23,'cli',NULL,NULL,'2025-06-28 12:21:17.063796663+02:00',NULL,'{"fake":"data"}','["[8052:8707:2eea:c767:5493:dd06:2d75:55a1]:60873","[8c83:88e1:5427:d2e:8604:ff8b:3c0a:6587]:6368","182.184.190.162:26611","[c45e:f0f9:8bf6:6beb:9170:ae3e:bc81:1842]:3750"]','2025-04-10 09:33:19.75758384+02:00','2025-06-28 12:21:17.064223203+02:00',NULL,'100.64.0.83','fd7a:115c:a1e0::54',NULL);
INSERT INTO nodes VALUES(93,'mkey:df4d9b0848620e7033c8cbecbe7cd076475433baa6a8233289a8207f538969c1','nodekey:2d50983fa2d5735e306a8c05630a41b897419528e2c9e7143efc29f2517777c6','discokey:7d62636f14b697c8d9666535fccc89cacb009088200957070d2ffb7108e79694','desktop-28','node093',23,'cli',NULL,NULL,'2025-06-28 12:23:07.890521061+02:00',NULL,'{"fake":"data"}','["[9497:e689:56ef:65ff:40ba:5bec:198:cbaa]:6478","165.179.14.165:11130","59.185.174.72:31766","[b430:987d:5157:7cdf:582b:c6c:801b:19d3]:8744"]','2025-04-10 11:00:40.243041051+02:00','2025-06-28 12:23:07.891010158+02:00',NULL,'100.64.0.84','fd7a:115c:a1e0::55',NULL);
INSERT INTO nodes VALUES(94,'mkey:0457d727c81909cd14e5edc1f8fd43c685bb5bca802c26df60fc27b90b66ff04','nodekey:316a01774fde64ebcfd3192f99ef9f83ff9c250b916090c1829d690d7ef5291e','discokey:de047a08a4c07142790d6919eb61e5d1c6bfebda7547778ba6e13b4166dd9100','email-53','node094',23,'cli',NULL,NULL,'2025-06-28 12:18:55.75713159+02:00',NULL,'{"fake":"data"}','["95.217.54.187:12234","2.119.104.181:58132","[7e19:7d5d:ce33:64aa:d9a0:5:ec9e:56c3]:40537","111.114.18.75:28011"]','2025-04-10 11:41:58.339188608+02:00','2025-06-28 12:18:55.757420045+02:00',NULL,'100.64.0.85','fd7a:115c:a1e0::56',NULL);
INSERT INTO nodes VALUES(95,'mkey:a0aad10c0947eabadb07e0a064b118abc6317194a20a35eefbf5f00497cc86b4','nodekey:f508bb43820174bbfbff0ddaa441477c6a4b1ad16e2d6a6c8bd8e7d579cc9512','discokey:7f3ea4389df4edfa3c5091be7ff8dab835b2584d453d8df7727d82828e9eb598','db-56','node095',1,'cli',NULL,NULL,'2025-06-28 10:23:24.075008579+02:00',NULL,'{"fake":"data"}','["24.36.243.82:39056","[100e:6264:4572:885e:777a:94d9:d296:29e5]:56545","[85c:f9c7:4780:41ba:b873:e740:7a65:aaf6]:46931","117.173.93.251:32036","3.127.130.51:31048","[b2b6:54b1:547b:3b76:a977:8ef0:9263:1d95]:10788"]','2025-04-18 07:31:25.494609012+02:00','2025-06-28 10:23:24.075270399+02:00',NULL,'100.64.0.86','fd7a:115c:a1e0::57',NULL);
INSERT INTO nodes VALUES(96,'mkey:9c90f9a2cf141fbf87bb7a713b11363c7700648c247b2be55880be65b097b32e','nodekey:a891e03b7e3f92ee155c51f966ff579e1b59affcdd7ffe2be0b17617fc5d2a4f','discokey:2d47647673be16002087672c8c3c333af739c0429b4ca3199a0b37c775f188ec','srv-31','node096',27,'cli',NULL,NULL,'2025-06-21 19:42:23.023186161+02:00',NULL,'{"fake":"data"}','["99.229.28.236:22736","[e5ea:7d6c:d0e6:153c:b9f6:17da:3b8e:a7dd]:11150","116.109.151.5:63986","[4167:adfc:1fcb:624c:e8d1:7469:aab7:e6a3]:29364","151.32.217.201:35528","129.148.62.154:38346","[5bcc:3f9b:413a:f79c:9785:4537:4acb:9123]:12439"]','2025-04-25 19:06:18.720283603+02:00','2025-06-21 19:42:23.023317999+02:00',NULL,'100.64.0.87','fd7a:115c:a1e0::58',NULL);
INSERT INTO nodes VALUES(97,'mkey:e403a9d40dd5cc7b3c34bb8e883069e46ea691bd901d80a18255b2e978ebbca3','nodekey:9fb4a4edd2f095f6d3ffc2783d13c1c1c9397edc7926a57a2b91d292dc6d9539','discokey:e3ddfd156fab89c7572aba20e9606ec10cdf6f8f60bf4a0e4b0ee9986b9fe875','desktop-17','node097',23,'cli',NULL,NULL,'2025-06-06 20:55:32.914042482+02:00',NULL,'{"fake":"data"}','["[5088:bc4f:e27b:708c:e75:6278:90c:92b5]:37686","[f352:c3ab:52a4:2b1c:d1b5:9ee4:a15e:d832]:39715"]','2025-05-14 09:57:07.359717602+02:00','2025-06-06 20:55:32.915628496+02:00',NULL,'100.64.0.88','fd7a:115c:a1e0::59',NULL);
INSERT INTO nodes VALUES(98,'mkey:076f21957e297a47c7e893b37dc38ccbc10d16041c45e733755f63a9adf27209','nodekey:23be3c688a8b508b5e09708e2a2623ece5b9ec426a776787ff163bea80104fa6','discokey:443acdc2d4a9c9f5c316b728916259e58eea2d0dc7e438181335306964c22121','desktop-72','node098',27,'cli',NULL,NULL,'2025-06-12 20:47:06.114210533+02:00',NULL,'{"fake":"data"}','["34.11.54.132:20475","[8104:4565:fd92:f07b:5ce7:8ad9:590e:349b]:64085","[fa37:1f6:5256:186d:2ce6:ed1f:b9b8:5d73]:42737","[6e79:cebf:1df1:83d1:d0de:38ca:4eaa:7bd3]:25953","[56df:3d29:e870:353a:bb28:ffcd:b225:5231]:57718","170.226.226.154:61176","[d122:a66a:2153:741a:b188:5260:a325:6c68]:17261","[67ca:e4a8:6a48:8880:1183:c56:7416:9af0]:57017","72.3.174.188:14460"]','2025-05-14 11:56:48.415832658+02:00','2025-06-12 20:47:06.114995503+02:00',NULL,'100.64.0.89','fd7a:115c:a1e0::5a',NULL);
INSERT INTO nodes VALUES(99,'mkey:24908f72d8e598ce86ab51aedbe19f7db7d459b33d53e0383231e3d54239680d','nodekey:37a38d1af4997a3a37406cfefc83240035cf5fbad122d46534e62ac9c9b23821','discokey:19926fa875306f0b304e898eee83f1711db11b5930a3016c18d0d503b37f0841','laptop-14','node099',14,'cli',NULL,NULL,'2025-06-06 20:55:32.627376311+02:00',NULL,'{"fake":"data"}','["[6228:aa08:b376:ded6:55d1:b081:66fa:6299]:59385"]','2025-05-22 13:59:12.642339275+02:00','2025-06-06 20:55:32.632840843+02:00',NULL,'100.64.0.90','fd7a:115c:a1e0::5b',NULL);
CREATE TABLE `policies` (`id` integer PRIMARY KEY AUTOINCREMENT,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`data` text);
CREATE TABLE IF NOT EXISTS "users" (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,`display_name` text,`email` text,`provider_identifier` text,`provider` text,`profile_pic_url` text,PRIMARY KEY (`id`));
INSERT INTO users VALUES(1,'2023-05-17 19:36:55.859473496+02:00','2025-05-14 19:39:49.446674051+02:00',NULL,'user001','','',NULL,'','');
INSERT INTO users VALUES(2,'2023-05-17 19:36:57.059073465+02:00','2025-05-14 19:39:49.446939883+02:00',NULL,'user002','','',NULL,'','');
INSERT INTO users VALUES(3,'2023-05-18 10:10:36.248939077+02:00','2025-05-14 19:39:49.447156233+02:00',NULL,'user003','','',NULL,'','');
INSERT INTO users VALUES(4,'2023-06-10 09:06:13.920718561+02:00','2025-05-14 19:39:49.447397385+02:00',NULL,'user004','','',NULL,'','');
INSERT INTO users VALUES(5,'2023-06-11 19:58:32.371218434+02:00','2025-05-14 19:39:49.447602838+02:00',NULL,'user005','','',NULL,'','');
INSERT INTO users VALUES(6,'2023-06-17 19:39:53.031565686+02:00','2025-05-14 19:39:49.447803872+02:00',NULL,'user006','','',NULL,'','');
INSERT INTO users VALUES(7,'2023-06-20 11:35:09.325846831+02:00','2025-05-14 19:39:49.447987808+02:00',NULL,'user007','','',NULL,'','');
INSERT INTO users VALUES(8,'2023-06-21 22:47:48.196234382+02:00','2025-05-14 19:39:49.44820155+02:00',NULL,'user008','','',NULL,'','');
INSERT INTO users VALUES(9,'2023-06-22 08:30:35.068995572+02:00','2025-05-14 19:39:49.448483514+02:00',NULL,'user009','','',NULL,'','');
INSERT INTO users VALUES(10,'2023-07-03 10:18:32.123226+02:00','2025-05-14 19:39:49.448692002+02:00',NULL,'user010','','',NULL,'','');
INSERT INTO users VALUES(11,'2023-07-03 10:18:37.130387602+02:00','2025-05-14 19:39:49.448883814+02:00',NULL,'user011','','',NULL,'','');
INSERT INTO users VALUES(12,'2023-12-15 08:05:06.013615212+01:00','2025-05-14 19:39:49.449111509+02:00',NULL,'user012','','',NULL,'','');
INSERT INTO users VALUES(13,'2024-02-03 16:32:42.224977233+01:00','2025-05-14 19:39:49.449357341+02:00',NULL,'user013','','',NULL,'','');
INSERT INTO users VALUES(14,'2024-05-03 10:12:38.220973042+02:00','2025-05-14 19:39:49.449556253+02:00',NULL,'user014','','',NULL,'','');
INSERT INTO users VALUES(15,'2024-07-26 08:08:40.979783263+02:00','2025-05-14 19:39:49.449755129+02:00',NULL,'user015','','',NULL,'','');
INSERT INTO users VALUES(16,'2024-08-05 17:32:02.878091894+02:00','2025-05-14 19:39:49.449974677+02:00',NULL,'user016','','',NULL,'','');
INSERT INTO users VALUES(17,'2024-09-22 15:48:00.287392203+02:00','2025-05-14 19:39:49.450181734+02:00',NULL,'user017','','',NULL,'','');
INSERT INTO users VALUES(18,'2024-12-10 13:55:11.256977421+01:00','2025-05-14 19:39:49.450421161+02:00',NULL,'user018','','',NULL,'','');
INSERT INTO users VALUES(19,'2024-12-17 14:57:58.550971236+01:00','2025-05-14 19:39:49.450633287+02:00',NULL,'user019','','',NULL,'','');
INSERT INTO users VALUES(20,'2024-12-17 15:02:08.053169491+01:00','2025-05-14 19:39:49.450837357+02:00',NULL,'user020','','',NULL,'','');
INSERT INTO users VALUES(21,'2025-01-28 15:57:32.774456057+01:00','2025-05-14 19:39:49.451012461+02:00',NULL,'user021','','',NULL,'','');
INSERT INTO users VALUES(22,'2025-02-03 14:10:50.491924701+01:00','2025-05-14 19:39:49.451214878+02:00',NULL,'user022','','',NULL,'','');
INSERT INTO users VALUES(23,'2025-02-14 16:58:30.250289644+01:00','2025-05-14 19:39:49.451415294+02:00',NULL,'user023','','',NULL,'','');
INSERT INTO users VALUES(25,'2025-02-15 12:48:14.650995528+01:00','2025-05-14 19:39:49.451605671+02:00',NULL,'user025','','',NULL,'','');
INSERT INTO users VALUES(26,'2025-03-18 09:09:00.456523573+01:00','2025-05-14 19:39:49.451854829+02:00',NULL,'user026','','',NULL,'','');
INSERT INTO users VALUES(27,'2025-03-26 10:23:51.960113834+01:00','2025-05-14 19:39:49.452164228+02:00',NULL,'user027','','',NULL,'','');
INSERT INTO users VALUES(28,'2025-03-31 18:25:26.535133091+02:00','2025-05-14 19:39:49.452536759+02:00',NULL,'user028','','',NULL,'','');
CREATE UNIQUE INDEX `idx_api_keys_prefix` ON `api_keys`(`prefix`);
CREATE INDEX `idx_policies_deleted_at` ON `policies`(`deleted_at`);
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,11 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
INSERT INTO kvs VALUES('db_version','1');
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,7 @@
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);

View File

@@ -0,0 +1,11 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
INSERT INTO kvs VALUES('db_version','1');
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,7 @@
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);

View File

@@ -0,0 +1,11 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
INSERT INTO kvs VALUES('db_version','1');
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,7 @@
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);

View File

@@ -0,0 +1,11 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
INSERT INTO kvs VALUES('db_version','1');
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,7 @@
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);

View File

@@ -0,0 +1,11 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
INSERT INTO kvs VALUES('db_version','1');
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,7 @@
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);

View File

@@ -0,0 +1,11 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
INSERT INTO kvs VALUES('db_version','1');
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);
COMMIT;

View File

@@ -0,0 +1,7 @@
CREATE TABLE `namespaces` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text UNIQUE,PRIMARY KEY (`id`));
CREATE INDEX `idx_namespaces_deleted_at` ON `namespaces`(`deleted_at`);
CREATE TABLE `pre_auth_keys` (`id` integer,`key` text,`namespace_id` integer,`reusable` numeric,`ephemeral` numeric DEFAULT false,`used` numeric DEFAULT false,`created_at` datetime,`expiration` datetime,PRIMARY KEY (`id`));
CREATE TABLE `machines` (`id` integer,`machine_key` varchar(64),`node_key` text,`disco_key` text,`ip_address` text,`name` text,`namespace_id` integer,`registered` numeric,`register_method` text,`auth_key_id` integer,`last_seen` datetime,`last_successful_update` datetime,`expiry` datetime,`host_info` JSON,`endpoints` JSON,`enabled_routes` JSON,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,PRIMARY KEY (`id`));
CREATE TABLE `kvs` (`key` text,`value` text);
CREATE TABLE `shared_machines` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`machine_id` integer,`namespace_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_shared_machines_deleted_at` ON `shared_machines`(`deleted_at`);

Some files were not shown because too many files have changed in this diff Show More