Compare commits

...

30 Commits

Author SHA1 Message Date
Johan Siebens d0eac84271 chore(deps): upgrade some dependencies 2023-12-23 08:48:16 +01:00
Johan Siebens f193afa146 chore: update base image 2023-12-23 07:48:30 +01:00
Johan Siebens cf67f6cf64 chore: update workflows and goreleaser 2023-12-23 07:29:58 +01:00
Johan Siebens 1ac3aa36ba chore(deps): upgrade tailscale dependency 2023-07-21 08:20:51 +02:00
Johan Siebens 9fd4e5fee4 fix: log error when starting server fails 2023-04-15 08:26:08 +02:00
Johan Siebens 326860c941 fix: panic when user is not authorized 2023-04-08 09:56:37 +02:00
Johan Siebens 4ba540cb2c chore: replace hclog with zap 2023-03-19 10:53:54 +01:00
Johan Siebens 3577b8b46e chore(deps): upgrade dependencies 2023-03-12 08:38:18 +01:00
Johan Siebens f24f0973fe chore(deps): golang 1.20 2023-03-12 08:26:35 +01:00
Johan Siebens 12cad15a4e chore(deps): upgrade tailscale 2023-03-12 08:26:13 +01:00
Johan Siebens d5c3c699dd chore(docs): fix typo 2023-03-11 08:53:54 +01:00
Johan Siebens b3b21be50d chore(docs): fix incorrect acme_enabled property 2023-03-11 08:41:11 +01:00
Johan Siebens 051650ae4e chore: upgrade to golang 1.20 2023-03-08 07:46:58 +01:00
Johan Siebens 2fc79ee0a1 chore(deps): replace coral with latest cobra 2023-03-08 07:43:03 +01:00
Johan Siebens b7b3796ae6 chore: update base image 2023-03-08 07:40:48 +01:00
Johan Siebens b0074152d1 chore: add tests with new 1.36 version 2023-01-28 19:36:27 +01:00
Johan Siebens 4550bdbf2a fix: set default ACL and IAM policy if not provided 2023-01-28 19:28:51 +01:00
Johan Siebens d32ece6304 feat: create and update tailnets with all properties 2023-01-07 08:20:35 +01:00
Johan Siebens ef325dd936 docs: update to latest version 2023-01-05 08:49:06 +01:00
Johan Siebens 9a55d67c7e chore(deps): upgrade setup-go action 2023-01-05 08:22:26 +01:00
Johan Siebens cbbaa31580 fix: use stdencoding instead of rawstdencoding 2023-01-03 08:13:06 +01:00
Johan Siebens 35c46eb2ec chore: fix workflow file 2023-01-02 14:10:10 +01:00
Johan Siebens d6a564b7a9 chore: some initial integration tests 2023-01-02 14:07:38 +01:00
Johan Siebens 527fb34560 fix: use smallzstd and sync pool, slightly improving performance 2023-01-01 12:08:25 +01:00
Johan Siebens 805a516626 fix: avoid double user entries 2023-01-01 09:43:14 +01:00
Johan Siebens 0dbc81d50f fix: send exit node prefixes when enabled 2023-01-01 08:10:31 +01:00
Johan Siebens 40cc7b5648 fix: send same user for all tagged devices, reducing mapresponse payload when having many tagged devices 2022-12-31 08:26:30 +01:00
Johan Siebens b62db084d1 feat: add config to tweak sql connection pool 2022-12-30 09:28:50 +01:00
Johan Siebens df23c178f9 feat: add gorm prometheus metrics 2022-12-30 09:07:29 +01:00
Johan Siebens 9f7263abd5 fix: add machines indeces and use gorm take instead of first 2022-12-27 11:14:53 +01:00
81 changed files with 3154 additions and 1871 deletions
+4 -3
View File
@@ -27,10 +27,11 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: 1.19
go-version-file: 'go.mod'
cache: true
- name: Build
run: |
go test ./...
go test -v -short ./...
go build cmd/ionscale/main.go
+33
View File
@@ -0,0 +1,33 @@
name: Integration Tests
on: workflow_dispatch
jobs:
integration:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ts_version:
- "1.46.0"
- "1.44.2"
- "1.42.0"
- "1.40.1"
- "1.38.4"
- "1.36.2"
- "1.34.1"
env:
IONSCALE_TESTS_TS_TARGET_VERSION: ${{ matrix.ts_version }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
cache: true
- name: Run Integration Tests
run: |
go test -v ./tests
-42
View File
@@ -1,42 +0,0 @@
name: nightly
on: workflow_dispatch
permissions:
contents: write
packages: write
id-token: write
jobs:
release:
runs-on: ubuntu-latest
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Docker Login
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.19
- name: Install cosign
uses: sigstore/cosign-installer@v2.8.1
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
distribution: goreleaser-pro
version: latest
args: release --nightly --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
+8 -8
View File
@@ -3,7 +3,7 @@ name: release
on:
push:
tags:
- '*'
- 'v*'
permissions:
contents: write
@@ -29,17 +29,17 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: 1.19
go-version-file: 'go.mod'
cache: true
- name: Install cosign
uses: sigstore/cosign-installer@v2.8.1
uses: sigstore/cosign-installer@v3.1.1
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser-pro
distribution: goreleaser
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+3 -4
View File
@@ -1,8 +1,5 @@
project_name: ionscale
nightly:
name_template: '{{ incminor .Version }}-dev'
before:
hooks:
- go mod tidy
@@ -44,7 +41,7 @@ docker_manifests:
image_templates:
- ghcr.io/jsiebens/{{ .ProjectName }}:{{ .Version }}-amd64
- ghcr.io/jsiebens/{{ .ProjectName }}:{{ .Version }}-arm64
- name_template: ghcr.io/jsiebens/{{ .ProjectName }}:{{ if .IsNightly }}dev{{ else }}latest{{ end }}
- name_template: ghcr.io/jsiebens/{{ .ProjectName }}:latest
image_templates:
- ghcr.io/jsiebens/{{ .ProjectName }}:{{ .Version }}-amd64
- ghcr.io/jsiebens/{{ .ProjectName }}:{{ .Version }}-arm64
@@ -59,6 +56,7 @@ signs:
- '--output-certificate=${certificate}'
- '--output-signature=${signature}'
- '${artifact}'
- '--yes'
artifacts: checksum
docker_signs:
@@ -70,6 +68,7 @@ docker_signs:
args:
- sign
- '${artifact}'
- '--yes'
archives:
- format: binary
+1 -1
View File
@@ -1,4 +1,4 @@
FROM --platform=${BUILDPLATFORM:-linux/amd64} alpine:3.16.2
FROM --platform=${BUILDPLATFORM:-linux/amd64} alpine:3.19.0
COPY ionscale /usr/local/bin/ionscale
+133 -110
View File
@@ -1,153 +1,176 @@
module github.com/jsiebens/ionscale
go 1.19
go 1.20
require (
github.com/apparentlymart/go-cidr v1.1.0
github.com/bufbuild/connect-go v1.0.0
github.com/bufbuild/connect-go v1.10.0
github.com/caarlos0/env/v6 v6.10.1
github.com/caddyserver/certmagic v0.17.1
github.com/coreos/go-oidc/v3 v3.3.0
github.com/glebarez/sqlite v1.5.0
github.com/caddyserver/certmagic v0.20.0
github.com/coreos/go-oidc/v3 v3.9.0
github.com/glebarez/sqlite v1.10.0
github.com/go-gormigrate/gormigrate/v2 v2.0.2
github.com/golang-jwt/jwt/v4 v4.4.2
github.com/hashicorp/go-bexpr v0.1.11
github.com/hashicorp/go-hclog v1.3.0
github.com/go-jose/go-jose/v3 v3.0.1
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/hashicorp/go-bexpr v0.1.13
github.com/hashicorp/go-multierror v1.1.1
github.com/imdario/mergo v0.3.12
github.com/imdario/mergo v0.3.15
github.com/jsiebens/go-edit v0.1.0
github.com/klauspost/compress v1.15.9
github.com/labstack/echo-contrib v0.13.0
github.com/labstack/echo/v4 v4.9.0
github.com/libdns/azure v0.2.0
github.com/klauspost/compress v1.17.4
github.com/labstack/echo-contrib v0.15.0
github.com/labstack/echo/v4 v4.11.4
github.com/libdns/azure v0.3.0
github.com/libdns/cloudflare v0.1.0
github.com/libdns/digitalocean v0.0.0-20220518195853-a541bc8aa80f
github.com/libdns/googleclouddns v1.0.2
github.com/libdns/digitalocean v0.0.0-20230728223659-4f9064657aea
github.com/libdns/googleclouddns v1.1.0
github.com/libdns/libdns v0.2.1
github.com/libdns/route53 v1.2.2
github.com/libdns/route53 v1.3.3
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/pointerstructure v1.2.1
github.com/mr-tron/base58 v1.2.0
github.com/muesli/coral v1.0.0
github.com/nleeper/goment v1.4.4
github.com/prometheus/client_golang v1.13.0
github.com/rodaine/table v1.0.1
github.com/sony/sonyflake v1.1.0
github.com/stretchr/testify v1.8.0
github.com/xhit/go-str2duration/v2 v2.0.0
golang.org/x/crypto v0.1.0
golang.org/x/net v0.4.0
golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0
google.golang.org/protobuf v1.28.1
gopkg.in/square/go-jose.v2 v2.6.0
github.com/ory/dockertest/v3 v3.9.1
github.com/prometheus/client_golang v1.17.0
github.com/rodaine/table v1.1.0
github.com/sony/sonyflake v1.2.0
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.8.4
github.com/xhit/go-str2duration/v2 v2.1.0
go.uber.org/zap v1.26.0
golang.org/x/crypto v0.17.0
golang.org/x/net v0.19.0
golang.org/x/oauth2 v0.15.0
golang.org/x/sync v0.5.0
google.golang.org/protobuf v1.32.0
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/postgres v1.4.4
gorm.io/gorm v1.24.0
gorm.io/driver/postgres v1.5.4
gorm.io/gorm v1.25.5
gorm.io/plugin/prometheus v0.1.0
inet.af/netaddr v0.0.0-20220811202034-502d2d690317
tailscale.com v1.32.0
tailscale.com v1.46.0
)
require (
cloud.google.com/go/compute v1.7.0 // indirect
github.com/Azure/azure-sdk-for-go v52.4.0+incompatible // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.17 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.11 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.7 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/logger v0.2.0 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
cloud.google.com/go/compute v1.23.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 // indirect
github.com/aws/aws-sdk-go-v2 v1.11.2 // indirect
github.com/aws/aws-sdk-go-v2/config v1.11.0 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.6.4 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.8.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.5.2 // indirect
github.com/aws/aws-sdk-go-v2/service/route53 v1.12.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.6.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.11.1 // indirect
github.com/aws/smithy-go v1.9.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect
github.com/aws/aws-sdk-go-v2/config v1.26.2 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect
github.com/aws/aws-sdk-go-v2/service/route53 v1.36.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect
github.com/aws/smithy-go v1.19.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/coreos/go-iptables v0.6.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/digitalocean/godo v1.41.0 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/form3tech-oss/jwt-go v3.2.2+incompatible // indirect
github.com/glebarez/go-sqlite v1.19.2 // indirect
github.com/digitalocean/godo v1.107.0 // indirect
github.com/docker/cli v23.0.5+incompatible // indirect
github.com/docker/docker v23.0.5+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/glebarez/go-sqlite v1.21.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v5 v5.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa // indirect
github.com/googleapis/gax-go/v2 v2.4.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/nftables v0.1.1-0.20230115205135-9aa6fdf5a28c // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.13.0 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.1 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jackc/pgtype v1.12.0 // indirect
github.com/jackc/pgx/v4 v4.17.2 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgx/v5 v5.5.1 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/native v1.0.0 // indirect
github.com/jsimonetti/rtnetlink v1.2.2 // indirect
github.com/klauspost/cpuid/v2 v2.1.1 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 // indirect
github.com/jsimonetti/rtnetlink v1.3.2 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/lib/pq v1.10.6 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mdlayher/netlink v1.6.0 // indirect
github.com/mdlayher/socket v0.2.3 // indirect
github.com/mholt/acmez v1.0.4 // indirect
github.com/miekg/dns v1.1.50 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mdlayher/netlink v1.7.2 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/mholt/acmez v1.2.0 // indirect
github.com/miekg/dns v1.1.57 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
github.com/opencontainers/runc v1.1.4 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85 // indirect
github.com/tkuchiki/go-timezone v0.2.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
go.opencensus.io v0.23.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.23.0 // indirect
go4.org/intern v0.0.0-20220617035311-6925f38cc365 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/vishvananda/netlink v1.2.1-beta.2 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go4.org/intern v0.0.0-20230205224052-192e9f60865c // indirect
go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
golang.org/x/tools v0.1.12 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230221090011-e4bae7ad2296 // indirect
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.1 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/api v0.84.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect
google.golang.org/grpc v1.48.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
modernc.org/libc v1.21.1 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.4.0 // indirect
modernc.org/sqlite v1.19.2 // indirect
google.golang.org/api v0.126.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect
google.golang.org/grpc v1.60.1 // indirect
gvisor.dev/gvisor v0.0.0-20230504175454-7b0a1988a28f // indirect
modernc.org/libc v1.38.0 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
modernc.org/sqlite v1.28.0 // indirect
nhooyr.io/websocket v1.8.7 // indirect
)
+592 -395
View File
File diff suppressed because it is too large Load Diff
+22 -12
View File
@@ -8,6 +8,8 @@ import (
"github.com/klauspost/compress/zstd"
"github.com/labstack/echo/v4"
"io/ioutil"
"sync"
"tailscale.com/smallzstd"
"tailscale.com/types/key"
)
@@ -77,12 +79,7 @@ func (d *defaultBinder) Marshal(compress string, v interface{}) ([]byte, error)
}
if compress == "zstd" {
encoder, err := zstd.NewWriter(nil)
if err != nil {
return nil, err
}
payload = encoder.EncodeAll(marshalled, nil)
payload = zstdEncode(marshalled)
} else {
payload = marshalled
}
@@ -140,12 +137,7 @@ func (b *boxBinder) Marshal(compress string, v interface{}) ([]byte, error) {
}
if compress == "zstd" {
encoder, err := zstd.NewWriter(nil)
if err != nil {
return nil, err
}
encoded := encoder.EncodeAll(marshalled, nil)
encoded := zstdEncode(marshalled)
payload = b.controlKey.SealTo(b.machineKey, encoded)
} else {
payload = b.controlKey.SealTo(b.machineKey, marshalled)
@@ -161,3 +153,21 @@ func (b *boxBinder) Marshal(compress string, v interface{}) ([]byte, error) {
func (b *boxBinder) Peer() key.MachinePublic {
return b.machineKey
}
func zstdEncode(in []byte) []byte {
encoder := zstdEncoderPool.Get().(*zstd.Encoder)
out := encoder.EncodeAll(in, nil)
encoder.Close()
zstdEncoderPool.Put(encoder)
return out
}
var zstdEncoderPool = &sync.Pool{
New: func() any {
encoder, err := smallzstd.NewEncoder(nil, zstd.WithEncoderLevel(zstd.SpeedFastest))
if err != nil {
panic(err)
}
return encoder
},
}
+10 -10
View File
@@ -8,13 +8,13 @@ import (
"github.com/bufbuild/connect-go"
"github.com/jsiebens/go-edit/editor"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/spf13/cobra"
"io/ioutil"
"os"
)
func getACLConfigCommand() *coral.Command {
command := &coral.Command{
func getACLConfigCommand() *cobra.Command {
command := &cobra.Command{
Use: "get-acl-policy",
Short: "Get the ACL policy",
SilenceUsage: true,
@@ -29,7 +29,7 @@ func getACLConfigCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(cmd *coral.Command, args []string) error {
command.RunE = func(cmd *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -58,8 +58,8 @@ func getACLConfigCommand() *coral.Command {
return command
}
func editACLConfigCommand() *coral.Command {
command := &coral.Command{
func editACLConfigCommand() *cobra.Command {
command := &cobra.Command{
Use: "edit-acl-policy",
Short: "Edit the ACL policy",
SilenceUsage: true,
@@ -74,7 +74,7 @@ func editACLConfigCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(cmd *coral.Command, args []string) error {
command.RunE = func(cmd *cobra.Command, args []string) error {
edit := editor.NewDefaultEditor([]string{"IONSCALE_EDITOR", "EDITOR"})
client, err := target.createGRPCClient()
@@ -122,8 +122,8 @@ func editACLConfigCommand() *coral.Command {
return command
}
func setACLConfigCommand() *coral.Command {
command := &coral.Command{
func setACLConfigCommand() *cobra.Command {
command := &cobra.Command{
Use: "set-acl-policy",
Short: "Set ACL policy",
SilenceUsage: true,
@@ -140,7 +140,7 @@ func setACLConfigCommand() *coral.Command {
command.Flags().StringVar(&file, "file", "", "Path to json file with the acl configuration")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(cmd *coral.Command, args []string) error {
command.RunE = func(cmd *cobra.Command, args []string) error {
rawJson, err := ioutil.ReadFile(file)
if err != nil {
return err
+6 -6
View File
@@ -6,11 +6,11 @@ import (
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/pkg/client/ionscale"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/spf13/cobra"
)
func authCommand() *coral.Command {
command := &coral.Command{
func authCommand() *cobra.Command {
command := &cobra.Command{
Use: "auth",
}
@@ -19,8 +19,8 @@ func authCommand() *coral.Command {
return command
}
func authLoginCommand() *coral.Command {
command := &coral.Command{
func authLoginCommand() *cobra.Command {
command := &cobra.Command{
Use: "login",
SilenceUsage: true,
}
@@ -29,7 +29,7 @@ func authLoginCommand() *coral.Command {
target.prepareCommand(command)
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
+12 -12
View File
@@ -5,16 +5,16 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/rodaine/table"
"github.com/spf13/cobra"
str2dur "github.com/xhit/go-str2duration/v2"
"google.golang.org/protobuf/types/known/durationpb"
"strings"
"time"
)
func authkeysCommand() *coral.Command {
command := &coral.Command{
func authkeysCommand() *cobra.Command {
command := &cobra.Command{
Use: "auth-keys",
Aliases: []string{"auth-key"},
Short: "Manage ionscale auth keys",
@@ -27,8 +27,8 @@ func authkeysCommand() *coral.Command {
return command
}
func createAuthkeysCommand() *coral.Command {
command := &coral.Command{
func createAuthkeysCommand() *cobra.Command {
command := &cobra.Command{
Use: "create",
Short: "Creates a new auth key in the specified tailnet",
SilenceUsage: true,
@@ -51,7 +51,7 @@ func createAuthkeysCommand() *coral.Command {
command.Flags().BoolVar(&preAuthorized, "pre-authorized", false, "Generate an auth key which is pre-authorized.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -98,8 +98,8 @@ func createAuthkeysCommand() *coral.Command {
return command
}
func deleteAuthKeyCommand() *coral.Command {
command := &coral.Command{
func deleteAuthKeyCommand() *cobra.Command {
command := &cobra.Command{
Use: "delete",
Short: "Delete a specified auth key",
SilenceUsage: true,
@@ -110,7 +110,7 @@ func deleteAuthKeyCommand() *coral.Command {
target.prepareCommand(command)
command.Flags().Uint64Var(&authKeyId, "id", 0, "Auth Key ID")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
grpcClient, err := target.createGRPCClient()
if err != nil {
return err
@@ -129,8 +129,8 @@ func deleteAuthKeyCommand() *coral.Command {
return command
}
func listAuthkeysCommand() *coral.Command {
command := &coral.Command{
func listAuthkeysCommand() *cobra.Command {
command := &cobra.Command{
Use: "list",
Short: "List all auth keys for a given tailnet",
SilenceUsage: true,
@@ -145,7 +145,7 @@ func listAuthkeysCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
+5 -5
View File
@@ -5,13 +5,13 @@ import (
"fmt"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/key"
"github.com/muesli/coral"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"path/filepath"
)
func configureCommand() *coral.Command {
command := &coral.Command{
func configureCommand() *cobra.Command {
command := &cobra.Command{
Use: "configure",
Short: "Generate a simple config file to get started.",
SilenceUsage: true,
@@ -33,7 +33,7 @@ func configureCommand() *coral.Command {
command.MarkFlagRequired("domain")
command.PreRunE = func(cmd *coral.Command, args []string) error {
command.PreRunE = func(cmd *cobra.Command, args []string) error {
if domain == "" {
return errors.New("required flag 'domain' is missing")
}
@@ -49,7 +49,7 @@ func configureCommand() *coral.Command {
return nil
}
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
c := &config.Config{}
c.HttpListenAddr = "0.0.0.0:80"
+12 -12
View File
@@ -6,14 +6,14 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"os"
"tailscale.com/tailcfg"
)
func systemCommand() *coral.Command {
command := &coral.Command{
func systemCommand() *cobra.Command {
command := &cobra.Command{
Use: "system",
Short: "Manage global system configurations",
}
@@ -25,8 +25,8 @@ func systemCommand() *coral.Command {
return command
}
func getDefaultDERPMap() *coral.Command {
command := &coral.Command{
func getDefaultDERPMap() *cobra.Command {
command := &cobra.Command{
Use: "get-derp-map",
Short: "Get the DERP Map configuration",
SilenceUsage: true,
@@ -38,7 +38,7 @@ func getDefaultDERPMap() *coral.Command {
target.prepareCommand(command)
command.Flags().BoolVar(&asJson, "json", false, "When enabled, render output as json otherwise yaml")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -80,8 +80,8 @@ func getDefaultDERPMap() *coral.Command {
return command
}
func setDefaultDERPMap() *coral.Command {
command := &coral.Command{
func setDefaultDERPMap() *cobra.Command {
command := &cobra.Command{
Use: "set-derp-map",
Short: "Set the DERP Map configuration",
SilenceUsage: true,
@@ -92,7 +92,7 @@ func setDefaultDERPMap() *coral.Command {
target.prepareCommand(command)
command.Flags().StringVar(&file, "file", "", "Path to json file with the DERP Map configuration")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
grpcClient, err := target.createGRPCClient()
if err != nil {
return err
@@ -121,8 +121,8 @@ func setDefaultDERPMap() *coral.Command {
return command
}
func resetDefaultDERPMap() *coral.Command {
command := &coral.Command{
func resetDefaultDERPMap() *cobra.Command {
command := &cobra.Command{
Use: "reset-derp-map",
Short: "Reset the DERP Map to the default configuration",
SilenceUsage: true,
@@ -131,7 +131,7 @@ func resetDefaultDERPMap() *coral.Command {
var target = Target{}
target.prepareCommand(command)
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
grpcClient, err := target.createGRPCClient()
if err != nil {
return err
+7 -7
View File
@@ -5,14 +5,14 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/spf13/cobra"
"os"
"strings"
"text/tabwriter"
)
func getDNSConfigCommand() *coral.Command {
command := &coral.Command{
func getDNSConfigCommand() *cobra.Command {
command := &cobra.Command{
Use: "get-dns",
Short: "Get DNS configuration",
SilenceUsage: true,
@@ -27,7 +27,7 @@ func getDNSConfigCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -82,8 +82,8 @@ func getDNSConfigCommand() *coral.Command {
return command
}
func setDNSConfigCommand() *coral.Command {
command := &coral.Command{
func setDNSConfigCommand() *cobra.Command {
command := &cobra.Command{
Use: "set-dns",
Short: "Set DNS config",
SilenceUsage: true,
@@ -105,7 +105,7 @@ func setDNSConfigCommand() *coral.Command {
command.Flags().BoolVarP(&overrideLocalDNS, "override-local-dns", "", false, "When enabled, connected clients ignore local DNS settings and always use the nameservers specified for this Tailnet")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
+2 -2
View File
@@ -7,10 +7,10 @@ import (
"github.com/jsiebens/ionscale/pkg/client/ionscale"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
apiconnect "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1/ionscalev1connect"
"github.com/muesli/coral"
"github.com/spf13/cobra"
)
func checkRequiredTailnetAndTailnetIdFlags(cmd *coral.Command, args []string) error {
func checkRequiredTailnetAndTailnetIdFlags(cmd *cobra.Command, args []string) error {
savedTailnetID, err := ionscale.TailnetFromFile()
if err != nil {
return err
+10 -10
View File
@@ -8,13 +8,13 @@ import (
"github.com/bufbuild/connect-go"
"github.com/jsiebens/go-edit/editor"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/spf13/cobra"
"io/ioutil"
"os"
)
func getIAMPolicyCommand() *coral.Command {
command := &coral.Command{
func getIAMPolicyCommand() *cobra.Command {
command := &cobra.Command{
Use: "get-iam-policy",
Short: "Get the IAM policy",
SilenceUsage: true,
@@ -29,7 +29,7 @@ func getIAMPolicyCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(cmd *coral.Command, args []string) error {
command.RunE = func(cmd *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -58,8 +58,8 @@ func getIAMPolicyCommand() *coral.Command {
return command
}
func editIAMPolicyCommand() *coral.Command {
command := &coral.Command{
func editIAMPolicyCommand() *cobra.Command {
command := &cobra.Command{
Use: "edit-iam-policy",
Short: "Edit the IAM policy",
SilenceUsage: true,
@@ -74,7 +74,7 @@ func editIAMPolicyCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(cmd *coral.Command, args []string) error {
command.RunE = func(cmd *cobra.Command, args []string) error {
edit := editor.NewDefaultEditor([]string{"IONSCALE_EDITOR", "EDITOR"})
client, err := target.createGRPCClient()
@@ -122,8 +122,8 @@ func editIAMPolicyCommand() *coral.Command {
return command
}
func setIAMPolicyCommand() *coral.Command {
command := &coral.Command{
func setIAMPolicyCommand() *cobra.Command {
command := &cobra.Command{
Use: "set-iam-policy",
Short: "Set IAM policy",
SilenceUsage: true,
@@ -140,7 +140,7 @@ func setIAMPolicyCommand() *coral.Command {
command.Flags().StringVar(&file, "file", "", "Path to json file with the acl configuration")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(cmd *coral.Command, args []string) error {
command.RunE = func(cmd *cobra.Command, args []string) error {
rawJson, err := ioutil.ReadFile(file)
if err != nil {
return err
+4 -4
View File
@@ -3,11 +3,11 @@ package cmd
import (
"fmt"
"github.com/jsiebens/ionscale/internal/key"
"github.com/muesli/coral"
"github.com/spf13/cobra"
)
func keyCommand() *coral.Command {
command := &coral.Command{
func keyCommand() *cobra.Command {
command := &cobra.Command{
Use: "genkey",
SilenceUsage: true,
}
@@ -16,7 +16,7 @@ func keyCommand() *coral.Command {
command.Flags().BoolVarP(&disableNewLine, "no-newline", "n", false, "do not output a trailing newline")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
serverKey := key.NewServerKey()
if disableNewLine {
fmt.Print(serverKey.String())
+39 -39
View File
@@ -5,17 +5,17 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/nleeper/goment"
"github.com/rodaine/table"
"github.com/spf13/cobra"
"inet.af/netaddr"
"os"
"strings"
"text/tabwriter"
)
func machineCommands() *coral.Command {
command := &coral.Command{
func machineCommands() *cobra.Command {
command := &cobra.Command{
Use: "machines",
Aliases: []string{"machine"},
Short: "Manage ionscale machines",
@@ -38,8 +38,8 @@ func machineCommands() *coral.Command {
return command
}
func getMachineCommand() *coral.Command {
command := &coral.Command{
func getMachineCommand() *cobra.Command {
command := &cobra.Command{
Use: "get",
Short: "Retrieve detailed information for a machine",
SilenceUsage: true,
@@ -52,7 +52,7 @@ func getMachineCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -150,8 +150,8 @@ func getMachineCommand() *coral.Command {
return command
}
func deleteMachineCommand() *coral.Command {
command := &coral.Command{
func deleteMachineCommand() *cobra.Command {
command := &cobra.Command{
Use: "delete",
Short: "Deletes a machine",
SilenceUsage: true,
@@ -164,7 +164,7 @@ func deleteMachineCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -183,8 +183,8 @@ func deleteMachineCommand() *coral.Command {
return command
}
func expireMachineCommand() *coral.Command {
command := &coral.Command{
func expireMachineCommand() *cobra.Command {
command := &cobra.Command{
Use: "expire",
Short: "Expires a machine",
SilenceUsage: true,
@@ -197,7 +197,7 @@ func expireMachineCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -216,8 +216,8 @@ func expireMachineCommand() *coral.Command {
return command
}
func authorizeMachineCommand() *coral.Command {
command := &coral.Command{
func authorizeMachineCommand() *cobra.Command {
command := &cobra.Command{
Use: "authorize",
Short: "Authorizes a machine",
SilenceUsage: true,
@@ -230,7 +230,7 @@ func authorizeMachineCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -249,8 +249,8 @@ func authorizeMachineCommand() *coral.Command {
return command
}
func listMachinesCommand() *coral.Command {
command := &coral.Command{
func listMachinesCommand() *cobra.Command {
command := &cobra.Command{
Use: "list",
Short: "List machines",
SilenceUsage: true,
@@ -265,7 +265,7 @@ func listMachinesCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -304,8 +304,8 @@ func listMachinesCommand() *coral.Command {
return command
}
func getMachineRoutesCommand() *coral.Command {
command := &coral.Command{
func getMachineRoutesCommand() *cobra.Command {
command := &cobra.Command{
Use: "get-routes",
Short: "Show routes advertised and enabled by a given machine",
SilenceUsage: true,
@@ -318,7 +318,7 @@ func getMachineRoutesCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
grpcClient, err := target.createGRPCClient()
if err != nil {
return err
@@ -338,8 +338,8 @@ func getMachineRoutesCommand() *coral.Command {
return command
}
func enableMachineRoutesCommand() *coral.Command {
command := &coral.Command{
func enableMachineRoutesCommand() *cobra.Command {
command := &cobra.Command{
Use: "enable-routes",
Short: "Enable routes for a given machine",
SilenceUsage: true,
@@ -356,7 +356,7 @@ func enableMachineRoutesCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -382,8 +382,8 @@ func enableMachineRoutesCommand() *coral.Command {
return command
}
func disableMachineRoutesCommand() *coral.Command {
command := &coral.Command{
func disableMachineRoutesCommand() *cobra.Command {
command := &cobra.Command{
Use: "disable-routes",
Short: "Disable routes for a given machine",
SilenceUsage: true,
@@ -398,7 +398,7 @@ func disableMachineRoutesCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -424,8 +424,8 @@ func disableMachineRoutesCommand() *coral.Command {
return command
}
func enableExitNodeCommand() *coral.Command {
command := &coral.Command{
func enableExitNodeCommand() *cobra.Command {
command := &cobra.Command{
Use: "enable-exit-node",
Short: "Enable given machine as an exit node",
SilenceUsage: true,
@@ -438,7 +438,7 @@ func enableExitNodeCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -458,8 +458,8 @@ func enableExitNodeCommand() *coral.Command {
return command
}
func disableExitNodeCommand() *coral.Command {
command := &coral.Command{
func disableExitNodeCommand() *cobra.Command {
command := &cobra.Command{
Use: "disable-exit-node",
Short: "Disable given machine as an exit node",
SilenceUsage: true,
@@ -472,7 +472,7 @@ func disableExitNodeCommand() *coral.Command {
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -492,8 +492,8 @@ func disableExitNodeCommand() *coral.Command {
return command
}
func enableMachineKeyExpiryCommand() *coral.Command {
command := &coral.Command{
func enableMachineKeyExpiryCommand() *cobra.Command {
command := &cobra.Command{
Use: "enable-key-expiry",
Short: "Enable machine key expiry",
SilenceUsage: true,
@@ -502,8 +502,8 @@ func enableMachineKeyExpiryCommand() *coral.Command {
return configureSetMachineKeyExpiryCommand(command, false)
}
func disableMachineKeyExpiryCommand() *coral.Command {
command := &coral.Command{
func disableMachineKeyExpiryCommand() *cobra.Command {
command := &cobra.Command{
Use: "disable-key-expiry",
Short: "Disable machine key expiry",
SilenceUsage: true,
@@ -512,7 +512,7 @@ func disableMachineKeyExpiryCommand() *coral.Command {
return configureSetMachineKeyExpiryCommand(command, true)
}
func configureSetMachineKeyExpiryCommand(command *coral.Command, v bool) *coral.Command {
func configureSetMachineKeyExpiryCommand(command *cobra.Command, v bool) *cobra.Command {
var machineID uint64
var target = Target{}
target.prepareCommand(command)
@@ -520,7 +520,7 @@ func configureSetMachineKeyExpiryCommand(command *coral.Command, v bool) *coral.
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
+4 -4
View File
@@ -1,10 +1,10 @@
package cmd
import (
"github.com/muesli/coral"
"github.com/spf13/cobra"
)
func Command() *coral.Command {
func Command() *cobra.Command {
rootCmd := rootCommand()
rootCmd.AddCommand(configureCommand())
rootCmd.AddCommand(keyCommand())
@@ -24,8 +24,8 @@ func Execute() error {
return Command().Execute()
}
func rootCommand() *coral.Command {
return &coral.Command{
func rootCommand() *cobra.Command {
return &cobra.Command{
Use: "ionscale",
}
}
+8 -7
View File
@@ -3,21 +3,22 @@ package cmd
import (
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/server"
"github.com/muesli/coral"
"github.com/spf13/cobra"
)
func serverCommand() *coral.Command {
command := &coral.Command{
Use: "server",
Short: "Start an ionscale server",
SilenceUsage: true,
func serverCommand() *cobra.Command {
command := &cobra.Command{
Use: "server",
Short: "Start an ionscale server",
SilenceUsage: true,
SilenceErrors: true,
}
var configFile string
command.Flags().StringVarP(&configFile, "config", "c", "", "Path to the configuration file.")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
c, err := config.LoadConfig(configFile)
if err != nil {
+55 -50
View File
@@ -6,17 +6,18 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
idomain "github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/pkg/defaults"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/rodaine/table"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"os"
"strings"
"tailscale.com/tailcfg"
)
func tailnetCommand() *coral.Command {
command := &coral.Command{
func tailnetCommand() *cobra.Command {
command := &cobra.Command{
Use: "tailnets",
Aliases: []string{"tailnet"},
Short: "Manage ionscale tailnets",
@@ -48,8 +49,8 @@ func tailnetCommand() *coral.Command {
return command
}
func listTailnetsCommand() *coral.Command {
command := &coral.Command{
func listTailnetsCommand() *cobra.Command {
command := &cobra.Command{
Use: "list",
Short: "List available Tailnets",
SilenceUsage: true,
@@ -58,7 +59,7 @@ func listTailnetsCommand() *coral.Command {
var target = Target{}
target.prepareCommand(command)
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
@@ -83,8 +84,8 @@ func listTailnetsCommand() *coral.Command {
return command
}
func createTailnetsCommand() *coral.Command {
command := &coral.Command{
func createTailnetsCommand() *cobra.Command {
command := &cobra.Command{
Use: "create",
Short: "Create a new Tailnet",
SilenceUsage: true,
@@ -100,7 +101,7 @@ func createTailnetsCommand() *coral.Command {
command.Flags().StringVar(&domain, "domain", "", "")
command.Flags().StringVar(&email, "email", "", "")
command.PreRunE = func(cmd *coral.Command, args []string) error {
command.PreRunE = func(cmd *cobra.Command, args []string) error {
if name == "" {
return fmt.Errorf("flag --name is required")
}
@@ -110,20 +111,22 @@ func createTailnetsCommand() *coral.Command {
return nil
}
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
var iamPolicy = api.IAMPolicy{}
dnsConfig := defaults.DefaultDNSConfig()
aclPolicy := defaults.DefaultACLPolicy()
iamPolicy := &api.IAMPolicy{}
if len(domain) != 0 {
domainToLower := strings.ToLower(domain)
iamPolicy = api.IAMPolicy{
iamPolicy = &api.IAMPolicy{
Filters: []string{fmt.Sprintf("domain == %s", domainToLower)},
}
}
if len(email) != 0 {
emailToLower := strings.ToLower(email)
iamPolicy = api.IAMPolicy{
iamPolicy = &api.IAMPolicy{
Emails: []string{emailToLower},
Roles: map[string]string{
emailToLower: string(idomain.UserRoleAdmin),
@@ -138,7 +141,9 @@ func createTailnetsCommand() *coral.Command {
resp, err := client.CreateTailnet(context.Background(), connect.NewRequest(&api.CreateTailnetRequest{
Name: name,
IamPolicy: &iamPolicy,
IamPolicy: iamPolicy,
AclPolicy: aclPolicy,
DnsConfig: dnsConfig,
}))
if err != nil {
@@ -155,8 +160,8 @@ func createTailnetsCommand() *coral.Command {
return command
}
func deleteTailnetCommand() *coral.Command {
command := &coral.Command{
func deleteTailnetCommand() *cobra.Command {
command := &cobra.Command{
Use: "delete",
Short: "Delete a tailnet",
SilenceUsage: true,
@@ -173,7 +178,7 @@ func deleteTailnetCommand() *coral.Command {
command.Flags().BoolVar(&force, "force", false, "When enabled, force delete the specified Tailnet even when machines are still available.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
@@ -199,8 +204,8 @@ func deleteTailnetCommand() *coral.Command {
return command
}
func getDERPMap() *coral.Command {
command := &coral.Command{
func getDERPMap() *cobra.Command {
command := &cobra.Command{
Use: "get-derp-map",
Short: "Get the DERP Map configuration",
SilenceUsage: true,
@@ -218,7 +223,7 @@ func getDERPMap() *coral.Command {
command.Flags().BoolVar(&asJson, "json", false, "When enabled, render output as json otherwise yaml")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -265,8 +270,8 @@ func getDERPMap() *coral.Command {
return command
}
func setDERPMap() *coral.Command {
command := &coral.Command{
func setDERPMap() *cobra.Command {
command := &cobra.Command{
Use: "set-derp-map",
Short: "Set the DERP Map configuration",
SilenceUsage: true,
@@ -283,7 +288,7 @@ func setDERPMap() *coral.Command {
command.Flags().StringVar(&file, "file", "", "Path to json file with the DERP Map configuration")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -317,8 +322,8 @@ func setDERPMap() *coral.Command {
return command
}
func resetDERPMap() *coral.Command {
command := &coral.Command{
func resetDERPMap() *cobra.Command {
command := &cobra.Command{
Use: "reset-derp-map",
Short: "Reset the DERP Map to the default configuration",
SilenceUsage: true,
@@ -333,7 +338,7 @@ func resetDERPMap() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -356,8 +361,8 @@ func resetDERPMap() *coral.Command {
return command
}
func enableFileSharingCommand() *coral.Command {
command := &coral.Command{
func enableFileSharingCommand() *cobra.Command {
command := &cobra.Command{
Use: "enable-file-sharing",
Aliases: []string{"enable-taildrop"},
Short: "Enable Taildrop, the file sharing feature",
@@ -373,7 +378,7 @@ func enableFileSharingCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -398,8 +403,8 @@ func enableFileSharingCommand() *coral.Command {
return command
}
func disableFileSharingCommand() *coral.Command {
command := &coral.Command{
func disableFileSharingCommand() *cobra.Command {
command := &cobra.Command{
Use: "disable-file-sharing",
Aliases: []string{"disable-taildrop"},
Short: "Disable Taildrop, the file sharing feature",
@@ -415,7 +420,7 @@ func disableFileSharingCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -440,8 +445,8 @@ func disableFileSharingCommand() *coral.Command {
return command
}
func enableServiceCollectionCommand() *coral.Command {
command := &coral.Command{
func enableServiceCollectionCommand() *cobra.Command {
command := &cobra.Command{
Use: "enable-service-collection",
Short: "Enable monitoring live services running on your networks machines.",
SilenceUsage: true,
@@ -456,7 +461,7 @@ func enableServiceCollectionCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -481,8 +486,8 @@ func enableServiceCollectionCommand() *coral.Command {
return command
}
func disableServiceCollectionCommand() *coral.Command {
command := &coral.Command{
func disableServiceCollectionCommand() *cobra.Command {
command := &cobra.Command{
Use: "disable-service-collection",
Short: "Disable monitoring live services running on your networks machines.",
SilenceUsage: true,
@@ -497,7 +502,7 @@ func disableServiceCollectionCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -522,8 +527,8 @@ func disableServiceCollectionCommand() *coral.Command {
return command
}
func enableSSHCommand() *coral.Command {
command := &coral.Command{
func enableSSHCommand() *cobra.Command {
command := &cobra.Command{
Use: "enable-ssh",
Short: "Enable ssh access using tailnet and ACLs.",
SilenceUsage: true,
@@ -538,7 +543,7 @@ func enableSSHCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -563,8 +568,8 @@ func enableSSHCommand() *coral.Command {
return command
}
func disableSSHCommand() *coral.Command {
command := &coral.Command{
func disableSSHCommand() *cobra.Command {
command := &cobra.Command{
Use: "disable-ssh",
Short: "Disable ssh access using tailnet and ACLs.",
SilenceUsage: true,
@@ -579,7 +584,7 @@ func disableSSHCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -604,8 +609,8 @@ func disableSSHCommand() *coral.Command {
return command
}
func enableMachineAuthorizationCommand() *coral.Command {
command := &coral.Command{
func enableMachineAuthorizationCommand() *cobra.Command {
command := &cobra.Command{
Use: "enable-machine-authorization",
Short: "Enable machine authorization.",
SilenceUsage: true,
@@ -620,7 +625,7 @@ func enableMachineAuthorizationCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -645,8 +650,8 @@ func enableMachineAuthorizationCommand() *coral.Command {
return command
}
func disableMachineAuthorizationCommand() *coral.Command {
command := &coral.Command{
func disableMachineAuthorizationCommand() *cobra.Command {
command := &cobra.Command{
Use: "disable-machine-authorization",
Short: "Disable machine authorization.",
SilenceUsage: true,
@@ -661,7 +666,7 @@ func disableMachineAuthorizationCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/pkg/client/ionscale"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1/ionscalev1connect"
"github.com/muesli/coral"
"github.com/spf13/cobra"
)
const (
@@ -19,7 +19,7 @@ type Target struct {
systemAdminKey string
}
func (t *Target) prepareCommand(cmd *coral.Command) {
func (t *Target) prepareCommand(cmd *cobra.Command) {
cmd.Flags().StringVar(&t.addr, "addr", "", "Addr of the ionscale server, as a complete URL")
cmd.Flags().BoolVar(&t.insecureSkipVerify, "tls-skip-verify", false, "Disable verification of TLS certificates")
cmd.Flags().StringVar(&t.systemAdminKey, "system-admin-key", "", "If specified, the given value will be used as the key to generate a Bearer token for the call. This can also be specified via the IONSCALE_ADMIN_KEY environment variable.")
+9 -9
View File
@@ -5,12 +5,12 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/rodaine/table"
"github.com/spf13/cobra"
)
func userCommands() *coral.Command {
command := &coral.Command{
func userCommands() *cobra.Command {
command := &cobra.Command{
Use: "users",
Aliases: []string{"user"},
Short: "Manage ionscale users",
@@ -23,8 +23,8 @@ func userCommands() *coral.Command {
return command
}
func listUsersCommand() *coral.Command {
command := &coral.Command{
func listUsersCommand() *cobra.Command {
command := &cobra.Command{
Use: "list",
Short: "List users",
SilenceUsage: true,
@@ -39,7 +39,7 @@ func listUsersCommand() *coral.Command {
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
@@ -69,8 +69,8 @@ func listUsersCommand() *coral.Command {
return command
}
func deleteUserCommand() *coral.Command {
command := &coral.Command{
func deleteUserCommand() *cobra.Command {
command := &cobra.Command{
Use: "delete",
Short: "Deletes a user",
SilenceUsage: true,
@@ -83,7 +83,7 @@ func deleteUserCommand() *coral.Command {
_ = command.MarkFlagRequired("user-id")
command.RunE = func(command *coral.Command, args []string) error {
command.RunE = func(command *cobra.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
+4 -4
View File
@@ -6,11 +6,11 @@ import (
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/version"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/spf13/cobra"
)
func versionCommand() *coral.Command {
var command = &coral.Command{
func versionCommand() *cobra.Command {
var command = &cobra.Command{
Use: "version",
Short: "Display version information",
SilenceUsage: true,
@@ -19,7 +19,7 @@ func versionCommand() *coral.Command {
var target = Target{}
target.prepareCommand(command)
command.Run = func(cmd *coral.Command, args []string) {
command.Run = func(cmd *cobra.Command, args []string) {
clientVersion, clientRevision := version.GetReleaseInfo()
fmt.Printf(`
Client:
+11 -5
View File
@@ -67,7 +67,7 @@ func LoadConfig(path string) (*Config, error) {
envCfgB64 := os.Getenv("IONSCALE_CONFIG_BASE64")
if len(envCfgB64) != 0 {
b, err := base64.RawStdEncoding.DecodeString(envCfgB64)
b, err := base64.StdEncoding.DecodeString(envCfgB64)
if err != nil {
return nil, err
}
@@ -105,8 +105,10 @@ func defaultConfig() *Config {
MetricsListenAddr: ":9091",
ServerUrl: "https://localhost:8843",
Database: Database{
Type: "sqlite",
Url: "./ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)",
Type: "sqlite",
Url: "./ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)",
MaxOpenConns: 0,
MaxIdleConns: 2,
},
Tls: Tls{
Disable: false,
@@ -169,8 +171,12 @@ type Logging struct {
}
type Database struct {
Type string `yaml:"type,omitempty" env:"TYPE"`
Url string `yaml:"url,omitempty" env:"URL"`
Type string `yaml:"type,omitempty" env:"TYPE"`
Url string `yaml:"url,omitempty" env:"URL"`
MaxOpenConns int `yaml:"max_open_conns,omitempty" env:"MAX_OPEN_CONNS"`
MaxIdleConns int `yaml:"max_idle_conns,omitempty" env:"MAX_IDLE_CONNS"`
ConnMaxLifetime time.Duration `yaml:"conn_max_life_time,omitempty" env:"CONN_MAX_LIFE_TIME"`
ConnMaxIdleTime time.Duration `yaml:"conn_max_idle_time,omitempty" env:"CONN_MAX_IDLE_TIME"`
}
type Keys struct {
+31 -20
View File
@@ -5,9 +5,9 @@ import (
"errors"
"fmt"
"github.com/go-gormigrate/gormigrate/v2"
"github.com/hashicorp/go-hclog"
"github.com/jsiebens/ionscale/internal/database/migration"
"github.com/jsiebens/ionscale/internal/util"
"go.uber.org/zap"
"tailscale.com/types/key"
"time"
@@ -15,37 +15,48 @@ import (
"github.com/jsiebens/ionscale/internal/domain"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/plugin/prometheus"
)
type db interface {
DB() *gorm.DB
type dbLock interface {
Lock() error
Unlock() error
UnlockErr(error) error
}
func OpenDB(config *config.Database, logger hclog.Logger) (domain.Repository, error) {
db, err := createDB(config, logger)
func OpenDB(config *config.Database, logger *zap.Logger) (domain.Repository, error) {
db, lock, err := createDB(config, logger)
if err != nil {
return nil, err
}
repository := domain.NewRepository(db.DB())
_ = db.Use(prometheus.New(prometheus.Config{StartServer: false}))
if err := db.Lock(); err != nil {
sqlDB, err := db.DB()
if err != nil {
return nil, err
}
if err := db.UnlockErr(migrate(db.DB())); err != nil {
sqlDB.SetMaxOpenConns(config.MaxOpenConns)
sqlDB.SetMaxIdleConns(config.MaxIdleConns)
sqlDB.SetConnMaxLifetime(config.ConnMaxLifetime)
sqlDB.SetConnMaxIdleTime(config.ConnMaxIdleTime)
repository := domain.NewRepository(db)
if err := lock.Lock(); err != nil {
return nil, err
}
if err := lock.UnlockErr(migrate(db)); err != nil {
return nil, err
}
return repository, nil
}
func createDB(config *config.Database, logger hclog.Logger) (db, error) {
func createDB(config *config.Database, logger *zap.Logger) (*gorm.DB, dbLock, error) {
gormConfig := &gorm.Config{
Logger: &GormLoggerAdapter{logger: logger.Named("db")},
Logger: &GormLoggerAdapter{logger: logger.Sugar()},
}
switch config.Type {
@@ -55,7 +66,7 @@ func createDB(config *config.Database, logger hclog.Logger) (db, error) {
return newPostgresDB(config, gormConfig)
}
return nil, fmt.Errorf("invalid database type '%s'", config.Type)
return nil, nil, fmt.Errorf("invalid database type '%s'", config.Type)
}
func migrate(db *gorm.DB) error {
@@ -123,7 +134,7 @@ func createJSONWebKeySet(ctx context.Context, repository domain.Repository) erro
}
type GormLoggerAdapter struct {
logger hclog.Logger
logger *zap.SugaredLogger
}
func (g *GormLoggerAdapter) LogMode(level logger.LogLevel) logger.Interface {
@@ -131,11 +142,11 @@ func (g *GormLoggerAdapter) LogMode(level logger.LogLevel) logger.Interface {
}
func (g *GormLoggerAdapter) Info(ctx context.Context, s string, i ...interface{}) {
g.logger.Info(s, i)
g.logger.Infow(s, i)
}
func (g *GormLoggerAdapter) Warn(ctx context.Context, s string, i ...interface{}) {
g.logger.Warn(s, i)
g.logger.Warnw(s, i)
}
func (g *GormLoggerAdapter) Error(ctx context.Context, s string, i ...interface{}) {
@@ -143,22 +154,22 @@ func (g *GormLoggerAdapter) Error(ctx context.Context, s string, i ...interface{
}
func (g *GormLoggerAdapter) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
if g.logger.IsTrace() {
if g.logger.Level().Enabled(zap.DebugLevel) {
elapsed := time.Since(begin)
switch {
case err != nil && !errors.Is(err, gorm.ErrRecordNotFound):
sql, rows := fc()
if rows == -1 {
g.logger.Trace("Error executing query", "sql", sql, "start_time", begin.Format(time.RFC3339), "duration", elapsed, "err", err)
g.logger.Debugw("Error executing query", "sql", sql, "start_time", begin.Format(time.RFC3339), "duration", elapsed, "err", err)
} else {
g.logger.Trace("Error executing query", "sql", sql, "start_time", begin.Format(time.RFC3339), "duration", elapsed, "rows", rows, "err", err)
g.logger.Debugw("Error executing query", "sql", sql, "start_time", begin.Format(time.RFC3339), "duration", elapsed, "rows", rows, "err", err)
}
default:
sql, rows := fc()
if rows == -1 {
g.logger.Trace("Statement executed", "sql", sql, "start_time", begin.Format(time.RFC3339), "duration", elapsed)
g.logger.Debugw("Statement executed", "sql", sql, "start_time", begin.Format(time.RFC3339), "duration", elapsed)
} else {
g.logger.Trace("Statement executed", "sql", sql, "start_time", begin.Format(time.RFC3339), "duration", elapsed, "rows", rows)
g.logger.Debugw("Statement executed", "sql", sql, "start_time", begin.Format(time.RFC3339), "duration", elapsed, "rows", rows)
}
}
}
@@ -0,0 +1,32 @@
package migration
import (
"github.com/go-gormigrate/gormigrate/v2"
"github.com/jsiebens/ionscale/internal/domain"
"gorm.io/gorm"
)
func m202212270800_machine_indeces() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202212270800",
Migrate: func(db *gorm.DB) error {
type Machine struct {
ID uint64 `gorm:"primaryKey;autoIncrement:false;index:idx_tailnet_id_id,priority:2"`
MachineKey string `gorm:"index:idx_machine_keys"`
NodeKey string `gorm:"index:idx_machine_keys"`
Name string `gorm:"index:idx_tailnet_id_name,priority:2"`
NameIdx uint64 `gorm:"index:idx_tailnet_id_name,sort:desc,priority:3"`
TailnetID uint64 `gorm:"index:idx_tailnet_id_id,priority:1;index:idx_tailnet_id_name,priority:1"`
IPv4 domain.IP `gorm:"index:idx_ipv4"`
}
return db.AutoMigrate(
&Machine{},
)
},
Rollback: nil,
}
}
@@ -15,6 +15,7 @@ func Migrations() []*gormigrate.Migration {
m202210080700_ssh_action_request(),
m202211031100_add_authorized_column(),
m202212201300_add_user_id_column(),
m202212270800_machine_indeces(),
}
return migrations
}
+14 -20
View File
@@ -11,26 +11,20 @@ import (
"gorm.io/gorm"
)
func newPostgresDB(config *config.Database, g *gorm.Config) (db, error) {
func newPostgresDB(config *config.Database, g *gorm.Config) (*gorm.DB, dbLock, error) {
db, err := gorm.Open(postgres.Open(config.Url), g)
if err != nil {
return nil, err
return nil, nil, err
}
return &Postgres{
db: db,
}, nil
return db, &pgLock{db: db}, nil
}
type Postgres struct {
type pgLock struct {
db *gorm.DB
}
func (s *Postgres) DB() *gorm.DB {
return s.db
}
func (s *Postgres) Lock() error {
func (s *pgLock) Lock() error {
d, _ := s.db.DB()
query := `SELECT pg_advisory_lock($1)`
@@ -42,7 +36,14 @@ func (s *Postgres) Lock() error {
return nil
}
func (s *Postgres) Unlock() error {
func (s *pgLock) UnlockErr(prevErr error) error {
if err := s.unlock(); err != nil {
return multierror.Append(prevErr, err)
}
return prevErr
}
func (s *pgLock) unlock() error {
d, _ := s.db.DB()
query := `SELECT pg_advisory_unlock($1)`
@@ -53,16 +54,9 @@ func (s *Postgres) Unlock() error {
return nil
}
func (s *Postgres) UnlockErr(prevErr error) error {
if err := s.Unlock(); err != nil {
return multierror.Append(prevErr, err)
}
return prevErr
}
const advisoryLockIDSalt uint = 1486364155
func (s *Postgres) generateAdvisoryLockId() string {
func (s *pgLock) generateAdvisoryLockId() string {
sum := crc32.ChecksumIEEE([]byte("ionscale_migration"))
sum = sum * uint32(advisoryLockIDSalt)
return fmt.Sprint(sum)
+6 -18
View File
@@ -6,33 +6,21 @@ import (
"gorm.io/gorm"
)
func newSqliteDB(config *config.Database, g *gorm.Config) (db, error) {
func newSqliteDB(config *config.Database, g *gorm.Config) (*gorm.DB, dbLock, error) {
db, err := gorm.Open(sqlite.Open(config.Url), g)
if err != nil {
return nil, err
return nil, nil, err
}
return &Sqlite{
db: db,
}, nil
return db, &sqliteLock{}, nil
}
type Sqlite struct {
db *gorm.DB
type sqliteLock struct {
}
func (s *Sqlite) DB() *gorm.DB {
return s.db
}
func (s *Sqlite) Lock() error {
func (s *sqliteLock) Lock() error {
return nil
}
func (s *Sqlite) Unlock() error {
return nil
}
func (s *Sqlite) UnlockErr(prevErr error) error {
func (s *sqliteLock) UnlockErr(prevErr error) error {
return prevErr
}
+7 -7
View File
@@ -21,17 +21,17 @@ const (
)
type AutoApprovers struct {
Routes map[string][]string `json:"routes"`
ExitNode []string `json:"exitNode"`
Routes map[string][]string `json:"routes,omitempty"`
ExitNode []string `json:"exitNode,omitempty"`
}
type ACLPolicy struct {
Groups map[string][]string `json:"groups,omitempty"`
Hosts map[string]string `json:"hosts,omitempty"`
ACLs []ACL `json:"acls"`
TagOwners map[string][]string `json:"tagowners"`
AutoApprovers *AutoApprovers `json:"autoApprovers"`
SSHRules []SSHRule `json:"ssh"`
ACLs []ACL `json:"acls,omitempty"`
TagOwners map[string][]string `json:"tagowners,omitempty"`
AutoApprovers *AutoApprovers `json:"autoApprovers,omitempty"`
SSHRules []SSHRule `json:"ssh,omitempty"`
}
type ACL struct {
@@ -47,7 +47,7 @@ type SSHRule struct {
Users []string `json:"users"`
}
func DefaultPolicy() ACLPolicy {
func DefaultACLPolicy() ACLPolicy {
return ACLPolicy{
ACLs: []ACL{
{
+1 -1
View File
@@ -65,7 +65,7 @@ func (r *repository) LoadApiKey(ctx context.Context, key string) (*ApiKey, error
}
var m ApiKey
tx := r.withContext(ctx).Preload("User").Preload("Tailnet").First(&m, "key = ?", split[0])
tx := r.withContext(ctx).Preload("User").Preload("Tailnet").Take(&m, "key = ?", split[0])
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
+1 -1
View File
@@ -136,7 +136,7 @@ func (r *repository) LoadAuthKey(ctx context.Context, key string) (*AuthKey, err
}
var m AuthKey
tx := r.withContext(ctx).Preload("User").Preload("Tailnet").First(&m, "key = ?", split[0])
tx := r.withContext(ctx).Preload("User").Preload("Tailnet").Take(&m, "key = ?", split[0])
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
+1 -1
View File
@@ -27,7 +27,7 @@ func (r *repository) SaveAuthenticationRequest(ctx context.Context, session *Aut
func (r *repository) GetAuthenticationRequest(ctx context.Context, key string) (*AuthenticationRequest, error) {
var m AuthenticationRequest
tx := r.withContext(ctx).First(&m, "key = ?", key)
tx := r.withContext(ctx).Take(&m, "key = ?", key)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
+4
View File
@@ -11,6 +11,10 @@ import (
"gorm.io/gorm/schema"
)
func DefaultIAMPolicy() IAMPolicy {
return IAMPolicy{}
}
type Identity struct {
UserID string
Username string
+4 -4
View File
@@ -357,7 +357,7 @@ func (r *repository) DeleteMachine(ctx context.Context, id uint64) (bool, error)
func (r *repository) GetMachine(ctx context.Context, machineID uint64) (*Machine, error) {
var m Machine
tx := r.withContext(ctx).Preload("Tailnet").Preload("User").First(&m, "id = ?", machineID)
tx := r.withContext(ctx).Preload("Tailnet").Preload("User").Take(&m, machineID)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
@@ -376,7 +376,7 @@ func (r *repository) GetNextMachineNameIndex(ctx context.Context, tailnetID uint
tx := r.withContext(ctx).
Where("name = ? AND tailnet_id = ?", name, tailnetID).
Order("name_idx desc").
First(&m)
Take(&m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return 0, nil
@@ -391,7 +391,7 @@ func (r *repository) GetNextMachineNameIndex(ctx context.Context, tailnetID uint
func (r *repository) GetMachineByKey(ctx context.Context, tailnetID uint64, machineKey string) (*Machine, error) {
var m Machine
tx := r.withContext(ctx).Preload("Tailnet").Preload("User").First(&m, "tailnet_id = ? AND machine_key = ?", tailnetID, machineKey)
tx := r.withContext(ctx).Preload("Tailnet").Preload("User").Take(&m, "tailnet_id = ? AND machine_key = ?", tailnetID, machineKey)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
@@ -406,7 +406,7 @@ func (r *repository) GetMachineByKey(ctx context.Context, tailnetID uint64, mach
func (r *repository) GetMachineByKeys(ctx context.Context, machineKey string, nodeKey string) (*Machine, error) {
var m Machine
tx := r.withContext(ctx).Preload("Tailnet").Preload("User").First(&m, "machine_key = ? AND node_key = ?", machineKey, nodeKey)
tx := r.withContext(ctx).Preload("Tailnet").Preload("User").Take(&m, "machine_key = ? AND node_key = ?", machineKey, nodeKey)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
+2 -6
View File
@@ -22,10 +22,6 @@ type RegistrationRequest struct {
UserID uint64
}
func (r *RegistrationRequest) IsFinished() bool {
return r.Authenticated || len(r.Error) != 0
}
type RegistrationRequestData tailcfg.RegisterRequest
func (hi *RegistrationRequestData) Scan(destination interface{}) error {
@@ -68,7 +64,7 @@ func (r *repository) SaveRegistrationRequest(ctx context.Context, request *Regis
func (r *repository) GetRegistrationRequestByKey(ctx context.Context, key string) (*RegistrationRequest, error) {
var m RegistrationRequest
tx := r.withContext(ctx).First(&m, "key = ?", key)
tx := r.withContext(ctx).Take(&m, "key = ?", key)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
@@ -83,7 +79,7 @@ func (r *repository) GetRegistrationRequestByKey(ctx context.Context, key string
func (r *repository) GetRegistrationRequestByMachineKey(ctx context.Context, key string) (*RegistrationRequest, error) {
var m RegistrationRequest
tx := r.withContext(ctx).First(&m, "machine_key = ?", key)
tx := r.withContext(ctx).Take(&m, "machine_key = ?", key)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
-1
View File
@@ -25,7 +25,6 @@ type Repository interface {
GetOrCreateAccount(ctx context.Context, externalID, loginName string) (*Account, bool, error)
SaveTailnet(ctx context.Context, tailnet *Tailnet) error
GetOrCreateTailnet(ctx context.Context, name string, iamPolicy IAMPolicy) (*Tailnet, bool, error)
GetTailnet(ctx context.Context, id uint64) (*Tailnet, error)
GetTailnetByAlias(ctx context.Context, alias string) (*Tailnet, error)
ListTailnets(ctx context.Context) ([]Tailnet, error)
+1 -1
View File
@@ -27,7 +27,7 @@ func (r *repository) SaveSSHActionRequest(ctx context.Context, session *SSHActio
func (r *repository) GetSSHActionRequest(ctx context.Context, key string) (*SSHActionRequest, error) {
var m SSHActionRequest
tx := r.withContext(ctx).First(&m, "key = ?", key)
tx := r.withContext(ctx).Take(&m, "key = ?", key)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
+1 -1
View File
@@ -69,7 +69,7 @@ func (r *repository) LoadSystemApiKey(ctx context.Context, token string) (*Syste
}
var m SystemApiKey
tx := r.withContext(ctx).Preload("Account").First(&m, "key = ?", key)
tx := r.withContext(ctx).Preload("Account").Take(&m, "key = ?", key)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
-17
View File
@@ -3,7 +3,6 @@ package domain
import (
"context"
"errors"
"github.com/jsiebens/ionscale/internal/util"
"gorm.io/gorm"
"net/mail"
"strings"
@@ -58,22 +57,6 @@ func (r *repository) SaveTailnet(ctx context.Context, tailnet *Tailnet) error {
return nil
}
func (r *repository) GetOrCreateTailnet(ctx context.Context, name string, iamPolicy IAMPolicy) (*Tailnet, bool, error) {
tailnet := &Tailnet{}
id := util.NextID()
tx := r.withContext(ctx).
Where(Tailnet{Name: name}).
Attrs(Tailnet{ID: id, ACLPolicy: DefaultPolicy(), IAMPolicy: iamPolicy}).
FirstOrCreate(tailnet)
if tx.Error != nil {
return nil, false, tx.Error
}
return tailnet, tailnet.ID == id, nil
}
func (r *repository) GetTailnet(ctx context.Context, id uint64) (*Tailnet, error) {
var t Tailnet
tx := r.withContext(ctx).Take(&t, "id = ?", id)
+1 -1
View File
@@ -100,7 +100,7 @@ func (r *repository) GetOrCreateUserWithAccount(ctx context.Context, tailnet *Ta
func (r *repository) GetUser(ctx context.Context, userID uint64) (*User, error) {
var m User
tx := r.withContext(ctx).Preload("Tailnet").Preload("Account").First(&m, "id = ?", userID)
tx := r.withContext(ctx).Preload("Tailnet").Preload("Account").Take(&m, "id = ?", userID)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
-42
View File
@@ -1,42 +0,0 @@
package errors
import (
"fmt"
"runtime"
)
type Error struct {
Cause error
Location string
}
func Wrap(err error, skip int) error {
if err == nil {
return nil
}
c := &Error{
Cause: err,
Location: getLocation(skip),
}
return c
}
func (w *Error) Error() string {
return w.Cause.Error()
}
func (f *Error) Unwrap() error {
return f.Cause
}
func (f *Error) Format(s fmt.State, verb rune) {
fmt.Fprintf(s, "%s\n", f.Cause.Error())
fmt.Fprintf(s, "\t%s\n", f.Location)
}
func getLocation(skip int) string {
_, file, line, _ := runtime.Caller(2 + skip)
return fmt.Sprintf("%s:%d", file, line)
}
+36 -37
View File
@@ -6,7 +6,6 @@ import (
"fmt"
"github.com/jsiebens/ionscale/internal/addr"
"github.com/jsiebens/ionscale/internal/auth"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/labstack/echo/v4/middleware"
"github.com/mr-tron/base58"
"net/http"
@@ -66,7 +65,7 @@ func (h *AuthenticationHandlers) StartAuth(c echo.Context) error {
// machine registration auth flow
if flow == "r" || flow == "" {
if req, err := h.repository.GetRegistrationRequestByKey(ctx, key); err != nil || req == nil {
return errors.Wrap(err, 0)
return logError(err)
}
csrf := c.Get(middleware.DefaultCSRFConfig.ContextKey).(string)
@@ -76,24 +75,24 @@ func (h *AuthenticationHandlers) StartAuth(c echo.Context) error {
// cli auth flow
if flow == "c" {
if s, err := h.repository.GetAuthenticationRequest(ctx, key); err != nil || s == nil {
return errors.Wrap(err, 0)
return logError(err)
}
}
// ssh check auth flow
if flow == "s" {
if s, err := h.repository.GetSSHActionRequest(ctx, key); err != nil || s == nil {
return errors.Wrap(err, 0)
return logError(err)
}
}
if h.authProvider == nil {
return errors.Wrap(fmt.Errorf("unable to start auth flow as no auth provider is configured"), 0)
return logError(fmt.Errorf("unable to start auth flow as no auth provider is configured"))
}
state, err := h.createState(flow, key)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
redirectUrl := h.authProvider.GetLoginURL(h.config.CreateUrl("/a/callback"), state)
@@ -110,7 +109,7 @@ func (h *AuthenticationHandlers) ProcessAuth(c echo.Context) error {
req, err := h.repository.GetRegistrationRequestByKey(ctx, key)
if err != nil || req == nil {
return errors.Wrap(err, 0)
return logError(err)
}
if authKey != "" {
@@ -120,7 +119,7 @@ func (h *AuthenticationHandlers) ProcessAuth(c echo.Context) error {
if interactive != "" {
state, err := h.createState("r", key)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
redirectUrl := h.authProvider.GetLoginURL(h.config.CreateUrl("/a/callback"), state)
@@ -142,12 +141,12 @@ func (h *AuthenticationHandlers) Callback(c echo.Context) error {
user, err := h.exchangeUser(code)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
account, _, err := h.repository.GetOrCreateAccount(ctx, user.ID, user.Name)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if state.Flow == "s" {
@@ -158,27 +157,27 @@ func (h *AuthenticationHandlers) Callback(c echo.Context) error {
machine, err := h.repository.GetMachine(ctx, sshActionReq.SrcMachineID)
if err != nil || sshActionReq == nil {
return errors.Wrap(err, 0)
return logError(err)
}
if !machine.HasTags() && machine.User.AccountID != nil && *machine.User.AccountID == account.ID {
sshActionReq.Action = "accept"
if err := h.repository.SaveSSHActionRequest(ctx, sshActionReq); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
return c.Redirect(http.StatusFound, "/a/success")
}
sshActionReq.Action = "reject"
if err := h.repository.SaveSSHActionRequest(ctx, sshActionReq); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
return c.Redirect(http.StatusFound, "/a/error?e=nmo")
}
tailnets, err := h.listAvailableTailnets(ctx, user)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
csrf := c.Get(middleware.DefaultCSRFConfig.ContextKey).(string)
@@ -203,7 +202,7 @@ func (h *AuthenticationHandlers) Callback(c echo.Context) error {
if state.Flow == "c" {
isSystemAdmin, err := h.isSystemAdmin(ctx, user)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if !isSystemAdmin && len(tailnets) == 0 {
@@ -258,7 +257,7 @@ func (h *AuthenticationHandlers) EndOAuth(c echo.Context) error {
if state.Flow == "r" {
req, err := h.repository.GetRegistrationRequestByKey(ctx, state.Key)
if err != nil || req == nil {
return errors.Wrap(err, 0)
return logError(err)
}
return h.endMachineRegistrationFlow(c, req, state)
@@ -266,7 +265,7 @@ func (h *AuthenticationHandlers) EndOAuth(c echo.Context) error {
req, err := h.repository.GetAuthenticationRequest(ctx, state.Key)
if err != nil || req == nil {
return errors.Wrap(err, 0)
return logError(err)
}
return h.endCliAuthenticationFlow(c, req, state)
@@ -308,12 +307,12 @@ func (h *AuthenticationHandlers) endCliAuthenticationFlow(c echo.Context, req *d
var form TailnetSelectionForm
if err := c.Bind(&form); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
account, err := h.repository.GetAccount(ctx, form.AccountID)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
// continue as system admin?
@@ -324,27 +323,27 @@ func (h *AuthenticationHandlers) endCliAuthenticationFlow(c echo.Context, req *d
err := h.repository.Transaction(func(rp domain.Repository) error {
if err := rp.SaveSystemApiKey(ctx, apiKey); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if err := rp.SaveAuthenticationRequest(ctx, req); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
return nil
})
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
return c.Redirect(http.StatusFound, "/a/success")
}
tailnet, err := h.repository.GetTailnet(ctx, form.TailnetID)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
user, _, err := h.repository.GetOrCreateUserWithAccount(ctx, tailnet, account)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
expiresAt := time.Now().Add(24 * time.Hour)
@@ -362,7 +361,7 @@ func (h *AuthenticationHandlers) endCliAuthenticationFlow(c echo.Context, req *d
return nil
})
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
return c.Redirect(http.StatusFound, "/a/success")
@@ -373,7 +372,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
var form TailnetSelectionForm
if err := c.Bind(&form); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
req := tailcfg.RegisterRequest(registrationRequest.Data)
@@ -389,7 +388,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
if form.AuthKey != "" {
authKey, err := h.repository.LoadAuthKey(ctx, form.AuthKey)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if authKey == nil {
@@ -398,7 +397,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
registrationRequest.Error = "invalid auth key"
if err := h.repository.SaveRegistrationRequest(ctx, registrationRequest); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
return c.Redirect(http.StatusFound, "/a/error?e=iak")
@@ -412,17 +411,17 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
} else {
selectedTailnet, err := h.repository.GetTailnet(ctx, form.TailnetID)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
account, err := h.repository.GetAccount(ctx, form.AccountID)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
selectedUser, _, err := h.repository.GetOrCreateUserWithAccount(ctx, selectedTailnet, account)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
user = selectedUser
@@ -434,7 +433,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
registrationRequest.Authenticated = false
registrationRequest.Error = err.Error()
if err := h.repository.SaveRegistrationRequest(ctx, registrationRequest); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
return c.Redirect(http.StatusFound, "/a/error?e=nto")
}
@@ -445,7 +444,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
m, err := h.repository.GetMachineByKey(ctx, tailnet.ID, machineKey)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
now := time.Now().UTC()
@@ -458,7 +457,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
m = &domain.Machine{
@@ -482,7 +481,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
ipv4, ipv6, err := addr.SelectIP(checkIP(ctx, h.repository.CountMachinesWithIPv4))
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
m.IPv4 = domain.IP{Addr: ipv4}
m.IPv6 = domain.IP{Addr: ipv6}
@@ -495,7 +494,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
if m.Name != sanitizeHostname {
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
m.Name = sanitizeHostname
m.NameIdx = nameIdx
@@ -529,7 +528,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
})
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if m.Authorized {
+3 -4
View File
@@ -3,7 +3,6 @@ package handlers
import (
"github.com/jsiebens/ionscale/internal/bind"
"github.com/jsiebens/ionscale/internal/dns"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/labstack/echo/v4"
"net"
"net/http"
@@ -29,12 +28,12 @@ func (h *DNSHandlers) SetDNS(c echo.Context) error {
binder, err := h.createBinder(c)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
req := &tailcfg.SetDNSRequest{}
if err := binder.BindRequest(c, req); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if h.provider == nil {
@@ -42,7 +41,7 @@ func (h *DNSHandlers) SetDNS(c echo.Context) error {
}
if err := h.provider.SetRecord(ctx, req.Type, req.Name, req.Value); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if strings.HasPrefix(req.Name, "_acme-challenge") && req.Type == "TXT" {
+7 -8
View File
@@ -2,14 +2,13 @@ package handlers
import (
"fmt"
"github.com/go-jose/go-jose/v3"
"github.com/golang-jwt/jwt/v4"
"github.com/jsiebens/ionscale/internal/bind"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/util"
"github.com/labstack/echo/v4"
"gopkg.in/square/go-jose.v2"
"net/http"
"tailscale.com/tailcfg"
"time"
@@ -56,7 +55,7 @@ func (h *IDTokenHandlers) OpenIDConfig(c echo.Context) error {
func (h *IDTokenHandlers) Jwks(c echo.Context) error {
keySet, err := h.repository.GetJSONWebKeySet(c.Request().Context())
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
pub := jose.JSONWebKey{Key: keySet.Key.Public(), KeyID: keySet.Key.Id, Algorithm: "RS256", Use: "sig"}
@@ -69,17 +68,17 @@ func (h *IDTokenHandlers) FetchToken(c echo.Context) error {
keySet, err := h.repository.GetJSONWebKeySet(c.Request().Context())
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
binder, err := h.createBinder(c)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
req := &tailcfg.TokenRequest{}
if err := binder.BindRequest(c, req); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
machineKey := binder.Peer().String()
@@ -88,7 +87,7 @@ func (h *IDTokenHandlers) FetchToken(c echo.Context) error {
var m *domain.Machine
m, err = h.repository.GetMachineByKeys(ctx, machineKey, nodeKey)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if m == nil {
@@ -131,7 +130,7 @@ func (h *IDTokenHandlers) FetchToken(c echo.Context) error {
jwtB64, err := unsignedToken.SignedString(&keySet.Key.PrivateKey)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
resp := tailcfg.TokenResponse{IDToken: jwtB64}
+2 -3
View File
@@ -2,7 +2,6 @@ package handlers
import (
stderrors "errors"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/labstack/echo/v4"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
@@ -28,9 +27,9 @@ func NewNoiseHandlers(controlKey key.MachinePrivate, createPeerHandler CreatePee
}
func (h *NoiseHandlers) Upgrade(c echo.Context) error {
conn, err := controlhttp.AcceptHTTP(c.Request().Context(), c.Response(), c.Request(), h.controlKey)
conn, err := controlhttp.AcceptHTTP(c.Request().Context(), c.Response(), c.Request(), h.controlKey, nil)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
handler := h.createPeerHandler(conn.Peer())
+21 -17
View File
@@ -6,7 +6,6 @@ import (
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/core"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/mapping"
"github.com/labstack/echo/v4"
"net/http"
@@ -40,12 +39,12 @@ func (h *PollNetMapHandler) PollNetMap(c echo.Context) error {
ctx := c.Request().Context()
binder, err := h.createBinder(c)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
req := &tailcfg.MapRequest{}
if err := binder.BindRequest(c, req); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
machineKey := binder.Peer().String()
@@ -54,7 +53,7 @@ func (h *PollNetMapHandler) PollNetMap(c echo.Context) error {
var m *domain.Machine
m, err = h.repository.GetMachineByKeys(ctx, machineKey, nodeKey)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if m == nil {
@@ -79,7 +78,7 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
m.LastSeen = &now
if err := h.repository.SaveMachine(ctx, m); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
tailnetID := m.TailnetID
@@ -96,7 +95,7 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
response, syncedPeers, derpMapChecksum, err := h.createMapResponse(m, binder, mapRequest, false, make(map[uint64]bool), derpMapChecksum)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
updateChan := make(chan *core.Ping, 20)
@@ -107,13 +106,13 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
keepAliveResponse, err := h.createKeepAliveResponse(binder, mapRequest)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
c.Response().WriteHeader(http.StatusOK)
if _, err := c.Response().Write(response); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
c.Response().Flush()
@@ -140,7 +139,7 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
case <-keepAliveTicker.C:
if mapRequest.KeepAlive {
if _, err := c.Response().Write(keepAliveResponse); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
_ = h.repository.SetMachineLastSeen(ctx, machineID)
c.Response().Flush()
@@ -149,7 +148,7 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
if latestSync.Before(latestUpdate) {
machine, err := h.repository.GetMachine(ctx, machineID)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if machine == nil {
return nil
@@ -165,7 +164,7 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
}
if _, err := c.Response().Write(payload); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
c.Response().Flush()
@@ -184,16 +183,16 @@ func (h *PollNetMapHandler) handleReadOnly(c echo.Context, binder bind.Binder, m
m.DiscoKey = request.DiscoKey.String()
if err := h.repository.SaveMachine(ctx, m); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
response, _, _, err := h.createMapResponse(m, binder, request, false, map[uint64]bool{}, "")
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
_, err = c.Response().Write(response)
return errors.Wrap(err, 0)
return logError(err)
}
func (h *PollNetMapHandler) createKeepAliveResponse(binder bind.Binder, request *tailcfg.MapRequest) ([]byte, error) {
@@ -214,8 +213,13 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
return nil, nil, "", err
}
serviceUser, _, err := h.repository.GetOrCreateServiceUser(ctx, tailnet)
if err != nil {
return nil, nil, "", err
}
hostinfo := tailcfg.Hostinfo(m.HostInfo)
node, user, err := mapping.ToNode(m, tailnet, false, true, prc.filter)
node, user, err := mapping.ToNode(m, tailnet, serviceUser, false, true, prc.filter)
if err != nil {
return nil, nil, "", err
}
@@ -231,7 +235,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
}
syncedPeerIDs := map[uint64]bool{}
syncedUserIDs := map[tailcfg.UserID]bool{}
syncedUserIDs := map[tailcfg.UserID]bool{user.ID: true}
for _, peer := range candidatePeers {
if peer.IsExpired() {
@@ -240,7 +244,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
if policies.IsValidPeer(m, &peer) || policies.IsValidPeer(&peer, m) {
isConnected := h.sessionManager.HasSession(peer.TailnetID, peer.ID)
n, u, err := mapping.ToNode(&peer, tailnet, true, isConnected, prc.filter)
n, u, err := mapping.ToNode(&peer, tailnet, serviceUser, true, isConnected, prc.filter)
if err != nil {
return nil, nil, "", err
}
+22 -15
View File
@@ -7,7 +7,6 @@ import (
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/core"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/mapping"
"github.com/jsiebens/ionscale/internal/util"
"github.com/labstack/echo/v4"
@@ -43,12 +42,12 @@ func (h *RegistrationHandlers) Register(c echo.Context) error {
binder, err := h.createBinder(c)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
req := &tailcfg.RegisterRequest{}
if err := binder.BindRequest(c, req); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
machineKey := binder.Peer().String()
@@ -58,7 +57,7 @@ func (h *RegistrationHandlers) Register(c echo.Context) error {
m, err = h.repository.GetMachineByKeys(ctx, machineKey, nodeKey)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if m != nil {
@@ -72,12 +71,12 @@ func (h *RegistrationHandlers) Register(c echo.Context) error {
if m.Ephemeral {
if _, err := h.repository.DeleteMachine(ctx, m.ID); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
h.sessionManager.NotifyAll(m.TailnetID)
} else {
if err := h.repository.SaveMachine(ctx, m); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
h.sessionManager.NotifyAll(m.TailnetID)
}
@@ -90,7 +89,7 @@ func (h *RegistrationHandlers) Register(c echo.Context) error {
if m.Name != sanitizeHostname {
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, m.TailnetID, sanitizeHostname)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
m.Name = sanitizeHostname
m.NameIdx = nameIdx
@@ -101,7 +100,7 @@ func (h *RegistrationHandlers) Register(c echo.Context) error {
m.Tags = append(m.RegisteredTags, advertisedTags...)
if err := h.repository.SaveMachine(ctx, m); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
tUser, tLogin := mapping.ToUser(m.User)
@@ -155,7 +154,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
authKey, err := h.repository.LoadAuthKey(ctx, req.Auth.AuthKey)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if authKey == nil {
@@ -181,7 +180,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
m, err = h.repository.GetMachineByKey(ctx, tailnet.ID, machineKey)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
now := time.Now().UTC()
@@ -190,7 +189,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
m = &domain.Machine{
@@ -218,7 +217,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
ipv4, ipv6, err := addr.SelectIP(checkIP(ctx, h.repository.CountMachinesWithIPv4))
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
m.IPv4 = domain.IP{Addr: ipv4}
m.IPv6 = domain.IP{Addr: ipv6}
@@ -227,7 +226,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
if m.Name != sanitizeHostname {
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
m.Name = sanitizeHostname
m.NameIdx = nameIdx
@@ -245,7 +244,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
}
if err := h.repository.SaveMachine(ctx, m); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
tUser, tLogin := mapping.ToUser(m.User)
@@ -278,7 +277,7 @@ func (h *RegistrationHandlers) followup(c echo.Context, binder bind.Binder, req
return binder.WriteResponse(c, http.StatusOK, response)
}
if m != nil && m.IsFinished() {
if m != nil && m.Authenticated {
user, err := h.repository.GetUser(ctx, m.UserID)
if err != nil {
return err
@@ -294,6 +293,14 @@ func (h *RegistrationHandlers) followup(c echo.Context, binder bind.Binder, req
}
return binder.WriteResponse(c, http.StatusOK, response)
}
if m != nil && len(m.Error) != 0 {
response := tailcfg.RegisterResponse{
MachineAuthorized: len(m.Error) != 0,
Error: m.Error,
}
return binder.WriteResponse(c, http.StatusOK, response)
}
case <-notify:
return nil
}
+4 -5
View File
@@ -5,7 +5,6 @@ import (
"github.com/jsiebens/ionscale/internal/bind"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/util"
"github.com/labstack/echo/v4"
"net/http"
@@ -37,12 +36,12 @@ func (h *SSHActionHandlers) StartAuth(c echo.Context) error {
binder, err := h.createBinder(c)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
data := new(sshActionRequestData)
if err = c.Bind(data); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
key := util.RandStringBytes(8)
@@ -56,7 +55,7 @@ func (h *SSHActionHandlers) StartAuth(c echo.Context) error {
authUrl := h.config.CreateUrl("/a/s/%s", key)
if err := h.repository.SaveSSHActionRequest(ctx, request); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
resp := &tailcfg.SSHAction{
@@ -74,7 +73,7 @@ func (h *SSHActionHandlers) CheckAuth(c echo.Context) error {
binder, err := h.createBinder(c)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
tick := time.NewTicker(2 * time.Second)
+6
View File
@@ -3,6 +3,7 @@ package handlers
import (
"github.com/jsiebens/ionscale/internal/version"
"github.com/labstack/echo/v4"
"go.uber.org/zap"
"net/http"
)
@@ -14,3 +15,8 @@ func Version(c echo.Context) error {
}
return c.JSON(http.StatusOK, resp)
}
func logError(err error) error {
zap.L().WithOptions(zap.AddCallerSkip(1)).Error("error processing request", zap.Error(err))
return err
}
+7 -3
View File
@@ -82,7 +82,7 @@ func ToDNSConfig(m *domain.Machine, tailnet *domain.Tailnet, c *domain.DNSConfig
return dnsConfig
}
func ToNode(m *domain.Machine, tailnet *domain.Tailnet, peer bool, connected bool, routeFilter func(m *domain.Machine) []netip.Prefix) (*tailcfg.Node, *tailcfg.UserProfile, error) {
func ToNode(m *domain.Machine, tailnet *domain.Tailnet, taggedDevicesUser *domain.User, peer bool, connected bool, routeFilter func(m *domain.Machine) []netip.Prefix) (*tailcfg.Node, *tailcfg.UserProfile, error) {
role := tailnet.IAMPolicy.GetRole(m.User)
var capabilities []string
@@ -148,6 +148,10 @@ func ToNode(m *domain.Machine, tailnet *domain.Tailnet, peer bool, connected boo
allowedIPs = append(allowedIPs, routeFilter(m)...)
}
if m.IsAllowedExitNode() {
allowedIPs = append(allowedIPs, netip.MustParsePrefix("0.0.0.0/0"), netip.MustParsePrefix("::/0"))
}
var derp string
if hostinfo.NetInfo != nil {
derp = fmt.Sprintf("127.3.3.40:%d", hostinfo.NetInfo.PreferredDERP)
@@ -203,9 +207,9 @@ func ToNode(m *domain.Machine, tailnet *domain.Tailnet, peer bool, connected boo
var user = ToUserProfile(m.User)
if m.HasTags() {
n.User = tailcfg.UserID(m.ID)
n.User = tailcfg.UserID(taggedDevicesUser.ID)
user = tailcfg.UserProfile{
ID: tailcfg.UserID(m.ID),
ID: tailcfg.UserID(taggedDevicesUser.ID),
LoginName: "tagged-devices",
DisplayName: "Tagged Devices",
}
+12 -39
View File
@@ -2,54 +2,35 @@ package server
import (
"fmt"
"github.com/hashicorp/go-hclog"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/labstack/echo-contrib/prometheus"
"github.com/labstack/echo/v4"
"go.uber.org/zap"
"net/http"
"strings"
"time"
)
func EchoErrorHandler(logger hclog.Logger) echo.MiddlewareFunc {
func EchoErrorHandler() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
request := c.Request()
if err := next(c); err != nil {
switch t := err.(type) {
case *echo.HTTPError:
return err
case *errors.Error:
logger.Error("error processing request",
"err", t.Cause,
"location", t.Location,
"http.method", request.Method,
"http.uri", request.RequestURI,
)
default:
logger.Error("error processing request",
"err", err,
"http.method", request.Method,
"http.uri", request.RequestURI,
)
}
err := next(c)
if strings.HasPrefix(request.RequestURI, "/a/") {
return c.Render(http.StatusInternalServerError, "error.html", nil)
}
if err != nil && strings.HasPrefix(request.RequestURI, "/a/") {
return c.Render(http.StatusInternalServerError, "error.html", nil)
}
return nil
return err
}
}
}
func EchoLogger(logger hclog.Logger) echo.MiddlewareFunc {
httpLogger := logger.Named("http")
func EchoLogger(logger *zap.Logger) echo.MiddlewareFunc {
httpLogger := logger.Sugar()
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) (err error) {
if !httpLogger.IsTrace() {
if !httpLogger.Level().Enabled(zap.DebugLevel) {
return next(c)
}
@@ -60,7 +41,7 @@ func EchoLogger(logger hclog.Logger) echo.MiddlewareFunc {
c.Error(err)
}
httpLogger.Trace("finished server http call",
httpLogger.Debugw("finished server http call",
"http.code", response.Status,
"http.method", request.Method,
"http.uri", request.RequestURI,
@@ -72,7 +53,7 @@ func EchoLogger(logger hclog.Logger) echo.MiddlewareFunc {
}
}
func EchoRecover(logger hclog.Logger) echo.MiddlewareFunc {
func EchoRecover() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
apply := func() (topErr error) {
@@ -82,6 +63,7 @@ func EchoRecover(logger hclog.Logger) echo.MiddlewareFunc {
if !ok {
err = fmt.Errorf("%v", r)
}
zap.L().Error("panic when processing request", zap.Error(err))
topErr = err
}
}()
@@ -92,15 +74,6 @@ func EchoRecover(logger hclog.Logger) echo.MiddlewareFunc {
}
}
func ErrorRedirect() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.Set("redirect_on_error", true)
return next(c)
}
}
}
func EchoMetrics(p *prometheus.Prometheus) echo.MiddlewareFunc {
return p.HandlerFunc
}
+2 -3
View File
@@ -2,7 +2,6 @@ package server
import (
"github.com/bufbuild/connect-go"
"github.com/hashicorp/go-hclog"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/key"
"github.com/jsiebens/ionscale/internal/service"
@@ -10,7 +9,7 @@ import (
"net/http"
)
func NewRpcHandler(systemAdminKey *key.ServerPrivate, repository domain.Repository, logger hclog.Logger, handler apiconnect.IonscaleServiceHandler) (string, http.Handler) {
interceptors := connect.WithInterceptors(service.NewErrorInterceptor(logger), service.AuthenticationInterceptor(systemAdminKey, repository))
func NewRpcHandler(systemAdminKey *key.ServerPrivate, repository domain.Repository, handler apiconnect.IonscaleServiceHandler) (string, http.Handler) {
interceptors := connect.WithInterceptors(service.NewErrorInterceptor(), service.AuthenticationInterceptor(systemAdminKey, repository))
return apiconnect.NewIonscaleServiceHandler(handler, interceptors)
}
+57 -45
View File
@@ -5,7 +5,6 @@ import (
"crypto/tls"
"fmt"
"github.com/caddyserver/certmagic"
"github.com/hashicorp/go-hclog"
"github.com/jsiebens/ionscale/internal/auth"
"github.com/jsiebens/ionscale/internal/bind"
"github.com/jsiebens/ionscale/internal/config"
@@ -19,15 +18,15 @@ import (
echo_prometheus "github.com/labstack/echo-contrib/prometheus"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"golang.org/x/sync/errgroup"
"log"
"net"
"net/http"
"net/url"
"os"
"strings"
"tailscale.com/types/key"
)
@@ -39,28 +38,38 @@ func Start(c *config.Config) error {
logger.Info("Starting ionscale server")
repository, err := database.OpenDB(&c.Database, logger)
if err != nil {
logError := func(err error) error {
if err != nil {
zap.L().WithOptions(zap.AddCallerSkip(1)).Error("Unable to start server", zap.Error(err))
}
return err
}
httpLogger := logger.Named("http")
dbLogger := logger.Named("db")
repository, err := database.OpenDB(&c.Database, dbLogger)
if err != nil {
return logError(err)
}
sessionManager := core.NewPollMapSessionManager()
defaultControlKeys, err := repository.GetControlKeys(context.Background())
if err != nil {
return err
return logError(err)
}
serverKey, err := c.ReadServerKeys(defaultControlKeys)
if err != nil {
return err
return logError(err)
}
core.StartReaper(repository, sessionManager)
serverUrl, err := url.Parse(c.ServerUrl)
if err != nil {
return err
return logError(err)
}
// prepare CertMagic
@@ -68,13 +77,14 @@ func Start(c *config.Config) error {
certmagic.DefaultACME.Agreed = true
certmagic.DefaultACME.Email = c.Tls.AcmeEmail
certmagic.DefaultACME.CA = c.Tls.AcmeCA
certmagic.Default.Logger = logger.Named("certmagic")
if c.Tls.AcmePath != "" {
certmagic.Default.Storage = &certmagic.FileStorage{Path: c.Tls.AcmePath}
}
cfg := certmagic.NewDefault()
if err := cfg.ManageAsync(context.Background(), []string{serverUrl.Host}); err != nil {
return err
return logError(err)
}
c.HttpListenAddr = fmt.Sprintf(":%d", certmagic.HTTPPort)
@@ -83,12 +93,12 @@ func Start(c *config.Config) error {
authProvider, systemIAMPolicy, err := setupAuthProvider(c.Auth)
if err != nil {
return fmt.Errorf("error configuring OIDC provider: %v", err)
return logError(fmt.Errorf("error configuring OIDC provider: %v", err))
}
dnsProvider, err := dns.NewProvider(c.DNS)
if err != nil {
return err
return logError(err)
}
p := echo_prometheus.NewPrometheus("http", nil)
@@ -106,7 +116,7 @@ func Start(c *config.Config) error {
sshActionHandlers := handlers.NewSSHActionHandlers(binder, c, repository)
e := echo.New()
e.Use(EchoMetrics(p), EchoLogger(logger), EchoErrorHandler(logger), EchoRecover(logger))
e.Use(EchoMetrics(p), EchoLogger(httpLogger), EchoErrorHandler(), EchoRecover())
e.POST("/machine/register", registrationHandlers.Register)
e.POST("/machine/map", pollNetMapHandler.PollNetMap)
e.POST("/machine/set-dns", dnsHandlers.SetDNS)
@@ -130,17 +140,17 @@ func Start(c *config.Config) error {
)
rpcService := service.NewService(c, authProvider, repository, sessionManager)
rpcPath, rpcHandler := NewRpcHandler(serverKey.SystemAdminKey, repository, logger, rpcService)
rpcPath, rpcHandler := NewRpcHandler(serverKey.SystemAdminKey, repository, rpcService)
nonTlsAppHandler := echo.New()
nonTlsAppHandler.Use(EchoMetrics(p), EchoLogger(logger), EchoErrorHandler(logger), EchoRecover(logger))
nonTlsAppHandler.Use(EchoMetrics(p), EchoLogger(httpLogger), EchoErrorHandler(), EchoRecover())
nonTlsAppHandler.POST("/ts2021", noiseHandlers.Upgrade)
nonTlsAppHandler.Any("/*", handlers.HttpRedirectHandler(c.Tls))
tlsAppHandler := echo.New()
tlsAppHandler.Renderer = templates.NewTemplates()
tlsAppHandler.Pre(handlers.HttpsRedirect(c.Tls))
tlsAppHandler.Use(EchoMetrics(p), EchoLogger(logger), EchoErrorHandler(logger), EchoRecover(logger))
tlsAppHandler.Use(EchoMetrics(p), EchoLogger(logger), EchoErrorHandler(), EchoRecover())
tlsAppHandler.Any("/*", handlers.IndexHandler(http.StatusNotFound))
tlsAppHandler.Any("/", handlers.IndexHandler(http.StatusOK))
@@ -167,17 +177,17 @@ func Start(c *config.Config) error {
tlsL, err := tlsListener(c)
if err != nil {
return err
return logError(err)
}
nonTlsL, err := nonTlsListener(c)
if err != nil {
return err
return logError(err)
}
metricsL, err := metricsListener(c)
if err != nil {
return err
return logError(err)
}
httpL := selectListener(tlsL, nonTlsL)
@@ -192,14 +202,14 @@ func Start(c *config.Config) error {
}
if c.Tls.AcmeEnabled {
logger.Info("TLS is enabled with ACME", "domain", serverUrl.Host)
logger.Info("Server is running", "http_addr", c.HttpListenAddr, "https_addr", c.HttpsListenAddr, "metrics_addr", c.MetricsListenAddr)
logger.Sugar().Infow("TLS is enabled with ACME", "domain", serverUrl.Host)
logger.Sugar().Infow("Server is running", "http_addr", c.HttpListenAddr, "https_addr", c.HttpsListenAddr, "metrics_addr", c.MetricsListenAddr)
} else if !c.Tls.Disable {
logger.Info("TLS is enabled", "cert", c.Tls.CertFile)
logger.Info("Server is running", "http_addr", c.HttpListenAddr, "https_addr", c.HttpsListenAddr, "metrics_addr", c.MetricsListenAddr)
logger.Sugar().Infow("TLS is enabled", "cert", c.Tls.CertFile)
logger.Sugar().Infow("Server is running", "http_addr", c.HttpListenAddr, "https_addr", c.HttpsListenAddr, "metrics_addr", c.MetricsListenAddr)
} else {
logger.Warn("TLS is disabled")
logger.Info("Server is running", "http_addr", c.HttpListenAddr, "metrics_addr", c.MetricsListenAddr)
logger.Sugar().Warnw("TLS is disabled")
logger.Sugar().Infow("Server is running", "http_addr", c.HttpListenAddr, "metrics_addr", c.MetricsListenAddr)
}
return g.Wait()
@@ -268,32 +278,34 @@ func selectListener(a net.Listener, b net.Listener) net.Listener {
return b
}
func setupLogging(config config.Logging) (hclog.Logger, error) {
file, err := createLogFile(config)
func setupLogging(config config.Logging) (*zap.Logger, error) {
level, err := zap.ParseAtomicLevel(config.Level)
if err != nil {
return nil, err
}
appLogger := hclog.New(&hclog.LoggerOptions{
Name: "ionscale",
Level: hclog.LevelFromString(config.Level),
JSONFormat: strings.ToLower(config.Format) == "json",
Output: file,
})
log.SetOutput(appLogger.StandardWriter(&hclog.StandardLoggerOptions{InferLevels: true}))
log.SetPrefix("")
log.SetFlags(0)
pc := zap.NewProductionConfig()
pc.Level = level
pc.DisableStacktrace = true
pc.OutputPaths = []string{"stdout"}
pc.Encoding = "console"
pc.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
pc.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
return appLogger, nil
}
func createLogFile(config config.Logging) (*os.File, error) {
if config.File != "" {
f, err := os.OpenFile(config.File, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
return nil, err
}
return f, nil
pc.OutputPaths = []string{config.File}
}
return os.Stdout, nil
if config.Format == "json" {
pc.Encoding = "json"
}
logger, err := pc.Build()
if err != nil {
return nil, err
}
zap.ReplaceGlobals(logger)
return logger, nil
}
+5 -6
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/mapping"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
)
@@ -18,7 +17,7 @@ func (s *Service) GetACLPolicy(ctx context.Context, req *connect.Request[api.Get
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet does not exist"))
@@ -26,7 +25,7 @@ func (s *Service) GetACLPolicy(ctx context.Context, req *connect.Request[api.Get
var policy api.ACLPolicy
if err := mapping.CopyViaJson(&tailnet.ACLPolicy, &policy); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
return connect.NewResponse(&api.GetACLPolicyResponse{Policy: &policy}), nil
@@ -40,7 +39,7 @@ func (s *Service) SetACLPolicy(ctx context.Context, req *connect.Request[api.Set
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet does not exist"))
@@ -48,12 +47,12 @@ func (s *Service) SetACLPolicy(ctx context.Context, req *connect.Request[api.Set
var policy domain.ACLPolicy
if err := mapping.CopyViaJson(req.Msg.Policy, &policy); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
tailnet.ACLPolicy = policy
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
+5 -6
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/util"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"time"
@@ -25,11 +24,11 @@ func (s *Service) Authenticate(ctx context.Context, req *connect.Request[api.Aut
}
if err := s.repository.SaveAuthenticationRequest(ctx, session); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if err := stream.Send(&api.AuthenticateResponse{AuthUrl: authUrl}); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
notify := ctx.Done()
@@ -45,7 +44,7 @@ func (s *Service) Authenticate(ctx context.Context, req *connect.Request[api.Aut
case <-tick.C:
m, err := s.repository.GetAuthenticationRequest(ctx, key)
if err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
if m == nil {
@@ -54,7 +53,7 @@ func (s *Service) Authenticate(ctx context.Context, req *connect.Request[api.Aut
if len(m.Token) != 0 {
if err := stream.Send(&api.AuthenticateResponse{Token: m.Token, TailnetId: m.TailnetID}); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
return nil
}
@@ -64,7 +63,7 @@ func (s *Service) Authenticate(ctx context.Context, req *connect.Request[api.Aut
}
if err := stream.Send(&api.AuthenticateResponse{AuthUrl: authUrl}); err != nil {
return errors.Wrap(err, 0)
return logError(err)
}
case <-notify:
+9 -10
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"google.golang.org/protobuf/types/known/timestamppb"
"time"
@@ -16,7 +15,7 @@ func (s *Service) GetAuthKey(ctx context.Context, req *connect.Request[api.GetAu
key, err := s.repository.GetAuthKey(ctx, req.Msg.AuthKeyId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if key == nil {
@@ -80,7 +79,7 @@ func (s *Service) ListAuthKeys(ctx context.Context, req *connect.Request[api.Lis
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
@@ -92,7 +91,7 @@ func (s *Service) ListAuthKeys(ctx context.Context, req *connect.Request[api.Lis
if principal.IsSystemAdmin() {
authKeys, err := s.repository.ListAuthKeys(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
response.AuthKeys = mapAuthKeysToApi(authKeys)
@@ -102,7 +101,7 @@ func (s *Service) ListAuthKeys(ctx context.Context, req *connect.Request[api.Lis
if principal.User != nil {
authKeys, err := s.repository.ListAuthKeysByTailnetAndUser(ctx, req.Msg.TailnetId, principal.User.ID)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
response.AuthKeys = mapAuthKeysToApi(authKeys)
@@ -128,7 +127,7 @@ func (s *Service) CreateAuthKey(ctx context.Context, req *connect.Request[api.Cr
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
@@ -155,7 +154,7 @@ func (s *Service) CreateAuthKey(ctx context.Context, req *connect.Request[api.Cr
if user == nil {
u, _, err := s.repository.GetOrCreateServiceUser(ctx, tailnet)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
user = u
}
@@ -165,7 +164,7 @@ func (s *Service) CreateAuthKey(ctx context.Context, req *connect.Request[api.Cr
v, authKey := domain.CreateAuthKey(tailnet, user, req.Msg.Ephemeral, req.Msg.PreAuthorized, tags, expiresAt)
if err := s.repository.SaveAuthKey(ctx, authKey); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
response := api.CreateAuthKeyResponse{
@@ -191,7 +190,7 @@ func (s *Service) DeleteAuthKey(ctx context.Context, req *connect.Request[api.De
key, err := s.repository.GetAuthKey(ctx, req.Msg.AuthKeyId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if key == nil {
@@ -203,7 +202,7 @@ func (s *Service) DeleteAuthKey(ctx context.Context, req *connect.Request[api.De
}
if _, err := s.repository.DeleteAuthKey(ctx, req.Msg.AuthKeyId); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
return connect.NewResponse(&api.DeleteAuthKeyResponse{}), nil
}
+7 -8
View File
@@ -6,7 +6,6 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/util"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"tailscale.com/tailcfg"
@@ -20,12 +19,12 @@ func (s *Service) GetDefaultDERPMap(ctx context.Context, _ *connect.Request[api.
dm, err := s.repository.GetDERPMap(ctx)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
raw, err := json.Marshal(dm.DERPMap)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
return connect.NewResponse(&api.GetDefaultDERPMapResponse{Value: raw}), nil
@@ -39,7 +38,7 @@ func (s *Service) SetDefaultDERPMap(ctx context.Context, req *connect.Request[ap
var derpMap tailcfg.DERPMap
if err := json.Unmarshal(req.Msg.Value, &derpMap); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
dp := domain.DERPMap{
@@ -48,12 +47,12 @@ func (s *Service) SetDefaultDERPMap(ctx context.Context, req *connect.Request[ap
}
if err := s.repository.SetDERPMap(ctx, &dp); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
tailnets, err := s.repository.ListTailnets(ctx)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
for _, t := range tailnets {
@@ -72,12 +71,12 @@ func (s *Service) ResetDefaultDERPMap(ctx context.Context, req *connect.Request[
dp := domain.DERPMap{}
if err := s.repository.SetDERPMap(ctx, &dp); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
tailnets, err := s.repository.ListTailnets(ctx)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
for _, t := range tailnets {
+31 -15
View File
@@ -6,7 +6,6 @@ import (
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
)
@@ -18,24 +17,14 @@ func (s *Service) GetDNSConfig(ctx context.Context, req *connect.Request[api.Get
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
}
dnsConfig := tailnet.DNSConfig
tailnetDomain := domain.SanitizeTailnetName(tailnet.Name)
resp := &api.GetDNSConfigResponse{
Config: &api.DNSConfig{
MagicDns: dnsConfig.MagicDNS,
HttpsCerts: dnsConfig.HttpsCertsEnabled,
MagicDnsSuffix: fmt.Sprintf("%s.%s", tailnetDomain, config.MagicDNSSuffix()),
OverrideLocalDns: dnsConfig.OverrideLocalDNS,
Nameservers: dnsConfig.Nameservers,
Routes: domainRoutesToApiRoutes(dnsConfig.Routes),
},
Config: domainDNSConfigToApiDNSConfig(tailnet),
}
return connect.NewResponse(resp), nil
@@ -55,7 +44,7 @@ func (s *Service) SetDNSConfig(ctx context.Context, req *connect.Request[api.Set
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -70,7 +59,7 @@ func (s *Service) SetDNSConfig(ctx context.Context, req *connect.Request[api.Set
}
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
@@ -95,3 +84,30 @@ func apiRoutesToDomainRoutes(routes map[string]*api.Routes) map[string][]string
}
return result
}
func apiDNSConfigToDomainDNSConfig(dnsConfig *api.DNSConfig) domain.DNSConfig {
if dnsConfig == nil {
return domain.DNSConfig{}
}
return domain.DNSConfig{
MagicDNS: dnsConfig.MagicDns,
HttpsCertsEnabled: dnsConfig.HttpsCerts,
OverrideLocalDNS: dnsConfig.OverrideLocalDns,
Nameservers: dnsConfig.Nameservers,
Routes: apiRoutesToDomainRoutes(dnsConfig.Routes),
}
}
func domainDNSConfigToApiDNSConfig(tailnet *domain.Tailnet) *api.DNSConfig {
tailnetDomain := domain.SanitizeTailnetName(tailnet.Name)
dnsConfig := tailnet.DNSConfig
return &api.DNSConfig{
MagicDns: dnsConfig.MagicDNS,
HttpsCerts: dnsConfig.HttpsCertsEnabled,
MagicDnsSuffix: fmt.Sprintf("%s.%s", tailnetDomain, config.MagicDNSSuffix()),
OverrideLocalDns: dnsConfig.OverrideLocalDNS,
Nameservers: dnsConfig.Nameservers,
Routes: domainRoutesToApiRoutes(dnsConfig.Routes),
}
}
+3 -4
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
)
@@ -17,7 +16,7 @@ func (s *Service) GetIAMPolicy(ctx context.Context, req *connect.Request[api.Get
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet does not exist"))
@@ -41,7 +40,7 @@ func (s *Service) SetIAMPolicy(ctx context.Context, req *connect.Request[api.Set
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet does not exist"))
@@ -55,7 +54,7 @@ func (s *Service) SetIAMPolicy(ctx context.Context, req *connect.Request[api.Set
}
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
return connect.NewResponse(&api.SetIAMPolicyResponse{}), nil
+10 -18
View File
@@ -4,11 +4,10 @@ import (
"context"
"fmt"
"github.com/bufbuild/connect-go"
"github.com/hashicorp/go-hclog"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/key"
"github.com/jsiebens/ionscale/internal/token"
"go.uber.org/zap"
"strings"
)
@@ -78,14 +77,11 @@ func exchangeToken(ctx context.Context, systemAdminKey *key.ServerPrivate, repos
return nil
}
func NewErrorInterceptor(logger hclog.Logger) *ErrorInterceptor {
return &ErrorInterceptor{
logger: logger,
}
func NewErrorInterceptor() *ErrorInterceptor {
return &ErrorInterceptor{}
}
type ErrorInterceptor struct {
logger hclog.Logger
}
func (e *ErrorInterceptor) handleError(err error) error {
@@ -93,23 +89,14 @@ func (e *ErrorInterceptor) handleError(err error) error {
return err
}
switch t := err.(type) {
switch err.(type) {
case *connect.Error:
return err
case *errors.Error:
e.logger.Error("error processing grpc request",
"err", t.Cause,
"location", t.Location,
)
return connect.NewError(connect.CodeInternal, fmt.Errorf("internal server error"))
default:
e.logger.Error("error processing grpc request",
"err", err,
)
return connect.NewError(connect.CodeInternal, fmt.Errorf("internal server error"))
}
}
func (e *ErrorInterceptor) WrapUnary(next connect.UnaryFunc) connect.UnaryFunc {
return func(ctx context.Context, request connect.AnyRequest) (connect.AnyResponse, error) {
response, err := next(ctx, request)
@@ -129,3 +116,8 @@ func (e *ErrorInterceptor) WrapStreamingHandler(next connect.StreamingHandlerFun
return e.handleError(err)
}
}
func logError(err error) error {
zap.L().WithOptions(zap.AddCallerSkip(1)).Error("error processing request", zap.Error(err))
return err
}
+22 -23
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"google.golang.org/protobuf/types/known/timestamppb"
"net/netip"
@@ -66,7 +65,7 @@ func (s *Service) ListMachines(ctx context.Context, req *connect.Request[api.Lis
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -74,7 +73,7 @@ func (s *Service) ListMachines(ctx context.Context, req *connect.Request[api.Lis
machines, err := s.repository.ListMachineByTailnet(ctx, tailnet.ID)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
response := &api.ListMachinesResponse{}
@@ -90,7 +89,7 @@ func (s *Service) GetMachine(ctx context.Context, req *connect.Request[api.GetMa
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -109,7 +108,7 @@ func (s *Service) DeleteMachine(ctx context.Context, req *connect.Request[api.De
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -121,7 +120,7 @@ func (s *Service) DeleteMachine(ctx context.Context, req *connect.Request[api.De
}
if _, err := s.repository.DeleteMachine(ctx, req.Msg.MachineId); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(m.TailnetID)
@@ -134,7 +133,7 @@ func (s *Service) ExpireMachine(ctx context.Context, req *connect.Request[api.Ex
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -150,7 +149,7 @@ func (s *Service) ExpireMachine(ctx context.Context, req *connect.Request[api.Ex
m.KeyExpiryDisabled = false
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(m.TailnetID)
@@ -163,7 +162,7 @@ func (s *Service) AuthorizeMachine(ctx context.Context, req *connect.Request[api
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -177,7 +176,7 @@ func (s *Service) AuthorizeMachine(ctx context.Context, req *connect.Request[api
if !m.Authorized {
m.Authorized = true
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
}
@@ -191,7 +190,7 @@ func (s *Service) GetMachineRoutes(ctx context.Context, req *connect.Request[api
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -220,7 +219,7 @@ func (s *Service) EnableMachineRoutes(ctx context.Context, req *connect.Request[
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -242,7 +241,7 @@ func (s *Service) EnableMachineRoutes(ctx context.Context, req *connect.Request[
for _, r := range req.Msg.Routes {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
allowIPs.Add(prefix)
}
@@ -250,7 +249,7 @@ func (s *Service) EnableMachineRoutes(ctx context.Context, req *connect.Request[
m.AllowIPs = allowIPs.Items()
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(m.TailnetID)
@@ -273,7 +272,7 @@ func (s *Service) DisableMachineRoutes(ctx context.Context, req *connect.Request
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -290,7 +289,7 @@ func (s *Service) DisableMachineRoutes(ctx context.Context, req *connect.Request
for _, r := range req.Msg.Routes {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
allowIPs.Remove(prefix)
autoAllowIPs.Remove(prefix)
@@ -299,7 +298,7 @@ func (s *Service) DisableMachineRoutes(ctx context.Context, req *connect.Request
m.AllowIPs = allowIPs.Items()
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(m.TailnetID)
@@ -322,7 +321,7 @@ func (s *Service) EnableExitNode(ctx context.Context, req *connect.Request[api.E
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -346,7 +345,7 @@ func (s *Service) EnableExitNode(ctx context.Context, req *connect.Request[api.E
m.AllowIPs = allowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(m.TailnetID)
@@ -369,7 +368,7 @@ func (s *Service) DisableExitNode(ctx context.Context, req *connect.Request[api.
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -397,7 +396,7 @@ func (s *Service) DisableExitNode(ctx context.Context, req *connect.Request[api.
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(m.TailnetID)
@@ -420,7 +419,7 @@ func (s *Service) SetMachineKeyExpiry(ctx context.Context, req *connect.Request[
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if m == nil {
@@ -434,7 +433,7 @@ func (s *Service) SetMachineKeyExpiry(ctx context.Context, req *connect.Request[
m.KeyExpiryDisabled = req.Msg.Disabled
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(m.TailnetID)
+146 -54
View File
@@ -6,44 +6,134 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
"github.com/jsiebens/ionscale/internal/mapping"
"github.com/jsiebens/ionscale/internal/util"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"tailscale.com/tailcfg"
)
func domainTailnetToApiTailnet(tailnet *domain.Tailnet) (*api.Tailnet, error) {
t := &api.Tailnet{
Id: tailnet.ID,
Name: tailnet.Name,
IamPolicy: new(api.IAMPolicy),
AclPolicy: new(api.ACLPolicy),
DnsConfig: domainDNSConfigToApiDNSConfig(tailnet),
ServiceCollectionEnabled: tailnet.ServiceCollectionEnabled,
FileSharingEnabled: tailnet.FileSharingEnabled,
SshEnabled: tailnet.SSHEnabled,
MachineAuthorizationEnabled: tailnet.MachineAuthorizationEnabled,
}
if err := mapping.CopyViaJson(tailnet.IAMPolicy, t.IamPolicy); err != nil {
return nil, err
}
if err := mapping.CopyViaJson(tailnet.ACLPolicy, t.AclPolicy); err != nil {
return nil, err
}
return t, nil
}
func (s *Service) CreateTailnet(ctx context.Context, req *connect.Request[api.CreateTailnetRequest]) (*connect.Response[api.CreateTailnetResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() {
return nil, connect.NewError(connect.CodePermissionDenied, fmt.Errorf("permission denied"))
}
name := req.Msg.Name
iamPolicy := domain.IAMPolicy{}
if req.Msg.IamPolicy != nil {
iamPolicy.Subs = req.Msg.IamPolicy.Subs
iamPolicy.Emails = req.Msg.IamPolicy.Emails
iamPolicy.Filters = req.Msg.IamPolicy.Filters
iamPolicy.Roles = apiRolesMapToDomainRolesMap(req.Msg.IamPolicy.Roles)
tailnet := &domain.Tailnet{
ID: util.NextID(),
Name: req.Msg.Name,
IAMPolicy: domain.IAMPolicy{},
ACLPolicy: domain.ACLPolicy{},
DNSConfig: apiDNSConfigToDomainDNSConfig(req.Msg.DnsConfig),
ServiceCollectionEnabled: req.Msg.ServiceCollectionEnabled,
FileSharingEnabled: req.Msg.FileSharingEnabled,
SSHEnabled: req.Msg.SshEnabled,
MachineAuthorizationEnabled: req.Msg.MachineAuthorizationEnabled,
}
tailnet := &domain.Tailnet{
ID: util.NextID(),
Name: name,
IAMPolicy: iamPolicy,
ACLPolicy: domain.DefaultPolicy(),
DNSConfig: domain.DNSConfig{MagicDNS: true},
if req.Msg.IamPolicy != nil {
if err := mapping.CopyViaJson(req.Msg.IamPolicy, &tailnet.IAMPolicy); err != nil {
return nil, logError(err)
}
} else {
tailnet.IAMPolicy = domain.DefaultIAMPolicy()
}
if req.Msg.AclPolicy != nil {
if err := mapping.CopyViaJson(req.Msg.AclPolicy, &tailnet.ACLPolicy); err != nil {
return nil, logError(err)
}
} else {
tailnet.ACLPolicy = domain.DefaultACLPolicy()
}
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
resp := &api.CreateTailnetResponse{Tailnet: &api.Tailnet{
Id: tailnet.ID,
Name: tailnet.Name,
}}
t, err := domainTailnetToApiTailnet(tailnet)
if err != nil {
return nil, logError(err)
}
resp := &api.CreateTailnetResponse{Tailnet: t}
return connect.NewResponse(resp), nil
}
func (s *Service) UpdateTailnet(ctx context.Context, req *connect.Request[api.UpdateTailnetRequest]) (*connect.Response[api.UpdateTailnetResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, fmt.Errorf("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
}
if req.Msg.IamPolicy != nil {
tailnet.IAMPolicy = domain.IAMPolicy{}
if err := mapping.CopyViaJson(req.Msg.IamPolicy, &tailnet.IAMPolicy); err != nil {
return nil, logError(err)
}
}
if req.Msg.AclPolicy != nil {
tailnet.ACLPolicy = domain.ACLPolicy{}
if err := mapping.CopyViaJson(req.Msg.AclPolicy, &tailnet.ACLPolicy); err != nil {
return nil, logError(err)
}
}
if req.Msg.DnsConfig != nil {
tailnet.DNSConfig = apiDNSConfigToDomainDNSConfig(req.Msg.DnsConfig)
}
tailnet.ServiceCollectionEnabled = req.Msg.ServiceCollectionEnabled
tailnet.FileSharingEnabled = req.Msg.FileSharingEnabled
tailnet.SSHEnabled = req.Msg.SshEnabled
tailnet.MachineAuthorizationEnabled = req.Msg.MachineAuthorizationEnabled
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
t, err := domainTailnetToApiTailnet(tailnet)
if err != nil {
return nil, logError(err)
}
resp := &api.UpdateTailnetResponse{Tailnet: t}
return connect.NewResponse(resp), nil
}
@@ -56,17 +146,19 @@ func (s *Service) GetTailnet(ctx context.Context, req *connect.Request[api.GetTa
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.Id)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
}
return connect.NewResponse(&api.GetTailnetResponse{Tailnet: &api.Tailnet{
Id: tailnet.ID,
Name: tailnet.Name,
}}), nil
t, err := domainTailnetToApiTailnet(tailnet)
if err != nil {
return nil, logError(err)
}
return connect.NewResponse(&api.GetTailnetResponse{Tailnet: t}), nil
}
func (s *Service) ListTailnets(ctx context.Context, req *connect.Request[api.ListTailnetsRequest]) (*connect.Response[api.ListTailnetsResponse], error) {
@@ -77,7 +169,7 @@ func (s *Service) ListTailnets(ctx context.Context, req *connect.Request[api.Lis
if principal.IsSystemAdmin() {
tailnets, err := s.repository.ListTailnets(ctx)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
for _, t := range tailnets {
gt := api.Tailnet{Id: t.ID, Name: t.Name}
@@ -88,7 +180,7 @@ func (s *Service) ListTailnets(ctx context.Context, req *connect.Request[api.Lis
if principal.User != nil {
tailnet, err := s.repository.GetTailnet(ctx, principal.User.TailnetID)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
gt := api.Tailnet{Id: tailnet.ID, Name: tailnet.Name}
resp.Tailnet = append(resp.Tailnet, &gt)
@@ -105,7 +197,7 @@ func (s *Service) DeleteTailnet(ctx context.Context, req *connect.Request[api.De
count, err := s.repository.CountMachineByTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if !req.Msg.Force && count > 0 {
@@ -137,7 +229,7 @@ func (s *Service) DeleteTailnet(ctx context.Context, req *connect.Request[api.De
})
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(req.Msg.TailnetId)
@@ -153,12 +245,12 @@ func (s *Service) SetDERPMap(ctx context.Context, req *connect.Request[api.SetDE
derpMap := tailcfg.DERPMap{}
if err := json.Unmarshal(req.Msg.Value, &derpMap); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -170,14 +262,14 @@ func (s *Service) SetDERPMap(ctx context.Context, req *connect.Request[api.SetDE
}
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
raw, err := json.Marshal(derpMap)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
return connect.NewResponse(&api.SetDERPMapResponse{Value: raw}), nil
@@ -191,7 +283,7 @@ func (s *Service) ResetDERPMap(ctx context.Context, req *connect.Request[api.Res
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -200,7 +292,7 @@ func (s *Service) ResetDERPMap(ctx context.Context, req *connect.Request[api.Res
tailnet.DERPMap = domain.DERPMap{}
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
@@ -216,7 +308,7 @@ func (s *Service) GetDERPMap(ctx context.Context, req *connect.Request[api.GetDE
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -224,12 +316,12 @@ func (s *Service) GetDERPMap(ctx context.Context, req *connect.Request[api.GetDE
derpMap, err := tailnet.GetDERPMap(ctx, s.repository)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
raw, err := json.Marshal(derpMap.DERPMap)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
return connect.NewResponse(&api.GetDERPMapResponse{Value: raw}), nil
@@ -243,7 +335,7 @@ func (s *Service) EnableFileSharing(ctx context.Context, req *connect.Request[ap
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -252,7 +344,7 @@ func (s *Service) EnableFileSharing(ctx context.Context, req *connect.Request[ap
if !tailnet.FileSharingEnabled {
tailnet.FileSharingEnabled = true
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
@@ -269,7 +361,7 @@ func (s *Service) DisableFileSharing(ctx context.Context, req *connect.Request[a
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -278,7 +370,7 @@ func (s *Service) DisableFileSharing(ctx context.Context, req *connect.Request[a
if tailnet.FileSharingEnabled {
tailnet.FileSharingEnabled = false
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
@@ -295,7 +387,7 @@ func (s *Service) EnableServiceCollection(ctx context.Context, req *connect.Requ
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -304,7 +396,7 @@ func (s *Service) EnableServiceCollection(ctx context.Context, req *connect.Requ
if !tailnet.ServiceCollectionEnabled {
tailnet.ServiceCollectionEnabled = true
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
@@ -321,7 +413,7 @@ func (s *Service) DisableServiceCollection(ctx context.Context, req *connect.Req
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -330,7 +422,7 @@ func (s *Service) DisableServiceCollection(ctx context.Context, req *connect.Req
if tailnet.ServiceCollectionEnabled {
tailnet.ServiceCollectionEnabled = false
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
@@ -347,7 +439,7 @@ func (s *Service) EnableSSH(ctx context.Context, req *connect.Request[api.Enable
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -356,7 +448,7 @@ func (s *Service) EnableSSH(ctx context.Context, req *connect.Request[api.Enable
if !tailnet.SSHEnabled {
tailnet.SSHEnabled = true
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
@@ -373,7 +465,7 @@ func (s *Service) DisableSSH(ctx context.Context, req *connect.Request[api.Disab
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -382,7 +474,7 @@ func (s *Service) DisableSSH(ctx context.Context, req *connect.Request[api.Disab
if tailnet.SSHEnabled {
tailnet.SSHEnabled = false
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
@@ -399,7 +491,7 @@ func (s *Service) EnableMachineAuthorization(ctx context.Context, req *connect.R
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -408,7 +500,7 @@ func (s *Service) EnableMachineAuthorization(ctx context.Context, req *connect.R
if !tailnet.MachineAuthorizationEnabled {
tailnet.MachineAuthorizationEnabled = true
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
}
@@ -423,7 +515,7 @@ func (s *Service) DisableMachineAuthorization(ctx context.Context, req *connect.
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
@@ -432,7 +524,7 @@ func (s *Service) DisableMachineAuthorization(ctx context.Context, req *connect.
if tailnet.MachineAuthorizationEnabled {
tailnet.MachineAuthorizationEnabled = false
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
}
+4 -5
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/errors"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
)
@@ -14,7 +13,7 @@ func (s *Service) ListUsers(ctx context.Context, req *connect.Request[api.ListUs
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if tailnet == nil {
@@ -27,7 +26,7 @@ func (s *Service) ListUsers(ctx context.Context, req *connect.Request[api.ListUs
users, err := s.repository.ListUsers(ctx, tailnet.ID)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
resp := &api.ListUsersResponse{}
@@ -51,7 +50,7 @@ func (s *Service) DeleteUser(ctx context.Context, req *connect.Request[api.Delet
user, err := s.repository.GetUser(ctx, req.Msg.UserId)
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
if user == nil {
@@ -87,7 +86,7 @@ func (s *Service) DeleteUser(ctx context.Context, req *connect.Request[api.Delet
})
if err != nil {
return nil, errors.Wrap(err, 0)
return nil, logError(err)
}
s.sessionManager.NotifyAll(user.TailnetID)
+2 -2
View File
@@ -29,13 +29,13 @@ tls:
# Required when TLS is enabled and ACME disabled
key_file: ""
# Enable automatic TLS certificates provisioning with Let's Encrypt
acme_enabled: false
acme: false
# An email address, used when creating an ACME account and keeping you up-to-date regarding your certificates
acme_email: ""
# The URL to the ACME CA's directory.
acme_ca: "https://acme-v02.api.letsencrypt.org/directory"
# Path to store certificates and metadata needed by ACME
amce_path: "./data"
acme_path: "./data"
database:
# Type of databas to use, supported values are sqlite or postgres
+1 -1
View File
@@ -68,5 +68,5 @@ docker run \
-v $(pwd)/data:/data \
-p 80:80 \
-p 443:443 \
ghcr.io/jsiebens/ionscale:0.5.0 server --config /etc/ionscale/config.yaml
ghcr.io/jsiebens/ionscale:0.8.2 server --config /etc/ionscale/config.yaml
```
+1 -1
View File
@@ -41,7 +41,7 @@ Run the following commands to install the __ionscale__ binary on your Linux host
``` bash
sudo curl \
-o "/usr/local/bin/ionscale" \
-sfL "https://github.com/jsiebens/ionscale/releases/download/v0.5.0/ionscale_linux_amd64"
-sfL "https://github.com/jsiebens/ionscale/releases/download/v0.8.2/ionscale_linux_amd64"
sudo chmod +x "/usr/local/bin/ionscale"
```
+21
View File
@@ -0,0 +1,21 @@
package defaults
import ionscalev1 "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
func DefaultACLPolicy() *ionscalev1.ACLPolicy {
return &ionscalev1.ACLPolicy{
Acls: []*ionscalev1.ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"*:*"},
},
},
}
}
func DefaultDNSConfig() *ionscalev1.DNSConfig {
return &ionscalev1.DNSConfig{
MagicDns: true,
}
}
+391 -382
View File
@@ -42,7 +42,7 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x32, 0xda, 0x1f, 0x0a, 0x0f, 0x49, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65,
0x6f, 0x32, 0xb4, 0x20, 0x0a, 0x0f, 0x49, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
@@ -79,228 +79,233 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x12,
0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65,
0x74, 0x73, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61,
0x70, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d,
0x61, 0x70, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x44, 0x45,
0x52, 0x50, 0x4d, 0x61, 0x70, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d,
0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x11,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e,
0x67, 0x12, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e,
0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c,
0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x67, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c,
0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69,
0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x27, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44,
0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e,
0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x76, 0x0a, 0x17, 0x45,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43,
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x18, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x2c, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69,
0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c,
0x0a, 0x09, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x12, 0x1d, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
0x53, 0x53, 0x48, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53,
0x53, 0x48, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a,
0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
0x53, 0x53, 0x48, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
0x53, 0x53, 0x48, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a,
0x1a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75,
0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x82,
0x01, 0x0a, 0x1b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73,
0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x30, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69,
0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68,
0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x53, 0x65,
0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x4e,
0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x55, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63,
0x79, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x49,
0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c,
0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50,
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x55, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12,
0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x41, 0x43, 0x4c,
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63,
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c,
0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a,
0x0a, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74,
0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74,
0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58,
0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12,
0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x75,
0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65,
0x79, 0x73, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x4c, 0x69, 0x73,
0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d,
0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x4c, 0x69, 0x73,
0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61,
0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x61, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63,
0x68, 0x69, 0x6e, 0x65, 0x12, 0x24, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63,
0x68, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65,
0x00, 0x12, 0x58, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e,
0x65, 0x74, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x47,
0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e,
0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e,
0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c,
0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69,
0x6c, 0x6e, 0x65, 0x74, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a,
0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x21,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x4d, 0x61,
0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x27,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74,
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65,
0x4b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65,
0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d,
0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x13, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x27, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62,
0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69,
0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x6d, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63,
0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x69, 0x6f, 0x6e,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a,
0x0a, 0x47, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x12, 0x1e, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x45, 0x52,
0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x45, 0x52,
0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f,
0x0a, 0x0a, 0x53, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x12, 0x1e, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x45,
0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x45,
0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x55, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x12,
0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
0x73, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x52, 0x65, 0x73, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x11, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x25, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x26, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69,
0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x67, 0x0a, 0x12,
0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69,
0x6e, 0x67, 0x12, 0x26, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72,
0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x76, 0x0a, 0x17, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x2b, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62,
0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a,
0x18, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43,
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x45, 0x6e, 0x61, 0x62,
0x6c, 0x65, 0x53, 0x53, 0x48, 0x12, 0x1d, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
0x65, 0x53, 0x53, 0x48, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x1a, 0x45, 0x6e, 0x61, 0x62, 0x6c,
0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x82, 0x01, 0x0a, 0x1b, 0x44, 0x69, 0x73,
0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61,
0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d,
0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a,
0x0c, 0x47, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44,
0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x47,
0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x20, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x41, 0x4d,
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49,
0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69,
0x63, 0x79, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x47, 0x65, 0x74,
0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f,
0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x43, 0x4c,
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x55, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79,
0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53,
0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x41, 0x75,
0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x75,
0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68,
0x4b, 0x65, 0x79, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x4b,
0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c,
0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x20, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41,
0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x41, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73,
0x12, 0x1d, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12,
0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65,
0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69,
0x6e, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x41, 0x75,
0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x24,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a,
0x0d, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x21,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70,
0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63,
0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x6a, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b,
0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x27, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x70,
0x69, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a,
0x10, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65,
0x73, 0x12, 0x24, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65,
0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x6a, 0x0a, 0x13, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74,
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x14,
0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f,
0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e,
0x6f, 0x64, 0x65, 0x12, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74,
0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e,
0x0a, 0x0f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64,
0x65, 0x12, 0x23, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74,
0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3d,
0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69,
0x65, 0x62, 0x65, 0x6e, 0x73, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70,
0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f,
0x76, 0x31, 0x3b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73,
0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x45,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62,
0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x23, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x24, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44,
0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65, 0x6e, 0x73, 0x2f,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e,
0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_ionscale_v1_ionscale_proto_goTypes = []interface{}{
@@ -310,86 +315,88 @@ var file_ionscale_v1_ionscale_proto_goTypes = []interface{}{
(*SetDefaultDERPMapRequest)(nil), // 3: ionscale.v1.SetDefaultDERPMapRequest
(*ResetDefaultDERPMapRequest)(nil), // 4: ionscale.v1.ResetDefaultDERPMapRequest
(*CreateTailnetRequest)(nil), // 5: ionscale.v1.CreateTailnetRequest
(*GetTailnetRequest)(nil), // 6: ionscale.v1.GetTailnetRequest
(*ListTailnetsRequest)(nil), // 7: ionscale.v1.ListTailnetsRequest
(*DeleteTailnetRequest)(nil), // 8: ionscale.v1.DeleteTailnetRequest
(*GetDERPMapRequest)(nil), // 9: ionscale.v1.GetDERPMapRequest
(*SetDERPMapRequest)(nil), // 10: ionscale.v1.SetDERPMapRequest
(*ResetDERPMapRequest)(nil), // 11: ionscale.v1.ResetDERPMapRequest
(*EnableFileSharingRequest)(nil), // 12: ionscale.v1.EnableFileSharingRequest
(*DisableFileSharingRequest)(nil), // 13: ionscale.v1.DisableFileSharingRequest
(*EnableServiceCollectionRequest)(nil), // 14: ionscale.v1.EnableServiceCollectionRequest
(*DisableServiceCollectionRequest)(nil), // 15: ionscale.v1.DisableServiceCollectionRequest
(*EnableSSHRequest)(nil), // 16: ionscale.v1.EnableSSHRequest
(*DisableSSHRequest)(nil), // 17: ionscale.v1.DisableSSHRequest
(*EnableMachineAuthorizationRequest)(nil), // 18: ionscale.v1.EnableMachineAuthorizationRequest
(*DisableMachineAuthorizationRequest)(nil), // 19: ionscale.v1.DisableMachineAuthorizationRequest
(*GetDNSConfigRequest)(nil), // 20: ionscale.v1.GetDNSConfigRequest
(*SetDNSConfigRequest)(nil), // 21: ionscale.v1.SetDNSConfigRequest
(*GetIAMPolicyRequest)(nil), // 22: ionscale.v1.GetIAMPolicyRequest
(*SetIAMPolicyRequest)(nil), // 23: ionscale.v1.SetIAMPolicyRequest
(*GetACLPolicyRequest)(nil), // 24: ionscale.v1.GetACLPolicyRequest
(*SetACLPolicyRequest)(nil), // 25: ionscale.v1.SetACLPolicyRequest
(*GetAuthKeyRequest)(nil), // 26: ionscale.v1.GetAuthKeyRequest
(*CreateAuthKeyRequest)(nil), // 27: ionscale.v1.CreateAuthKeyRequest
(*DeleteAuthKeyRequest)(nil), // 28: ionscale.v1.DeleteAuthKeyRequest
(*ListAuthKeysRequest)(nil), // 29: ionscale.v1.ListAuthKeysRequest
(*ListUsersRequest)(nil), // 30: ionscale.v1.ListUsersRequest
(*DeleteUserRequest)(nil), // 31: ionscale.v1.DeleteUserRequest
(*GetMachineRequest)(nil), // 32: ionscale.v1.GetMachineRequest
(*ListMachinesRequest)(nil), // 33: ionscale.v1.ListMachinesRequest
(*AuthorizeMachineRequest)(nil), // 34: ionscale.v1.AuthorizeMachineRequest
(*ExpireMachineRequest)(nil), // 35: ionscale.v1.ExpireMachineRequest
(*DeleteMachineRequest)(nil), // 36: ionscale.v1.DeleteMachineRequest
(*SetMachineKeyExpiryRequest)(nil), // 37: ionscale.v1.SetMachineKeyExpiryRequest
(*GetMachineRoutesRequest)(nil), // 38: ionscale.v1.GetMachineRoutesRequest
(*EnableMachineRoutesRequest)(nil), // 39: ionscale.v1.EnableMachineRoutesRequest
(*DisableMachineRoutesRequest)(nil), // 40: ionscale.v1.DisableMachineRoutesRequest
(*EnableExitNodeRequest)(nil), // 41: ionscale.v1.EnableExitNodeRequest
(*DisableExitNodeRequest)(nil), // 42: ionscale.v1.DisableExitNodeRequest
(*GetVersionResponse)(nil), // 43: ionscale.v1.GetVersionResponse
(*AuthenticateResponse)(nil), // 44: ionscale.v1.AuthenticateResponse
(*GetDefaultDERPMapResponse)(nil), // 45: ionscale.v1.GetDefaultDERPMapResponse
(*SetDefaultDERPMapResponse)(nil), // 46: ionscale.v1.SetDefaultDERPMapResponse
(*ResetDefaultDERPMapResponse)(nil), // 47: ionscale.v1.ResetDefaultDERPMapResponse
(*CreateTailnetResponse)(nil), // 48: ionscale.v1.CreateTailnetResponse
(*GetTailnetResponse)(nil), // 49: ionscale.v1.GetTailnetResponse
(*ListTailnetsResponse)(nil), // 50: ionscale.v1.ListTailnetsResponse
(*DeleteTailnetResponse)(nil), // 51: ionscale.v1.DeleteTailnetResponse
(*GetDERPMapResponse)(nil), // 52: ionscale.v1.GetDERPMapResponse
(*SetDERPMapResponse)(nil), // 53: ionscale.v1.SetDERPMapResponse
(*ResetDERPMapResponse)(nil), // 54: ionscale.v1.ResetDERPMapResponse
(*EnableFileSharingResponse)(nil), // 55: ionscale.v1.EnableFileSharingResponse
(*DisableFileSharingResponse)(nil), // 56: ionscale.v1.DisableFileSharingResponse
(*EnableServiceCollectionResponse)(nil), // 57: ionscale.v1.EnableServiceCollectionResponse
(*DisableServiceCollectionResponse)(nil), // 58: ionscale.v1.DisableServiceCollectionResponse
(*EnableSSHResponse)(nil), // 59: ionscale.v1.EnableSSHResponse
(*DisableSSHResponse)(nil), // 60: ionscale.v1.DisableSSHResponse
(*EnableMachineAuthorizationResponse)(nil), // 61: ionscale.v1.EnableMachineAuthorizationResponse
(*DisableMachineAuthorizationResponse)(nil), // 62: ionscale.v1.DisableMachineAuthorizationResponse
(*GetDNSConfigResponse)(nil), // 63: ionscale.v1.GetDNSConfigResponse
(*SetDNSConfigResponse)(nil), // 64: ionscale.v1.SetDNSConfigResponse
(*GetIAMPolicyResponse)(nil), // 65: ionscale.v1.GetIAMPolicyResponse
(*SetIAMPolicyResponse)(nil), // 66: ionscale.v1.SetIAMPolicyResponse
(*GetACLPolicyResponse)(nil), // 67: ionscale.v1.GetACLPolicyResponse
(*SetACLPolicyResponse)(nil), // 68: ionscale.v1.SetACLPolicyResponse
(*GetAuthKeyResponse)(nil), // 69: ionscale.v1.GetAuthKeyResponse
(*CreateAuthKeyResponse)(nil), // 70: ionscale.v1.CreateAuthKeyResponse
(*DeleteAuthKeyResponse)(nil), // 71: ionscale.v1.DeleteAuthKeyResponse
(*ListAuthKeysResponse)(nil), // 72: ionscale.v1.ListAuthKeysResponse
(*ListUsersResponse)(nil), // 73: ionscale.v1.ListUsersResponse
(*DeleteUserResponse)(nil), // 74: ionscale.v1.DeleteUserResponse
(*GetMachineResponse)(nil), // 75: ionscale.v1.GetMachineResponse
(*ListMachinesResponse)(nil), // 76: ionscale.v1.ListMachinesResponse
(*AuthorizeMachineResponse)(nil), // 77: ionscale.v1.AuthorizeMachineResponse
(*ExpireMachineResponse)(nil), // 78: ionscale.v1.ExpireMachineResponse
(*DeleteMachineResponse)(nil), // 79: ionscale.v1.DeleteMachineResponse
(*SetMachineKeyExpiryResponse)(nil), // 80: ionscale.v1.SetMachineKeyExpiryResponse
(*GetMachineRoutesResponse)(nil), // 81: ionscale.v1.GetMachineRoutesResponse
(*EnableMachineRoutesResponse)(nil), // 82: ionscale.v1.EnableMachineRoutesResponse
(*DisableMachineRoutesResponse)(nil), // 83: ionscale.v1.DisableMachineRoutesResponse
(*EnableExitNodeResponse)(nil), // 84: ionscale.v1.EnableExitNodeResponse
(*DisableExitNodeResponse)(nil), // 85: ionscale.v1.DisableExitNodeResponse
(*UpdateTailnetRequest)(nil), // 6: ionscale.v1.UpdateTailnetRequest
(*GetTailnetRequest)(nil), // 7: ionscale.v1.GetTailnetRequest
(*ListTailnetsRequest)(nil), // 8: ionscale.v1.ListTailnetsRequest
(*DeleteTailnetRequest)(nil), // 9: ionscale.v1.DeleteTailnetRequest
(*GetDERPMapRequest)(nil), // 10: ionscale.v1.GetDERPMapRequest
(*SetDERPMapRequest)(nil), // 11: ionscale.v1.SetDERPMapRequest
(*ResetDERPMapRequest)(nil), // 12: ionscale.v1.ResetDERPMapRequest
(*EnableFileSharingRequest)(nil), // 13: ionscale.v1.EnableFileSharingRequest
(*DisableFileSharingRequest)(nil), // 14: ionscale.v1.DisableFileSharingRequest
(*EnableServiceCollectionRequest)(nil), // 15: ionscale.v1.EnableServiceCollectionRequest
(*DisableServiceCollectionRequest)(nil), // 16: ionscale.v1.DisableServiceCollectionRequest
(*EnableSSHRequest)(nil), // 17: ionscale.v1.EnableSSHRequest
(*DisableSSHRequest)(nil), // 18: ionscale.v1.DisableSSHRequest
(*EnableMachineAuthorizationRequest)(nil), // 19: ionscale.v1.EnableMachineAuthorizationRequest
(*DisableMachineAuthorizationRequest)(nil), // 20: ionscale.v1.DisableMachineAuthorizationRequest
(*GetDNSConfigRequest)(nil), // 21: ionscale.v1.GetDNSConfigRequest
(*SetDNSConfigRequest)(nil), // 22: ionscale.v1.SetDNSConfigRequest
(*GetIAMPolicyRequest)(nil), // 23: ionscale.v1.GetIAMPolicyRequest
(*SetIAMPolicyRequest)(nil), // 24: ionscale.v1.SetIAMPolicyRequest
(*GetACLPolicyRequest)(nil), // 25: ionscale.v1.GetACLPolicyRequest
(*SetACLPolicyRequest)(nil), // 26: ionscale.v1.SetACLPolicyRequest
(*GetAuthKeyRequest)(nil), // 27: ionscale.v1.GetAuthKeyRequest
(*CreateAuthKeyRequest)(nil), // 28: ionscale.v1.CreateAuthKeyRequest
(*DeleteAuthKeyRequest)(nil), // 29: ionscale.v1.DeleteAuthKeyRequest
(*ListAuthKeysRequest)(nil), // 30: ionscale.v1.ListAuthKeysRequest
(*ListUsersRequest)(nil), // 31: ionscale.v1.ListUsersRequest
(*DeleteUserRequest)(nil), // 32: ionscale.v1.DeleteUserRequest
(*GetMachineRequest)(nil), // 33: ionscale.v1.GetMachineRequest
(*ListMachinesRequest)(nil), // 34: ionscale.v1.ListMachinesRequest
(*AuthorizeMachineRequest)(nil), // 35: ionscale.v1.AuthorizeMachineRequest
(*ExpireMachineRequest)(nil), // 36: ionscale.v1.ExpireMachineRequest
(*DeleteMachineRequest)(nil), // 37: ionscale.v1.DeleteMachineRequest
(*SetMachineKeyExpiryRequest)(nil), // 38: ionscale.v1.SetMachineKeyExpiryRequest
(*GetMachineRoutesRequest)(nil), // 39: ionscale.v1.GetMachineRoutesRequest
(*EnableMachineRoutesRequest)(nil), // 40: ionscale.v1.EnableMachineRoutesRequest
(*DisableMachineRoutesRequest)(nil), // 41: ionscale.v1.DisableMachineRoutesRequest
(*EnableExitNodeRequest)(nil), // 42: ionscale.v1.EnableExitNodeRequest
(*DisableExitNodeRequest)(nil), // 43: ionscale.v1.DisableExitNodeRequest
(*GetVersionResponse)(nil), // 44: ionscale.v1.GetVersionResponse
(*AuthenticateResponse)(nil), // 45: ionscale.v1.AuthenticateResponse
(*GetDefaultDERPMapResponse)(nil), // 46: ionscale.v1.GetDefaultDERPMapResponse
(*SetDefaultDERPMapResponse)(nil), // 47: ionscale.v1.SetDefaultDERPMapResponse
(*ResetDefaultDERPMapResponse)(nil), // 48: ionscale.v1.ResetDefaultDERPMapResponse
(*CreateTailnetResponse)(nil), // 49: ionscale.v1.CreateTailnetResponse
(*UpdateTailnetResponse)(nil), // 50: ionscale.v1.UpdateTailnetResponse
(*GetTailnetResponse)(nil), // 51: ionscale.v1.GetTailnetResponse
(*ListTailnetsResponse)(nil), // 52: ionscale.v1.ListTailnetsResponse
(*DeleteTailnetResponse)(nil), // 53: ionscale.v1.DeleteTailnetResponse
(*GetDERPMapResponse)(nil), // 54: ionscale.v1.GetDERPMapResponse
(*SetDERPMapResponse)(nil), // 55: ionscale.v1.SetDERPMapResponse
(*ResetDERPMapResponse)(nil), // 56: ionscale.v1.ResetDERPMapResponse
(*EnableFileSharingResponse)(nil), // 57: ionscale.v1.EnableFileSharingResponse
(*DisableFileSharingResponse)(nil), // 58: ionscale.v1.DisableFileSharingResponse
(*EnableServiceCollectionResponse)(nil), // 59: ionscale.v1.EnableServiceCollectionResponse
(*DisableServiceCollectionResponse)(nil), // 60: ionscale.v1.DisableServiceCollectionResponse
(*EnableSSHResponse)(nil), // 61: ionscale.v1.EnableSSHResponse
(*DisableSSHResponse)(nil), // 62: ionscale.v1.DisableSSHResponse
(*EnableMachineAuthorizationResponse)(nil), // 63: ionscale.v1.EnableMachineAuthorizationResponse
(*DisableMachineAuthorizationResponse)(nil), // 64: ionscale.v1.DisableMachineAuthorizationResponse
(*GetDNSConfigResponse)(nil), // 65: ionscale.v1.GetDNSConfigResponse
(*SetDNSConfigResponse)(nil), // 66: ionscale.v1.SetDNSConfigResponse
(*GetIAMPolicyResponse)(nil), // 67: ionscale.v1.GetIAMPolicyResponse
(*SetIAMPolicyResponse)(nil), // 68: ionscale.v1.SetIAMPolicyResponse
(*GetACLPolicyResponse)(nil), // 69: ionscale.v1.GetACLPolicyResponse
(*SetACLPolicyResponse)(nil), // 70: ionscale.v1.SetACLPolicyResponse
(*GetAuthKeyResponse)(nil), // 71: ionscale.v1.GetAuthKeyResponse
(*CreateAuthKeyResponse)(nil), // 72: ionscale.v1.CreateAuthKeyResponse
(*DeleteAuthKeyResponse)(nil), // 73: ionscale.v1.DeleteAuthKeyResponse
(*ListAuthKeysResponse)(nil), // 74: ionscale.v1.ListAuthKeysResponse
(*ListUsersResponse)(nil), // 75: ionscale.v1.ListUsersResponse
(*DeleteUserResponse)(nil), // 76: ionscale.v1.DeleteUserResponse
(*GetMachineResponse)(nil), // 77: ionscale.v1.GetMachineResponse
(*ListMachinesResponse)(nil), // 78: ionscale.v1.ListMachinesResponse
(*AuthorizeMachineResponse)(nil), // 79: ionscale.v1.AuthorizeMachineResponse
(*ExpireMachineResponse)(nil), // 80: ionscale.v1.ExpireMachineResponse
(*DeleteMachineResponse)(nil), // 81: ionscale.v1.DeleteMachineResponse
(*SetMachineKeyExpiryResponse)(nil), // 82: ionscale.v1.SetMachineKeyExpiryResponse
(*GetMachineRoutesResponse)(nil), // 83: ionscale.v1.GetMachineRoutesResponse
(*EnableMachineRoutesResponse)(nil), // 84: ionscale.v1.EnableMachineRoutesResponse
(*DisableMachineRoutesResponse)(nil), // 85: ionscale.v1.DisableMachineRoutesResponse
(*EnableExitNodeResponse)(nil), // 86: ionscale.v1.EnableExitNodeResponse
(*DisableExitNodeResponse)(nil), // 87: ionscale.v1.DisableExitNodeResponse
}
var file_ionscale_v1_ionscale_proto_depIdxs = []int32{
0, // 0: ionscale.v1.IonscaleService.GetVersion:input_type -> ionscale.v1.GetVersionRequest
@@ -398,88 +405,90 @@ var file_ionscale_v1_ionscale_proto_depIdxs = []int32{
3, // 3: ionscale.v1.IonscaleService.SetDefaultDERPMap:input_type -> ionscale.v1.SetDefaultDERPMapRequest
4, // 4: ionscale.v1.IonscaleService.ResetDefaultDERPMap:input_type -> ionscale.v1.ResetDefaultDERPMapRequest
5, // 5: ionscale.v1.IonscaleService.CreateTailnet:input_type -> ionscale.v1.CreateTailnetRequest
6, // 6: ionscale.v1.IonscaleService.GetTailnet:input_type -> ionscale.v1.GetTailnetRequest
7, // 7: ionscale.v1.IonscaleService.ListTailnets:input_type -> ionscale.v1.ListTailnetsRequest
8, // 8: ionscale.v1.IonscaleService.DeleteTailnet:input_type -> ionscale.v1.DeleteTailnetRequest
9, // 9: ionscale.v1.IonscaleService.GetDERPMap:input_type -> ionscale.v1.GetDERPMapRequest
10, // 10: ionscale.v1.IonscaleService.SetDERPMap:input_type -> ionscale.v1.SetDERPMapRequest
11, // 11: ionscale.v1.IonscaleService.ResetDERPMap:input_type -> ionscale.v1.ResetDERPMapRequest
12, // 12: ionscale.v1.IonscaleService.EnableFileSharing:input_type -> ionscale.v1.EnableFileSharingRequest
13, // 13: ionscale.v1.IonscaleService.DisableFileSharing:input_type -> ionscale.v1.DisableFileSharingRequest
14, // 14: ionscale.v1.IonscaleService.EnableServiceCollection:input_type -> ionscale.v1.EnableServiceCollectionRequest
15, // 15: ionscale.v1.IonscaleService.DisableServiceCollection:input_type -> ionscale.v1.DisableServiceCollectionRequest
16, // 16: ionscale.v1.IonscaleService.EnableSSH:input_type -> ionscale.v1.EnableSSHRequest
17, // 17: ionscale.v1.IonscaleService.DisableSSH:input_type -> ionscale.v1.DisableSSHRequest
18, // 18: ionscale.v1.IonscaleService.EnableMachineAuthorization:input_type -> ionscale.v1.EnableMachineAuthorizationRequest
19, // 19: ionscale.v1.IonscaleService.DisableMachineAuthorization:input_type -> ionscale.v1.DisableMachineAuthorizationRequest
20, // 20: ionscale.v1.IonscaleService.GetDNSConfig:input_type -> ionscale.v1.GetDNSConfigRequest
21, // 21: ionscale.v1.IonscaleService.SetDNSConfig:input_type -> ionscale.v1.SetDNSConfigRequest
22, // 22: ionscale.v1.IonscaleService.GetIAMPolicy:input_type -> ionscale.v1.GetIAMPolicyRequest
23, // 23: ionscale.v1.IonscaleService.SetIAMPolicy:input_type -> ionscale.v1.SetIAMPolicyRequest
24, // 24: ionscale.v1.IonscaleService.GetACLPolicy:input_type -> ionscale.v1.GetACLPolicyRequest
25, // 25: ionscale.v1.IonscaleService.SetACLPolicy:input_type -> ionscale.v1.SetACLPolicyRequest
26, // 26: ionscale.v1.IonscaleService.GetAuthKey:input_type -> ionscale.v1.GetAuthKeyRequest
27, // 27: ionscale.v1.IonscaleService.CreateAuthKey:input_type -> ionscale.v1.CreateAuthKeyRequest
28, // 28: ionscale.v1.IonscaleService.DeleteAuthKey:input_type -> ionscale.v1.DeleteAuthKeyRequest
29, // 29: ionscale.v1.IonscaleService.ListAuthKeys:input_type -> ionscale.v1.ListAuthKeysRequest
30, // 30: ionscale.v1.IonscaleService.ListUsers:input_type -> ionscale.v1.ListUsersRequest
31, // 31: ionscale.v1.IonscaleService.DeleteUser:input_type -> ionscale.v1.DeleteUserRequest
32, // 32: ionscale.v1.IonscaleService.GetMachine:input_type -> ionscale.v1.GetMachineRequest
33, // 33: ionscale.v1.IonscaleService.ListMachines:input_type -> ionscale.v1.ListMachinesRequest
34, // 34: ionscale.v1.IonscaleService.AuthorizeMachine:input_type -> ionscale.v1.AuthorizeMachineRequest
35, // 35: ionscale.v1.IonscaleService.ExpireMachine:input_type -> ionscale.v1.ExpireMachineRequest
36, // 36: ionscale.v1.IonscaleService.DeleteMachine:input_type -> ionscale.v1.DeleteMachineRequest
37, // 37: ionscale.v1.IonscaleService.SetMachineKeyExpiry:input_type -> ionscale.v1.SetMachineKeyExpiryRequest
38, // 38: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest
39, // 39: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest
40, // 40: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest
41, // 41: ionscale.v1.IonscaleService.EnableExitNode:input_type -> ionscale.v1.EnableExitNodeRequest
42, // 42: ionscale.v1.IonscaleService.DisableExitNode:input_type -> ionscale.v1.DisableExitNodeRequest
43, // 43: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse
44, // 44: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticateResponse
45, // 45: ionscale.v1.IonscaleService.GetDefaultDERPMap:output_type -> ionscale.v1.GetDefaultDERPMapResponse
46, // 46: ionscale.v1.IonscaleService.SetDefaultDERPMap:output_type -> ionscale.v1.SetDefaultDERPMapResponse
47, // 47: ionscale.v1.IonscaleService.ResetDefaultDERPMap:output_type -> ionscale.v1.ResetDefaultDERPMapResponse
48, // 48: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse
49, // 49: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse
50, // 50: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetsResponse
51, // 51: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse
52, // 52: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse
53, // 53: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse
54, // 54: ionscale.v1.IonscaleService.ResetDERPMap:output_type -> ionscale.v1.ResetDERPMapResponse
55, // 55: ionscale.v1.IonscaleService.EnableFileSharing:output_type -> ionscale.v1.EnableFileSharingResponse
56, // 56: ionscale.v1.IonscaleService.DisableFileSharing:output_type -> ionscale.v1.DisableFileSharingResponse
57, // 57: ionscale.v1.IonscaleService.EnableServiceCollection:output_type -> ionscale.v1.EnableServiceCollectionResponse
58, // 58: ionscale.v1.IonscaleService.DisableServiceCollection:output_type -> ionscale.v1.DisableServiceCollectionResponse
59, // 59: ionscale.v1.IonscaleService.EnableSSH:output_type -> ionscale.v1.EnableSSHResponse
60, // 60: ionscale.v1.IonscaleService.DisableSSH:output_type -> ionscale.v1.DisableSSHResponse
61, // 61: ionscale.v1.IonscaleService.EnableMachineAuthorization:output_type -> ionscale.v1.EnableMachineAuthorizationResponse
62, // 62: ionscale.v1.IonscaleService.DisableMachineAuthorization:output_type -> ionscale.v1.DisableMachineAuthorizationResponse
63, // 63: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse
64, // 64: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse
65, // 65: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse
66, // 66: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse
67, // 67: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse
68, // 68: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse
69, // 69: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse
70, // 70: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse
71, // 71: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse
72, // 72: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse
73, // 73: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse
74, // 74: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse
75, // 75: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse
76, // 76: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse
77, // 77: ionscale.v1.IonscaleService.AuthorizeMachine:output_type -> ionscale.v1.AuthorizeMachineResponse
78, // 78: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse
79, // 79: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse
80, // 80: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse
81, // 81: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
82, // 82: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.EnableMachineRoutesResponse
83, // 83: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.DisableMachineRoutesResponse
84, // 84: ionscale.v1.IonscaleService.EnableExitNode:output_type -> ionscale.v1.EnableExitNodeResponse
85, // 85: ionscale.v1.IonscaleService.DisableExitNode:output_type -> ionscale.v1.DisableExitNodeResponse
43, // [43:86] is the sub-list for method output_type
0, // [0:43] is the sub-list for method input_type
6, // 6: ionscale.v1.IonscaleService.UpdateTailnet:input_type -> ionscale.v1.UpdateTailnetRequest
7, // 7: ionscale.v1.IonscaleService.GetTailnet:input_type -> ionscale.v1.GetTailnetRequest
8, // 8: ionscale.v1.IonscaleService.ListTailnets:input_type -> ionscale.v1.ListTailnetsRequest
9, // 9: ionscale.v1.IonscaleService.DeleteTailnet:input_type -> ionscale.v1.DeleteTailnetRequest
10, // 10: ionscale.v1.IonscaleService.GetDERPMap:input_type -> ionscale.v1.GetDERPMapRequest
11, // 11: ionscale.v1.IonscaleService.SetDERPMap:input_type -> ionscale.v1.SetDERPMapRequest
12, // 12: ionscale.v1.IonscaleService.ResetDERPMap:input_type -> ionscale.v1.ResetDERPMapRequest
13, // 13: ionscale.v1.IonscaleService.EnableFileSharing:input_type -> ionscale.v1.EnableFileSharingRequest
14, // 14: ionscale.v1.IonscaleService.DisableFileSharing:input_type -> ionscale.v1.DisableFileSharingRequest
15, // 15: ionscale.v1.IonscaleService.EnableServiceCollection:input_type -> ionscale.v1.EnableServiceCollectionRequest
16, // 16: ionscale.v1.IonscaleService.DisableServiceCollection:input_type -> ionscale.v1.DisableServiceCollectionRequest
17, // 17: ionscale.v1.IonscaleService.EnableSSH:input_type -> ionscale.v1.EnableSSHRequest
18, // 18: ionscale.v1.IonscaleService.DisableSSH:input_type -> ionscale.v1.DisableSSHRequest
19, // 19: ionscale.v1.IonscaleService.EnableMachineAuthorization:input_type -> ionscale.v1.EnableMachineAuthorizationRequest
20, // 20: ionscale.v1.IonscaleService.DisableMachineAuthorization:input_type -> ionscale.v1.DisableMachineAuthorizationRequest
21, // 21: ionscale.v1.IonscaleService.GetDNSConfig:input_type -> ionscale.v1.GetDNSConfigRequest
22, // 22: ionscale.v1.IonscaleService.SetDNSConfig:input_type -> ionscale.v1.SetDNSConfigRequest
23, // 23: ionscale.v1.IonscaleService.GetIAMPolicy:input_type -> ionscale.v1.GetIAMPolicyRequest
24, // 24: ionscale.v1.IonscaleService.SetIAMPolicy:input_type -> ionscale.v1.SetIAMPolicyRequest
25, // 25: ionscale.v1.IonscaleService.GetACLPolicy:input_type -> ionscale.v1.GetACLPolicyRequest
26, // 26: ionscale.v1.IonscaleService.SetACLPolicy:input_type -> ionscale.v1.SetACLPolicyRequest
27, // 27: ionscale.v1.IonscaleService.GetAuthKey:input_type -> ionscale.v1.GetAuthKeyRequest
28, // 28: ionscale.v1.IonscaleService.CreateAuthKey:input_type -> ionscale.v1.CreateAuthKeyRequest
29, // 29: ionscale.v1.IonscaleService.DeleteAuthKey:input_type -> ionscale.v1.DeleteAuthKeyRequest
30, // 30: ionscale.v1.IonscaleService.ListAuthKeys:input_type -> ionscale.v1.ListAuthKeysRequest
31, // 31: ionscale.v1.IonscaleService.ListUsers:input_type -> ionscale.v1.ListUsersRequest
32, // 32: ionscale.v1.IonscaleService.DeleteUser:input_type -> ionscale.v1.DeleteUserRequest
33, // 33: ionscale.v1.IonscaleService.GetMachine:input_type -> ionscale.v1.GetMachineRequest
34, // 34: ionscale.v1.IonscaleService.ListMachines:input_type -> ionscale.v1.ListMachinesRequest
35, // 35: ionscale.v1.IonscaleService.AuthorizeMachine:input_type -> ionscale.v1.AuthorizeMachineRequest
36, // 36: ionscale.v1.IonscaleService.ExpireMachine:input_type -> ionscale.v1.ExpireMachineRequest
37, // 37: ionscale.v1.IonscaleService.DeleteMachine:input_type -> ionscale.v1.DeleteMachineRequest
38, // 38: ionscale.v1.IonscaleService.SetMachineKeyExpiry:input_type -> ionscale.v1.SetMachineKeyExpiryRequest
39, // 39: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest
40, // 40: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest
41, // 41: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest
42, // 42: ionscale.v1.IonscaleService.EnableExitNode:input_type -> ionscale.v1.EnableExitNodeRequest
43, // 43: ionscale.v1.IonscaleService.DisableExitNode:input_type -> ionscale.v1.DisableExitNodeRequest
44, // 44: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse
45, // 45: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticateResponse
46, // 46: ionscale.v1.IonscaleService.GetDefaultDERPMap:output_type -> ionscale.v1.GetDefaultDERPMapResponse
47, // 47: ionscale.v1.IonscaleService.SetDefaultDERPMap:output_type -> ionscale.v1.SetDefaultDERPMapResponse
48, // 48: ionscale.v1.IonscaleService.ResetDefaultDERPMap:output_type -> ionscale.v1.ResetDefaultDERPMapResponse
49, // 49: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse
50, // 50: ionscale.v1.IonscaleService.UpdateTailnet:output_type -> ionscale.v1.UpdateTailnetResponse
51, // 51: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse
52, // 52: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetsResponse
53, // 53: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse
54, // 54: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse
55, // 55: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse
56, // 56: ionscale.v1.IonscaleService.ResetDERPMap:output_type -> ionscale.v1.ResetDERPMapResponse
57, // 57: ionscale.v1.IonscaleService.EnableFileSharing:output_type -> ionscale.v1.EnableFileSharingResponse
58, // 58: ionscale.v1.IonscaleService.DisableFileSharing:output_type -> ionscale.v1.DisableFileSharingResponse
59, // 59: ionscale.v1.IonscaleService.EnableServiceCollection:output_type -> ionscale.v1.EnableServiceCollectionResponse
60, // 60: ionscale.v1.IonscaleService.DisableServiceCollection:output_type -> ionscale.v1.DisableServiceCollectionResponse
61, // 61: ionscale.v1.IonscaleService.EnableSSH:output_type -> ionscale.v1.EnableSSHResponse
62, // 62: ionscale.v1.IonscaleService.DisableSSH:output_type -> ionscale.v1.DisableSSHResponse
63, // 63: ionscale.v1.IonscaleService.EnableMachineAuthorization:output_type -> ionscale.v1.EnableMachineAuthorizationResponse
64, // 64: ionscale.v1.IonscaleService.DisableMachineAuthorization:output_type -> ionscale.v1.DisableMachineAuthorizationResponse
65, // 65: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse
66, // 66: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse
67, // 67: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse
68, // 68: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse
69, // 69: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse
70, // 70: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse
71, // 71: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse
72, // 72: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse
73, // 73: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse
74, // 74: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse
75, // 75: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse
76, // 76: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse
77, // 77: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse
78, // 78: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse
79, // 79: ionscale.v1.IonscaleService.AuthorizeMachine:output_type -> ionscale.v1.AuthorizeMachineResponse
80, // 80: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse
81, // 81: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse
82, // 82: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse
83, // 83: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
84, // 84: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.EnableMachineRoutesResponse
85, // 85: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.DisableMachineRoutesResponse
86, // 86: ionscale.v1.IonscaleService.EnableExitNode:output_type -> ionscale.v1.EnableExitNodeResponse
87, // 87: ionscale.v1.IonscaleService.DisableExitNode:output_type -> ionscale.v1.DisableExitNodeResponse
44, // [44:88] is the sub-list for method output_type
0, // [0:44] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
@@ -33,6 +33,7 @@ type IonscaleServiceClient interface {
SetDefaultDERPMap(context.Context, *connect_go.Request[v1.SetDefaultDERPMapRequest]) (*connect_go.Response[v1.SetDefaultDERPMapResponse], error)
ResetDefaultDERPMap(context.Context, *connect_go.Request[v1.ResetDefaultDERPMapRequest]) (*connect_go.Response[v1.ResetDefaultDERPMapResponse], error)
CreateTailnet(context.Context, *connect_go.Request[v1.CreateTailnetRequest]) (*connect_go.Response[v1.CreateTailnetResponse], error)
UpdateTailnet(context.Context, *connect_go.Request[v1.UpdateTailnetRequest]) (*connect_go.Response[v1.UpdateTailnetResponse], error)
GetTailnet(context.Context, *connect_go.Request[v1.GetTailnetRequest]) (*connect_go.Response[v1.GetTailnetResponse], error)
ListTailnets(context.Context, *connect_go.Request[v1.ListTailnetsRequest]) (*connect_go.Response[v1.ListTailnetsResponse], error)
DeleteTailnet(context.Context, *connect_go.Request[v1.DeleteTailnetRequest]) (*connect_go.Response[v1.DeleteTailnetResponse], error)
@@ -112,6 +113,11 @@ func NewIonscaleServiceClient(httpClient connect_go.HTTPClient, baseURL string,
baseURL+"/ionscale.v1.IonscaleService/CreateTailnet",
opts...,
),
updateTailnet: connect_go.NewClient[v1.UpdateTailnetRequest, v1.UpdateTailnetResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/UpdateTailnet",
opts...,
),
getTailnet: connect_go.NewClient[v1.GetTailnetRequest, v1.GetTailnetResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/GetTailnet",
@@ -308,6 +314,7 @@ type ionscaleServiceClient struct {
setDefaultDERPMap *connect_go.Client[v1.SetDefaultDERPMapRequest, v1.SetDefaultDERPMapResponse]
resetDefaultDERPMap *connect_go.Client[v1.ResetDefaultDERPMapRequest, v1.ResetDefaultDERPMapResponse]
createTailnet *connect_go.Client[v1.CreateTailnetRequest, v1.CreateTailnetResponse]
updateTailnet *connect_go.Client[v1.UpdateTailnetRequest, v1.UpdateTailnetResponse]
getTailnet *connect_go.Client[v1.GetTailnetRequest, v1.GetTailnetResponse]
listTailnets *connect_go.Client[v1.ListTailnetsRequest, v1.ListTailnetsResponse]
deleteTailnet *connect_go.Client[v1.DeleteTailnetRequest, v1.DeleteTailnetResponse]
@@ -377,6 +384,11 @@ func (c *ionscaleServiceClient) CreateTailnet(ctx context.Context, req *connect_
return c.createTailnet.CallUnary(ctx, req)
}
// UpdateTailnet calls ionscale.v1.IonscaleService.UpdateTailnet.
func (c *ionscaleServiceClient) UpdateTailnet(ctx context.Context, req *connect_go.Request[v1.UpdateTailnetRequest]) (*connect_go.Response[v1.UpdateTailnetResponse], error) {
return c.updateTailnet.CallUnary(ctx, req)
}
// GetTailnet calls ionscale.v1.IonscaleService.GetTailnet.
func (c *ionscaleServiceClient) GetTailnet(ctx context.Context, req *connect_go.Request[v1.GetTailnetRequest]) (*connect_go.Response[v1.GetTailnetResponse], error) {
return c.getTailnet.CallUnary(ctx, req)
@@ -570,6 +582,7 @@ type IonscaleServiceHandler interface {
SetDefaultDERPMap(context.Context, *connect_go.Request[v1.SetDefaultDERPMapRequest]) (*connect_go.Response[v1.SetDefaultDERPMapResponse], error)
ResetDefaultDERPMap(context.Context, *connect_go.Request[v1.ResetDefaultDERPMapRequest]) (*connect_go.Response[v1.ResetDefaultDERPMapResponse], error)
CreateTailnet(context.Context, *connect_go.Request[v1.CreateTailnetRequest]) (*connect_go.Response[v1.CreateTailnetResponse], error)
UpdateTailnet(context.Context, *connect_go.Request[v1.UpdateTailnetRequest]) (*connect_go.Response[v1.UpdateTailnetResponse], error)
GetTailnet(context.Context, *connect_go.Request[v1.GetTailnetRequest]) (*connect_go.Response[v1.GetTailnetResponse], error)
ListTailnets(context.Context, *connect_go.Request[v1.ListTailnetsRequest]) (*connect_go.Response[v1.ListTailnetsResponse], error)
DeleteTailnet(context.Context, *connect_go.Request[v1.DeleteTailnetRequest]) (*connect_go.Response[v1.DeleteTailnetResponse], error)
@@ -646,6 +659,11 @@ func NewIonscaleServiceHandler(svc IonscaleServiceHandler, opts ...connect_go.Ha
svc.CreateTailnet,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/UpdateTailnet", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/UpdateTailnet",
svc.UpdateTailnet,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/GetTailnet", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/GetTailnet",
svc.GetTailnet,
@@ -861,6 +879,10 @@ func (UnimplementedIonscaleServiceHandler) CreateTailnet(context.Context, *conne
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.CreateTailnet is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) UpdateTailnet(context.Context, *connect_go.Request[v1.UpdateTailnetRequest]) (*connect_go.Response[v1.UpdateTailnetResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.UpdateTailnet is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) GetTailnet(context.Context, *connect_go.Request[v1.GetTailnetRequest]) (*connect_go.Response[v1.GetTailnetResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.GetTailnet is not implemented"))
}
File diff suppressed because it is too large Load Diff
+1
View File
@@ -26,6 +26,7 @@ service IonscaleService {
rpc ResetDefaultDERPMap(ResetDefaultDERPMapRequest) returns (ResetDefaultDERPMapResponse) {}
rpc CreateTailnet(CreateTailnetRequest) returns (CreateTailnetResponse) {}
rpc UpdateTailnet(UpdateTailnetRequest) returns (UpdateTailnetResponse) {}
rpc GetTailnet(GetTailnetRequest) returns (GetTailnetResponse) {}
rpc ListTailnets(ListTailnetsRequest) returns (ListTailnetsResponse) {}
rpc DeleteTailnet(DeleteTailnetRequest) returns (DeleteTailnetResponse) {}
+33
View File
@@ -2,24 +2,57 @@ syntax = "proto3";
package ionscale.v1;
import "ionscale/v1/acl.proto";
import "ionscale/v1/iam.proto";
import "ionscale/v1/dns.proto";
option go_package = "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1;ionscalev1";
message Tailnet {
uint64 id = 1;
string name = 2;
IAMPolicy iam_policy = 3;
ACLPolicy acl_policy = 4;
DNSConfig dns_config = 5;
bool service_collection_enabled = 6;
bool file_sharing_enabled = 7;
bool ssh_enabled = 8;
bool machine_authorization_enabled = 9;
}
message CreateTailnetRequest {
string name = 1;
IAMPolicy iam_policy = 2;
ACLPolicy acl_policy = 3;
DNSConfig dns_config = 4;
bool service_collection_enabled = 5;
bool file_sharing_enabled = 6;
bool ssh_enabled = 7;
bool machine_authorization_enabled = 8;
}
message CreateTailnetResponse {
Tailnet tailnet = 1;
}
message UpdateTailnetRequest {
uint64 tailnet_id = 1;
IAMPolicy iam_policy = 2;
ACLPolicy acl_policy = 3;
DNSConfig dns_config = 4;
bool service_collection_enabled = 5;
bool file_sharing_enabled = 6;
bool ssh_enabled = 7;
bool machine_authorization_enabled = 8;
}
message UpdateTailnetResponse {
Tailnet tailnet = 1;
}
message GetTailnetRequest {
uint64 id = 1;
}
+16
View File
@@ -0,0 +1,16 @@
http_listen_addr: ":8080"
server_url: "http://localhost:8080"
tls:
disable: true
force_https: false
keys:
system_admin_key: "804ecd57365342254ce6647da5c249e85c10a0e51e74856bfdf292a2136b4249"
database:
type: sqlite
url: /opt/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)
logging:
level: debug
+19
View File
@@ -0,0 +1,19 @@
FROM golang:1.20-buster as builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . ./
RUN go build -v -o ionscale cmd/ionscale/main.go
FROM debian:buster-slim
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
ca-certificates && \
rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/ionscale /usr/local/bin/ionscale
ENTRYPOINT ["/usr/local/bin/ionscale"]
+11
View File
@@ -0,0 +1,11 @@
FROM alpine:3.14.0
ARG TAILSCALE_VERSION
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
WORKDIR /app
ENV TSFILE=tailscale_${TAILSCALE_VERSION}_amd64.tgz
RUN wget https://pkgs.tailscale.com/stable/${TSFILE} && tar xzf ${TSFILE} --strip-components=1
RUN mkdir -p /var/run/tailscale /var/cache/tailscale /var/lib/tailscale /.cache
+80
View File
@@ -0,0 +1,80 @@
package tests
import (
"github.com/jsiebens/ionscale/tests/sc"
"github.com/stretchr/testify/assert"
"testing"
)
func TestPing(t *testing.T) {
sc.Run(t, func(s sc.Scenario) {
tailnet := s.CreateTailnet("pingtest")
key := s.CreateAuthKey(tailnet.Id, true)
nodeA := s.NewTailscaleNode("pingtest-a")
nodeB := s.NewTailscaleNode("pingtest-b")
nodeA.Up(key)
nodeB.Up(key)
nodeA.WaitForPeers(1)
nodeA.Ping("pingtest-b")
nodeA.Ping(nodeB.IPv4())
nodeA.Ping(nodeB.IPv6())
})
}
func TestGetIPs(t *testing.T) {
sc.Run(t, func(s sc.Scenario) {
tailnet := s.CreateTailnet("tailnet01")
authKey := s.CreateAuthKey(tailnet.Id, false)
tsNode := s.NewTailscaleNode("testip")
tsNode.Up(authKey)
ip4 := tsNode.IPv4()
ip6 := tsNode.IPv6()
var found = false
machines := s.ListMachines(tailnet.Id)
for _, m := range machines {
if m.Name == tsNode.Hostname() {
found = true
assert.Equal(t, m.Ipv4, ip4)
assert.Equal(t, m.Ipv6, ip6)
}
}
assert.True(t, found)
})
}
func TestNodeWithSameHostname(t *testing.T) {
sc.Run(t, func(s sc.Scenario) {
tailnet := s.CreateTailnet("tailnet01")
authKey := s.CreateAuthKey(tailnet.Id, false)
tsNode := s.NewTailscaleNode("test")
_ = tsNode.Up(authKey)
for i := 0; i < 5; i++ {
tc := s.NewTailscaleNode("test")
_ = tc.Up(authKey)
}
machines := make(map[string]bool)
for _, m := range s.ListMachines(tailnet.Id) {
machines[m.Name] = true
}
assert.Equal(t, map[string]bool{
"test": true,
"test-1": true,
"test-2": true,
"test-3": true,
"test-4": true,
"test-5": true,
}, machines)
})
}
+136
View File
@@ -0,0 +1,136 @@
package sc
import (
"bytes"
"encoding/json"
"fmt"
"github.com/ory/dockertest/v3"
"strings"
"tailscale.com/ipn/ipnstate"
"testing"
)
type TailscaleNode interface {
Hostname() string
Up(authkey string) ipnstate.Status
IPv4() string
IPv6() string
WaitForPeers(expected int)
Ping(target string)
}
type tailscaleNode struct {
t *testing.T
loginServer string
hostname string
resource *dockertest.Resource
}
func (t *tailscaleNode) Hostname() string {
return t.hostname
}
func (t *tailscaleNode) Up(authkey string) ipnstate.Status {
t.mustExecTailscaleCmd("up", "--login-server", t.loginServer, "--authkey", authkey)
return t.waitForReady()
}
func (t *tailscaleNode) IPv4() string {
return t.mustExecTailscaleCmd("ip", "-4")
}
func (t *tailscaleNode) IPv6() string {
return t.mustExecTailscaleCmd("ip", "-6")
}
func (t *tailscaleNode) waitForReady() ipnstate.Status {
var status ipnstate.Status
err := pool.Retry(func() error {
out, err := t.execTailscaleCmd("status", "--json")
if err != nil {
return err
}
if err := json.Unmarshal([]byte(out), &status); err != nil {
return err
}
if status.CurrentTailnet != nil {
return nil
}
return fmt.Errorf("not connected")
})
if err != nil {
t.t.Fatal(err)
}
return status
}
func (t *tailscaleNode) WaitForPeers(expected int) {
err := pool.Retry(func() error {
out, err := t.execTailscaleCmd("status", "--json")
if err != nil {
return err
}
var status ipnstate.Status
if err := json.Unmarshal([]byte(out), &status); err != nil {
return err
}
if len(status.Peers()) != expected {
return fmt.Errorf("incorrect peer count")
}
return nil
})
if err != nil {
t.t.Fatal(err)
}
}
func (t *tailscaleNode) Ping(target string) {
result, err := t.execTailscaleCmd("ping", "--timeout=1s", "--c=10", "--until-direct=true", target)
if err != nil {
t.t.Fatal(err)
}
if !strings.Contains(result, "pong") && !strings.Contains(result, "is local") {
t.t.Fatal("ping failed")
}
}
func (t *tailscaleNode) execTailscaleCmd(cmd ...string) (string, error) {
i := append([]string{"/app/tailscale", "--socket=/tmp/tailscaled.sock"}, cmd...)
return execCmd(t.resource, i...)
}
func (t *tailscaleNode) mustExecTailscaleCmd(cmd ...string) string {
i := append([]string{"/app/tailscale", "--socket=/tmp/tailscaled.sock"}, cmd...)
s, err := execCmd(t.resource, i...)
if err != nil {
t.t.Fatal(err)
}
return s
}
func execCmd(resource *dockertest.Resource, cmd ...string) (string, error) {
var stdout bytes.Buffer
var stderr bytes.Buffer
exitCode, err := resource.Exec(cmd, dockertest.ExecOptions{StdOut: &stdout, StdErr: &stderr})
if err != nil {
return "", err
}
if err != nil {
return strings.TrimSpace(stdout.String()), err
}
if exitCode != 0 {
return strings.TrimSpace(stdout.String()), fmt.Errorf("command failed with: %s", stderr.String())
}
return strings.TrimSpace(stdout.String()), nil
}
+271
View File
@@ -0,0 +1,271 @@
package sc
import (
"context"
"fmt"
"github.com/bufbuild/connect-go"
ionscaleclt "github.com/jsiebens/ionscale/pkg/client/ionscale"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
ionscaleconnect "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1/ionscalev1connect"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
"google.golang.org/protobuf/types/known/durationpb"
"io"
"log"
"net"
"net/http"
"os"
"strings"
"sync"
"testing"
"time"
)
const DefaultTargetVersion = "1.46.0"
var (
setupOnce sync.Once
targetVersion string
pool *dockertest.Pool
)
type Scenario interface {
NewTailscaleNode(hostname string) TailscaleNode
ListMachines(tailnetID uint64) []*api.Machine
CreateAuthKey(tailnetID uint64, ephemeral bool) string
CreateTailnet(name string) *api.Tailnet
}
type scenario struct {
t *testing.T
pool *dockertest.Pool
network *dockertest.Network
ionscale *dockertest.Resource
resources []*dockertest.Resource
client ionscaleconnect.IonscaleServiceClient
}
func (s *scenario) CreateTailnet(name string) *api.Tailnet {
createTailnetResponse, err := s.client.CreateTailnet(context.Background(), connect.NewRequest(&api.CreateTailnetRequest{Name: name}))
if err != nil {
s.t.Fatal(err)
}
return createTailnetResponse.Msg.GetTailnet()
}
func (s *scenario) CreateAuthKey(tailnetID uint64, ephemeral bool) string {
key, err := s.client.CreateAuthKey(context.Background(), connect.NewRequest(&api.CreateAuthKeyRequest{TailnetId: tailnetID, Ephemeral: ephemeral, Tags: []string{"tag:test"}, Expiry: durationpb.New(60 * time.Minute)}))
if err != nil {
s.t.Fatal(err)
}
return key.Msg.Value
}
func (s *scenario) ListMachines(tailnetID uint64) []*api.Machine {
machines, err := s.client.ListMachines(context.Background(), connect.NewRequest(&api.ListMachinesRequest{TailnetId: tailnetID}))
if err != nil {
s.t.Fatal(err)
}
return machines.Msg.Machines
}
func (s *scenario) NewTailscaleNode(hostname string) TailscaleNode {
tailscaleOptions := &dockertest.RunOptions{
Repository: fmt.Sprintf("ts-%s", strings.Replace(targetVersion, ".", "-", -1)),
Hostname: hostname,
Networks: []*dockertest.Network{s.network},
ExposedPorts: []string{"1055"},
Cmd: []string{
"/app/tailscaled", "--tun", "userspace-networking", "--socks5-server", "0.0.0.0:1055", "--socket", "/tmp/tailscaled.sock",
},
}
resource, err := s.pool.RunWithOptions(
tailscaleOptions,
restartPolicy,
)
if err != nil {
s.t.Fatal(err)
}
err = s.pool.Retry(portCheck(resource.GetPort("1055/tcp")))
if err != nil {
s.t.Fatal(err)
}
s.resources = append(s.resources, resource)
return &tailscaleNode{
t: s.t,
loginServer: "http://ionscale:8080",
hostname: hostname,
resource: resource,
}
}
func Run(t *testing.T, f func(s Scenario)) {
t.Parallel()
if testing.Short() {
t.Skip("skipped due to -short flag")
}
setupOnce.Do(prepareDockerPoolAndImages)
if pool == nil {
t.FailNow()
}
var err error
s := &scenario{t: t}
defer func() {
for _, r := range s.resources {
_ = pool.Purge(r)
}
if s.ionscale != nil {
_ = pool.Purge(s.ionscale)
}
if s.network != nil {
_ = s.network.Close()
}
s.resources = nil
s.network = nil
}()
if s.pool, err = dockertest.NewPool(""); err != nil {
t.Fatal(err)
}
s.network, err = pool.CreateNetwork("ionscale-test")
if err != nil {
t.Fatal(err)
}
currentPath, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
ionscale := &dockertest.RunOptions{
Hostname: "ionscale",
Repository: "ionscale-test",
Mounts: []string{
fmt.Sprintf("%s/config:/etc/ionscale", currentPath),
},
Networks: []*dockertest.Network{s.network},
ExposedPorts: []string{"8080"},
Cmd: []string{"server", "--config", "/etc/ionscale/config.yaml"},
}
s.ionscale, err = pool.RunWithOptions(ionscale, restartPolicy)
if err != nil {
t.Fatal(err)
}
port := s.ionscale.GetPort("8080/tcp")
err = pool.Retry(httpCheck(port, "/key"))
if err != nil {
t.Fatal(err)
}
auth, err := ionscaleclt.LoadClientAuth("804ecd57365342254ce6647da5c249e85c10a0e51e74856bfdf292a2136b4249")
if err != nil {
t.Fatal(err)
}
s.client, err = ionscaleclt.NewClient(auth, fmt.Sprintf("http://localhost:%s", port), true)
if err != nil {
t.Fatal(err)
}
f(s)
}
func restartPolicy(config *docker.HostConfig) {
config.AutoRemove = true
config.RestartPolicy = docker.RestartPolicy{
Name: "no",
}
}
func portCheck(port string) func() error {
return func() error {
conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%s", port))
if err != nil {
return err
}
defer conn.Close()
return nil
}
}
func httpCheck(port string, path string) func() error {
return func() error {
url := fmt.Sprintf("http://localhost:%s%s", port, path)
resp, err := http.Get(url)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("status code not OK")
}
return nil
}
}
func prepareDockerPoolAndImages() {
targetVersion = os.Getenv("IONSCALE_TESTS_TS_TARGET_VERSION")
if targetVersion == "" {
targetVersion = DefaultTargetVersion
}
pool, _ = dockertest.NewPool("")
buildOpts := &dockertest.BuildOptions{
ContextDir: "./docker/tailscale",
BuildArgs: []docker.BuildArg{
{
Name: "TAILSCALE_VERSION",
Value: targetVersion,
},
},
}
err := pool.Client.BuildImage(docker.BuildImageOptions{
Name: fmt.Sprintf("ts-%s", strings.Replace(targetVersion, ".", "-", -1)),
Dockerfile: buildOpts.Dockerfile,
OutputStream: io.Discard,
ContextDir: buildOpts.ContextDir,
BuildArgs: buildOpts.BuildArgs,
Platform: buildOpts.Platform,
})
if err != nil {
log.Fatal(err)
}
buildOpts = &dockertest.BuildOptions{
ContextDir: "../",
Dockerfile: "tests/docker/ionscale/Dockerfile",
}
err = pool.Client.BuildImage(docker.BuildImageOptions{
Name: "ionscale-test",
Dockerfile: buildOpts.Dockerfile,
OutputStream: io.Discard,
ContextDir: buildOpts.ContextDir,
BuildArgs: buildOpts.BuildArgs,
Platform: buildOpts.Platform,
})
if err != nil {
log.Fatal(err)
}
}