Compare commits

...

39 Commits

Author SHA1 Message Date
Johan Siebens ddc65d2df9 feat: add support for ssh acl policies 2022-10-08 07:26:30 +02:00
Johan Siebens c70a4cfe6a fix: don't send peer capabilities to nodes 2022-10-07 20:10:30 +02:00
Johan Siebens 5bf919da12 fix: don't send derp map if not changed 2022-10-07 16:43:37 +02:00
Johan Siebens 6d4a7b7014 feat: set default derp map configuration 2022-10-07 16:31:57 +02:00
Johan Siebens bc1f188816 feat: add some command aliases 2022-10-07 15:43:51 +02:00
Johan Siebens 9522e3531e feat: enable/disable taildrop and service collection 2022-10-07 10:12:31 +02:00
Johan Siebens 1e3541e7c8 fix: remove check on nameservers as it is not required anymore for MagicDNS 2022-10-06 21:30:34 +02:00
Johan Siebens c3e1344199 fix: add admin capability flag when needed 2022-10-06 21:19:58 +02:00
Johan Siebens 70b9373df3 feat: set derp map for a tailnet 2022-10-04 16:06:15 +02:00
Johan Siebens 58de86a978 fix: use crypto/rand 2022-10-03 15:52:39 +02:00
Johan Siebens 2e57338b54 feat: add id token handler 2022-09-30 16:13:25 +02:00
Johan Siebens 7cadcc9085 fix: move auth config a level deeper 2022-09-30 15:39:19 +02:00
Johan Siebens 22cfe60c7d feat: add support for https certs 2022-09-30 15:31:57 +02:00
Johan Siebens 45572397ea fix: use correct context 2022-09-28 14:58:04 +02:00
Johan Siebens e5a3d3c589 fix: sanitize tailnet name properly 2022-09-28 11:50:31 +02:00
Johan Siebens 2a5fe7f136 feat: generate control keys by default in db 2022-09-27 16:40:48 +02:00
Johan Siebens 7ee4b27688 feat: add cmd to enable/disable exit nodes and print information properly 2022-09-27 11:14:22 +02:00
Johan Siebens 69f7c22307 feat: add support for autogroup:internet in acls 2022-09-27 09:36:10 +02:00
Johan Siebens 4e5f89ab7e feat: add autoapprovers support in acls 2022-09-27 07:52:37 +02:00
Johan Siebens c1ffe03e81 feat: mark machines as ephemeral when requested by the client 2022-09-25 08:11:10 +02:00
Johan Siebens 7ad91c4c20 feat: add support for autogroup:self and autogroup:members 2022-09-24 15:42:55 +02:00
Johan Siebens fb04248db4 chore(ci): add some security analysis 2022-09-24 09:37:26 +02:00
Johan Siebens d84bad12d0 chore: fixes 2022-09-24 08:16:52 +02:00
Johan Siebens cadf938e2a chore(ci): update build targets 2022-09-24 08:09:26 +02:00
Johan Siebens 980ae6dd85 feat: add flags to create tailnet with some proper default IAM policies 2022-09-23 14:04:23 +02:00
Johan Siebens 6e3e22bc72 chore: remove config flags for now 2022-09-23 10:36:55 +02:00
Johan Siebens 0051eec355 feat: configure magic dns suffix 2022-09-22 18:23:42 +02:00
Johan Siebens 617575803c chore: remove auth provider config from flags and env variables 2022-09-22 18:05:03 +02:00
Johan Siebens 8c6ea9041b fix: system admin can always use tags 2022-09-22 16:49:38 +02:00
Johan Siebens c6ebeb36bc fix: improve some default values 2022-09-22 15:47:35 +02:00
Johan Siebens d87c7252c2 chore: update script 2022-09-22 14:31:23 +02:00
Johan Siebens bfcf0c7925 feat: configure server using flags 2022-09-21 08:15:39 +02:00
Johan Siebens aea3d2d6a9 chore: some better error descriptions 2022-09-20 12:54:29 +02:00
Johan Siebens 9781e75833 chore: add data dir 2022-09-20 12:41:46 +02:00
Johan Siebens 47b15d31f0 fix: make config file optional 2022-09-20 12:41:22 +02:00
Johan Siebens ec353f7add feat: flag to disable newline in genkey output 2022-09-20 09:06:01 +02:00
Johan Siebens 92ca75b7f4 fix: remove _ from tag_owners, make it more compliant 2022-09-19 12:01:55 +02:00
Johan Siebens 1702cf135e fix: change precedence order, env variables overrule file config 2022-09-17 08:34:37 +02:00
Johan Siebens b65119bbba fix: system admin is always a tag owner 2022-09-17 07:13:06 +02:00
71 changed files with 7163 additions and 1063 deletions
+4
View File
@@ -4,6 +4,9 @@ on:
push:
branches:
- '*'
pull_request:
branches:
- main
jobs:
build:
@@ -19,4 +22,5 @@ jobs:
- name: Build
run: |
go test ./...
go build cmd/ionscale/main.go
+48
View File
@@ -0,0 +1,48 @@
name: "Security Analysis"
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0'
jobs:
codeql:
name: CodeQL
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: go
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
trivy:
name: Trivy
runs-on: ubuntu-latest
permissions:
actions: read
security-events: write
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ghcr.io/jsiebens/ionscale:latest
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: 'trivy-results.sarif'
+6 -1
View File
@@ -1,3 +1,8 @@
FROM alpine:3.16.2
FROM --platform=${BUILDPLATFORM:-linux/amd64} alpine:3.16.2
COPY ionscale /usr/local/bin/ionscale
RUN mkdir -p /data/ionscale
WORKDIR /data/ionscale
ENTRYPOINT ["/usr/local/bin/ionscale"]
+44 -3
View File
@@ -5,24 +5,32 @@ go 1.19
require (
github.com/apparentlymart/go-cidr v1.1.0
github.com/bufbuild/connect-go v0.4.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.4.6
github.com/go-gormigrate/gormigrate/v2 v2.0.2
github.com/golang-jwt/jwt/v4 v4.4.2
github.com/google/uuid v1.3.0
github.com/hashicorp/go-bexpr v0.1.11
github.com/hashicorp/go-hclog v1.3.0
github.com/hashicorp/go-multierror v1.1.1
github.com/imdario/mergo v0.3.12
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/lib/pq v1.10.6
github.com/libdns/azure v0.2.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/libdns v0.2.1
github.com/libdns/route53 v1.2.2
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/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.13.0
github.com/rodaine/table v1.0.1
github.com/sony/sonyflake v1.1.0
@@ -33,6 +41,7 @@ require (
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde
google.golang.org/protobuf v1.28.1
gopkg.in/square/go-jose.v2 v2.6.0
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/postgres v1.3.9
@@ -42,16 +51,45 @@ require (
)
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-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
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/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // 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.18.1 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/go-querystring v1.0.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/hashicorp/errwrap v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
@@ -64,11 +102,11 @@ require (
github.com/jackc/pgx/v4 v4.17.2 // 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.3.1 // indirect
github.com/libdns/libdns v0.2.1 // 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
@@ -86,6 +124,7 @@ require (
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
@@ -98,9 +137,11 @@ require (
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
golang.org/x/tools v0.1.12 // indirect
golang.zx2c4.com/wireguard/windows v0.4.10 // 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
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
modernc.org/libc v1.18.0 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.3.0 // indirect
+106
View File
@@ -27,6 +27,8 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go v0.101.1/go.mod h1:55HwjsGW4CHD3JrNuMdZtSDsgTs0CuCB/bBTugD+7AA=
cloud.google.com/go v0.102.0 h1:DAq3r8y4mDgyB/ZPJ9v/5VJNqjgJAxTn6ZYLlUywOu8=
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
@@ -39,6 +41,7 @@ cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJW
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk=
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
@@ -52,9 +55,33 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.22.0/go.mod h1:GbaLEoMqbVm6sx3Z0R++gSiBlgMv6yUi2q1DeGFKQgE=
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/mkcert v1.4.3 h1:axpnmtrZMM8u5Hf4N3UXxboGemMOV+Tn+e+pkHM6E3o=
github.com/Azure/azure-sdk-for-go v52.4.0+incompatible h1:NpkT8MjJJMcgPJ5Q9E66QUgY9QRyxqM8MFx2P29uQZ4=
github.com/Azure/azure-sdk-for-go v52.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.17 h1:2zCdHwNgRH+St1J+ZMf66xI8aLr/5KMy+wWLH97zwYM=
github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
github.com/Azure/go-autorest/autorest/adal v0.9.11 h1:L4/pmq7poLdsy41Bj1FayKvBhayuWRYkx9HU5i4Ybl0=
github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.7 h1:8DQB8yl7aLQuP+nuR5e2RO6454OvFlSTXXaNHshc16s=
github.com/Azure/go-autorest/autorest/azure/auth v0.5.7/go.mod h1:AkzUsqkrdmNhfP2i54HqINVQopw0CLDnvHpJ88Zz1eI=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 h1:dMOmEJfkLKW/7JsokJqkyoYSgmR08hi9KrhjZb+JALY=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM=
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk=
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8Pcx+3oqrE=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@@ -73,6 +100,39 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4=
github.com/aws/aws-sdk-go-v2 v1.10.0/go.mod h1:U/EyyVvKtzmFeQQcca7eBotKdlpcP2zzU6bXBYcf7CE=
github.com/aws/aws-sdk-go-v2 v1.11.2 h1:SDiCYqxdIYi6HgQfAWRhgdZrdnOuGyLDJVRSWLeHWvs=
github.com/aws/aws-sdk-go-v2 v1.11.2/go.mod h1:SQfA+m2ltnu1cA0soUkj4dRSsmITiVQUJvBIZjzfPyQ=
github.com/aws/aws-sdk-go-v2/config v1.9.0/go.mod h1:qhK5NNSgo9/nOSMu3HyE60WHXZTWTHTgd5qtIF44vOQ=
github.com/aws/aws-sdk-go-v2/config v1.11.0 h1:Czlld5zBB61A3/aoegA9/buZulwL9mHHfizh/Oq+Kqs=
github.com/aws/aws-sdk-go-v2/config v1.11.0/go.mod h1:VrQDJGFBM5yZe+IOeenNZ/DWoErdny+k2MHEIpwDsEY=
github.com/aws/aws-sdk-go-v2/credentials v1.5.0/go.mod h1:kvqTkpzQmzri9PbsiTY+LvwFzM0gY19emlAWwBOJMb0=
github.com/aws/aws-sdk-go-v2/credentials v1.6.4 h1:2hvbUoHufns0lDIsaK8FVCMukT1WngtZPavN+W2FkSw=
github.com/aws/aws-sdk-go-v2/credentials v1.6.4/go.mod h1:tTrhvBPHyPde4pdIPSba4Nv7RYr4wP9jxXEDa1bKn/8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.7.0/go.mod h1:KqEkRkxm/+1Pd/rENRNbQpfblDBYeg5HDSqjB6ks8hA=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.8.2 h1:KiN5TPOLrEjbGCvdTQR4t0U4T87vVwALZ5Bg3jpMqPY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.8.2/go.mod h1:dF2F6tXEOgmW5X1ZFO/EPtWrcm7XkW07KNcJUGNtt4s=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.2 h1:XJLnluKuUxQG255zPNe+04izXl7GSyUVafIsgfv9aw4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.2/go.mod h1:SgKKNBIoDC/E1ZCDhhMW3yalWjwuLjMcpLzsM/QQnWo=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.2 h1:EauRoYZVNPlidZSZJDscjJBQ22JhVF2+tdteatax2Ak=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.0.2/go.mod h1:xT4XX6w5Sa3dhg50JrYyy3e4WPYo/+WjY/BXtqXVunU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.5/go.mod h1:6ZBTuDmvpCOD4Sf1i2/I3PgftlEcDGgvi8ocq64oQEg=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.2 h1:IQup8Q6lorXeiA/rK72PeToWoWK8h7VAPgHNWdSrtgE=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.2/go.mod h1:VITe/MdW6EMXPb0o0txu/fsonXbMHUU2OC2Qp7ivU4o=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.4.0/go.mod h1:X5/JuOxPLU/ogICgDTtnpfaQzdQJO0yKDcpoxWLLJ8Y=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.5.2 h1:CKdUNKmuilw/KNmO2Q53Av8u+ZyXMC2M9aX8Z+c/gzg=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.5.2/go.mod h1:FgR1tCsn8C6+Hf+N5qkfrE4IXvUL1RgW87sunJ+5J4I=
github.com/aws/aws-sdk-go-v2/service/route53 v1.12.0 h1:XNmW6Z/l4NL/Glz76gqAb6WOgdSYC2a1T0YBBEHfQ58=
github.com/aws/aws-sdk-go-v2/service/route53 v1.12.0/go.mod h1:LbPVLMeOEGLIW54yuMayW70DcTtsb+17ekL5j48deF4=
github.com/aws/aws-sdk-go-v2/service/sso v1.5.0/go.mod h1:GsqaJOJeOfeYD88/2vHWKXegvDRofDqWwC5i48A2kgs=
github.com/aws/aws-sdk-go-v2/service/sso v1.6.2 h1:2IDmvSb86KT44lSg1uU4ONpzgWLOuApRl6Tg54mZ6Dk=
github.com/aws/aws-sdk-go-v2/service/sso v1.6.2/go.mod h1:KnIpszaIdwI33tmc/W/GGXyn22c1USYxA/2KyvoeDY0=
github.com/aws/aws-sdk-go-v2/service/sts v1.8.0/go.mod h1:dOlm91B439le5y1vtPCk5yJtbx3RdT3hRGYRY8TYKvQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.11.1 h1:QKR7wy5e650q70PFKMfGF9sTo0rZgUevSSJ4wxmyWXk=
github.com/aws/aws-sdk-go-v2/service/sts v1.11.1/go.mod h1:UV2N5HaPfdbDpkgkz4sRzWCvQswZjdO1FfqCWl0t7RA=
github.com/aws/smithy-go v1.8.1/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/aws/smithy-go v1.9.0 h1:c7FUdEqrQA1/UVKKCNDFQPNKGp4FQg3YW4Ck5SLTG58=
github.com/aws/smithy-go v1.9.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -81,6 +141,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bufbuild/connect-go v0.4.0 h1:fIMyUYG8mXSTH+nnlOx9KmRUf3mBF0R2uKK+BQBoOHE=
github.com/bufbuild/connect-go v0.4.0/go.mod h1:ZEtBnQ7J/m7bvWOW+H8T/+hKQCzPVfhhhICuvtcnjlI=
github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II=
github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
github.com/caddyserver/certmagic v0.17.1 h1:VrWANhQAj3brK7jAUKyN6XBHg56WsyorI/84Ilq1tCQ=
github.com/caddyserver/certmagic v0.17.1/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -116,6 +178,11 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA=
github.com/digitalocean/godo v1.41.0 h1:WYy7MIVVhTMZUNB+UA3irl2V9FyDJeDttsifYyn7jYA=
github.com/digitalocean/godo v1.41.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -130,6 +197,8 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss=
github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -175,6 +244,8 @@ github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -228,11 +299,16 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -251,6 +327,7 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa h1:7MYGT2XEMam7Mtzv1yDUYXANedWvwk3HKkR3MyGowy8=
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
@@ -258,6 +335,7 @@ github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pf
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk=
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
@@ -276,6 +354,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@@ -336,6 +416,10 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
@@ -386,8 +470,19 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libdns/azure v0.2.0 h1:SVYG+iMKtSpSJZBZ0hjETAMNscPoWRMJI7nnlLonwD4=
github.com/libdns/azure v0.2.0/go.mod h1:vu7sD/dXAExlzdne/OTPKTEOXOpDUxPuAKQwqzUT8nk=
github.com/libdns/cloudflare v0.1.0 h1:93WkJaGaiXCe353LHEP36kAWCUw0YjFqwhkBkU2/iic=
github.com/libdns/cloudflare v0.1.0/go.mod h1:a44IP6J1YH6nvcNl1PverfJviADgXUnsozR3a7vBKN8=
github.com/libdns/digitalocean v0.0.0-20220518195853-a541bc8aa80f h1:Y0JkwI0Uip+Zrh71aHLmNz150cKnWuC+535v/zLS8zo=
github.com/libdns/digitalocean v0.0.0-20220518195853-a541bc8aa80f/go.mod h1:B2TChhOTxvBflpRTHlguXWtwa1Ha5WI6JkB6aCViM+0=
github.com/libdns/googleclouddns v1.0.2 h1:r7zZKDlMUglvOT6hmpZuMmxld8KpddbsVhEETEHRjjg=
github.com/libdns/googleclouddns v1.0.2/go.mod h1:Qogt1qOp5teTZAyiKfkhBzI5Ri+6Z/XA16y6eJz2veA=
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/libdns/route53 v1.2.2 h1:ZnlxO2w8ftO/aR0PNRRB8lrG6AcKPOl/H0vU8mb/Ixo=
github.com/libdns/route53 v1.2.2/go.mod h1:Vu827KwORxYR2I6iGsu8IKh4MESliECL7VA4pAsn95o=
github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
@@ -537,6 +632,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@@ -578,7 +674,9 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -887,6 +985,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.zx2c4.com/wireguard v0.0.0-20210905140043-2ef39d47540c/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8=
golang.zx2c4.com/wireguard/windows v0.4.10 h1:HmjzJnb+G4NCdX+sfjsQlsxGPuYaThxRbZUZFLyR0/s=
@@ -927,8 +1026,10 @@ google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/S
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
google.golang.org/api v0.84.0 h1:NMB9J4cCxs9xEm+1Z9QiO3eFvn7EnQj3Eo3hN6ugVlg=
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1006,15 +1107,18 @@ google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 h1:4SPz2GL2CXJt28MTF8V6Ap/9ZiVbQlJeGSd9qtA7DLs=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -1047,6 +1151,8 @@ google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+4 -14
View File
@@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"github.com/lib/pq"
"github.com/pkg/errors"
"time"
)
@@ -16,13 +15,9 @@ type pgPubsub struct {
target Pubsub
}
// NewPubsub creates a new Pubsub implementation using a PostgreSQL connection.
func NewPubsub(ctx context.Context, database *sql.DB, connectURL string) (Pubsub, error) {
// Creates a new listener using pq.
errCh := make(chan error)
listener := pq.NewListener(connectURL, time.Second, time.Minute, func(event pq.ListenerEventType, err error) {
// This callback gets events whenever the connection state changes.
// Don't send if the errChannel has already been closed.
select {
case <-errCh:
return
@@ -35,14 +30,14 @@ func NewPubsub(ctx context.Context, database *sql.DB, connectURL string) (Pubsub
select {
case err := <-errCh:
if err != nil {
return nil, errors.Errorf("create pq listener: %w", err)
return nil, fmt.Errorf("create pq listener: %w", err)
}
case <-ctx.Done():
return nil, ctx.Err()
}
if err := listener.Listen("ionscale_events"); err != nil {
return nil, errors.Errorf("listen: %w", err)
return nil, fmt.Errorf("listen: %w", err)
}
pubsub := &pgPubsub{
@@ -55,7 +50,6 @@ func NewPubsub(ctx context.Context, database *sql.DB, connectURL string) (Pubsub
return pubsub, nil
}
// Close closes the pubsub instance.
func (p *pgPubsub) Close() error {
return p.pgListener.Close()
}
@@ -75,18 +69,14 @@ func (p *pgPubsub) Publish(tailnet uint64, message *Signal) error {
return err
}
// This is safe because we are calling pq.QuoteLiteral. pg_notify doesn't
// support the first parameter being a prepared statement.
//nolint:gosec
_, err = p.db.ExecContext(context.Background(), `select pg_notify(`+pq.QuoteLiteral("ionscale_events")+`, $1)`, payload)
if err != nil {
fmt.Println(err)
return errors.Errorf("exec pg_notify: %w", err)
return fmt.Errorf("exec pg_notify: %w", err)
}
return nil
}
// listen begins receiving messages on the pq listener.
func (p *pgPubsub) listen(ctx context.Context) {
var (
notif *pq.Notification
+3 -2
View File
@@ -15,8 +15,9 @@ import (
func authkeysCommand() *coral.Command {
command := &coral.Command{
Use: "auth-keys",
Short: "Manage ionscale auth keys",
Use: "auth-keys",
Aliases: []string{"auth-key"},
Short: "Manage ionscale auth keys",
}
command.AddCommand(createAuthkeysCommand())
+42 -16
View File
@@ -8,25 +8,26 @@ import (
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"gopkg.in/yaml.v2"
"io/ioutil"
"os"
"tailscale.com/tailcfg"
)
func derpMapCommand() *coral.Command {
func systemCommand() *coral.Command {
command := &coral.Command{
Use: "derp-map",
Short: "Manage DERP Map configuration",
Use: "system",
Short: "Manage global system configurations",
}
command.AddCommand(getDERPMap())
command.AddCommand(setDERPMap())
command.AddCommand(getDefaultDERPMap())
command.AddCommand(setDefaultDERPMap())
command.AddCommand(resetDefaultDERPMap())
return command
}
func getDERPMap() *coral.Command {
func getDefaultDERPMap() *coral.Command {
command := &coral.Command{
Use: "get",
Use: "get-derp-map",
Short: "Get the DERP Map configuration",
SilenceUsage: true,
}
@@ -43,7 +44,7 @@ func getDERPMap() *coral.Command {
return err
}
resp, err := client.GetDERPMap(context.Background(), connect.NewRequest(&api.GetDERPMapRequest{}))
resp, err := client.GetDefaultDERPMap(context.Background(), connect.NewRequest(&api.GetDefaultDERPMapRequest{}))
if err != nil {
return err
@@ -63,7 +64,6 @@ func getDERPMap() *coral.Command {
return err
}
fmt.Println()
fmt.Println(string(marshal))
} else {
marshal, err := yaml.Marshal(derpMap)
@@ -71,7 +71,6 @@ func getDERPMap() *coral.Command {
return err
}
fmt.Println()
fmt.Println(string(marshal))
}
@@ -81,9 +80,9 @@ func getDERPMap() *coral.Command {
return command
}
func setDERPMap() *coral.Command {
func setDefaultDERPMap() *coral.Command {
command := &coral.Command{
Use: "set",
Use: "set-derp-map",
Short: "Set the DERP Map configuration",
SilenceUsage: true,
}
@@ -99,12 +98,12 @@ func setDERPMap() *coral.Command {
return err
}
rawJson, err := ioutil.ReadFile(file)
rawJson, err := os.ReadFile(file)
if err != nil {
return err
}
resp, err := grpcClient.SetDERPMap(context.Background(), connect.NewRequest(&api.SetDERPMapRequest{Value: rawJson}))
resp, err := grpcClient.SetDefaultDERPMap(context.Background(), connect.NewRequest(&api.SetDefaultDERPMapRequest{Value: rawJson}))
if err != nil {
return err
}
@@ -114,7 +113,34 @@ func setDERPMap() *coral.Command {
return err
}
fmt.Println()
fmt.Println("DERP Map updated successfully")
return nil
}
return command
}
func resetDefaultDERPMap() *coral.Command {
command := &coral.Command{
Use: "reset-derp-map",
Short: "Reset the DERP Map to the default configuration",
SilenceUsage: true,
}
var target = Target{}
target.prepareCommand(command)
command.RunE = func(command *coral.Command, args []string) error {
grpcClient, err := target.createGRPCClient()
if err != nil {
return err
}
if _, err := grpcClient.ResetDefaultDERPMap(context.Background(), connect.NewRequest(&api.ResetDefaultDERPMapRequest{})); err != nil {
return err
}
fmt.Println("DERP Map updated successfully")
return nil
+85
View File
@@ -172,3 +172,88 @@ func setDNSConfigCommand() *coral.Command {
return command
}
func enableHttpsCommand() *coral.Command {
command := &coral.Command{
Use: "enable-https",
Short: "Enable HTTPS certificates",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var alias string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
command.Flags().StringVar(&alias, "alias", "", "")
command.PreRunE = checkRequiredTailnetAndTailnetIdFlags
command.RunE = func(command *coral.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
req := api.EnableHttpsCertificatesRequest{
TailnetId: tailnet.Id,
Alias: alias,
}
if _, err := client.EnableHttpsCertificates(context.Background(), connect.NewRequest(&req)); err != nil {
return err
}
return nil
}
return command
}
func disableHttpsCommand() *coral.Command {
command := &coral.Command{
Use: "disable-https",
Short: "Disable HTTPS certificates",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
req := api.DisableHttpsCertificatesRequest{
TailnetId: tailnet.Id,
}
if _, err := client.DisableHttpsCertificates(context.Background(), connect.NewRequest(&req)); err != nil {
return err
}
return nil
}
return command
}
+9 -1
View File
@@ -12,9 +12,17 @@ func keyCommand() *coral.Command {
SilenceUsage: true,
}
var disableNewLine bool
command.Flags().BoolVarP(&disableNewLine, "no-newline", "n", false, "do not output a trailing newline")
command.RunE = func(command *coral.Command, args []string) error {
serverKey := key.NewServerKey()
fmt.Println(serverKey.String())
if disableNewLine {
fmt.Print(serverKey.String())
} else {
fmt.Println(serverKey.String())
}
return nil
}
+112 -53
View File
@@ -17,6 +17,7 @@ import (
func machineCommands() *coral.Command {
command := &coral.Command{
Use: "machines",
Aliases: []string{"machine"},
Short: "Manage ionscale machines",
SilenceUsage: true,
}
@@ -29,6 +30,8 @@ func machineCommands() *coral.Command {
command.AddCommand(enableMachineRoutesCommand())
command.AddCommand(disableMachineRoutesCommand())
command.AddCommand(enableMachineKeyExpiryCommand())
command.AddCommand(enableExitNodeCommand())
command.AddCommand(disableExitNodeCommand())
command.AddCommand(disableMachineKeyExpiryCommand())
return command
@@ -126,6 +129,16 @@ func getMachineCommand() *coral.Command {
}
}
if m.AdvertisedExitNode {
if m.EnabledExitNode {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "enabled")
} else {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "disabled")
}
} else {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "no")
}
return nil
}
@@ -279,25 +292,7 @@ func getMachineRoutesCommand() *coral.Command {
return err
}
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
defer w.Flush()
for i, t := range resp.Msg.AdvertisedRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Advertised routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
for i, t := range resp.Msg.EnabledRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Enabled routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
printMachinesRoutesResponse(resp.Msg)
return nil
}
@@ -341,25 +336,7 @@ func enableMachineRoutesCommand() *coral.Command {
return err
}
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
defer w.Flush()
for i, t := range resp.Msg.AdvertisedRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Advertised routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
for i, t := range resp.Msg.EnabledRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Enabled routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
printMachinesRoutesResponse(resp.Msg)
return nil
}
@@ -401,26 +378,76 @@ func disableMachineRoutesCommand() *coral.Command {
return err
}
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
defer w.Flush()
printMachinesRoutesResponse(resp.Msg)
for i, t := range resp.Msg.AdvertisedRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Advertised routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
return nil
}
return command
}
func enableExitNodeCommand() *coral.Command {
command := &coral.Command{
Use: "enable-exit-node",
Short: "Enable given machine as an exit node",
SilenceUsage: true,
}
var machineID uint64
var target = Target{}
target.prepareCommand(command)
command.Flags().Uint64Var(&machineID, "machine-id", 0, "Machine ID")
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
}
for i, t := range resp.Msg.EnabledRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Enabled routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
req := api.EnableExitNodeRequest{MachineId: machineID}
resp, err := client.EnableExitNode(context.Background(), connect.NewRequest(&req))
if err != nil {
return err
}
printMachinesRoutesResponse(resp.Msg)
return nil
}
return command
}
func disableExitNodeCommand() *coral.Command {
command := &coral.Command{
Use: "disable-exit-node",
Short: "Disable given machine as an exit node",
SilenceUsage: true,
}
var machineID uint64
var target = Target{}
target.prepareCommand(command)
command.Flags().Uint64Var(&machineID, "machine-id", 0, "Machine ID")
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
}
req := api.DisableExitNodeRequest{MachineId: machineID}
resp, err := client.DisableExitNode(context.Background(), connect.NewRequest(&req))
if err != nil {
return err
}
printMachinesRoutesResponse(resp.Msg)
return nil
}
@@ -472,3 +499,35 @@ func configureSetMachineKeyExpiryCommand(command *coral.Command, v bool) *coral.
return command
}
func printMachinesRoutesResponse(msg *api.GetMachineRoutesResponse) {
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
defer w.Flush()
for i, t := range msg.AdvertisedRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Advertised routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
for i, t := range msg.EnabledRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Enabled routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
if msg.AdvertisedExitNode {
if msg.EnabledExitNode {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "enabled")
} else {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "disabled")
}
} else {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "no")
}
}
+1 -1
View File
@@ -9,13 +9,13 @@ func Command() *coral.Command {
rootCmd.AddCommand(configureCommand())
rootCmd.AddCommand(keyCommand())
rootCmd.AddCommand(authCommand())
rootCmd.AddCommand(derpMapCommand())
rootCmd.AddCommand(serverCommand())
rootCmd.AddCommand(versionCommand())
rootCmd.AddCommand(tailnetCommand())
rootCmd.AddCommand(authkeysCommand())
rootCmd.AddCommand(machineCommands())
rootCmd.AddCommand(userCommands())
rootCmd.AddCommand(systemCommand())
return rootCmd
}
+1 -1
View File
@@ -15,7 +15,7 @@ func serverCommand() *coral.Command {
var configFile string
command.Flags().StringVarP(&configFile, "config", "c", "ionscale.yaml", "Path to the configuration file.")
command.Flags().StringVarP(&configFile, "config", "c", "", "Path to the configuration file.")
command.RunE = func(command *coral.Command, args []string) error {
+469 -4
View File
@@ -2,17 +2,24 @@ package cmd
import (
"context"
"encoding/json"
"fmt"
"github.com/bufbuild/connect-go"
idomain "github.com/jsiebens/ionscale/internal/domain"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/rodaine/table"
"gopkg.in/yaml.v3"
"os"
"strings"
"tailscale.com/tailcfg"
)
func tailnetCommand() *coral.Command {
command := &coral.Command{
Use: "tailnets",
Short: "Manage ionscale tailnets",
Use: "tailnets",
Aliases: []string{"tailnet"},
Short: "Manage ionscale tailnets",
}
command.AddCommand(listTailnetsCommand())
@@ -24,6 +31,17 @@ func tailnetCommand() *coral.Command {
command.AddCommand(setACLConfigCommand())
command.AddCommand(getIAMPolicyCommand())
command.AddCommand(setIAMPolicyCommand())
command.AddCommand(enableHttpsCommand())
command.AddCommand(disableHttpsCommand())
command.AddCommand(enableServiceCollectionCommand())
command.AddCommand(disableServiceCollectionCommand())
command.AddCommand(enableFileSharingCommand())
command.AddCommand(disableFileSharingCommand())
command.AddCommand(enableSSHCommand())
command.AddCommand(disableSSHCommand())
command.AddCommand(getDERPMap())
command.AddCommand(setDERPMap())
command.AddCommand(resetDERPMap())
return command
}
@@ -71,20 +89,62 @@ func createTailnetsCommand() *coral.Command {
}
var name string
var domain string
var email string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVarP(&name, "name", "n", "", "")
_ = command.MarkFlagRequired("name")
command.Flags().StringVar(&domain, "domain", "", "")
command.Flags().StringVar(&email, "email", "", "")
command.PreRunE = func(cmd *coral.Command, args []string) error {
if name == "" && email == "" && domain == "" {
return fmt.Errorf("at least flag --name, --email or --domain is required")
}
if domain != "" && email != "" {
return fmt.Errorf("flags --email and --domain are mutually exclusive")
}
return nil
}
command.RunE = func(command *coral.Command, args []string) error {
var tailnetName = ""
var iamPolicy = api.IAMPolicy{}
if len(domain) != 0 {
domainToLower := strings.ToLower(domain)
tailnetName = domainToLower
iamPolicy = api.IAMPolicy{
Filters: []string{fmt.Sprintf("domain == %s", domainToLower)},
}
}
if len(email) != 0 {
emailToLower := strings.ToLower(email)
tailnetName = emailToLower
iamPolicy = api.IAMPolicy{
Emails: []string{emailToLower},
Roles: map[string]string{
emailToLower: string(idomain.UserRoleAdmin),
},
}
}
if len(name) != 0 {
tailnetName = name
}
client, err := target.createGRPCClient()
if err != nil {
return err
}
resp, err := client.CreateTailnet(context.Background(), connect.NewRequest(&api.CreateTailnetRequest{Name: name}))
resp, err := client.CreateTailnet(context.Background(), connect.NewRequest(&api.CreateTailnetRequest{
Name: tailnetName,
IamPolicy: &iamPolicy,
}))
if err != nil {
return err
@@ -143,3 +203,408 @@ func deleteTailnetCommand() *coral.Command {
return command
}
func getDERPMap() *coral.Command {
command := &coral.Command{
Use: "get-derp-map",
Short: "Get the DERP Map configuration",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var asJson bool
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
resp, err := client.GetDERPMap(context.Background(), connect.NewRequest(&api.GetDERPMapRequest{TailnetId: tailnet.Id}))
if err != nil {
return err
}
var derpMap struct {
Regions map[int]*tailcfg.DERPRegion
}
if err := json.Unmarshal(resp.Msg.Value, &derpMap); err != nil {
return err
}
if asJson {
marshal, err := json.MarshalIndent(derpMap, "", " ")
if err != nil {
return err
}
fmt.Println(string(marshal))
} else {
marshal, err := yaml.Marshal(derpMap)
if err != nil {
return err
}
fmt.Println(string(marshal))
}
return nil
}
return command
}
func setDERPMap() *coral.Command {
command := &coral.Command{
Use: "set-derp-map",
Short: "Set the DERP Map configuration",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var file string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
rawJson, err := os.ReadFile(file)
if err != nil {
return err
}
resp, err := client.SetDERPMap(context.Background(), connect.NewRequest(&api.SetDERPMapRequest{TailnetId: tailnet.Id, Value: rawJson}))
if err != nil {
return err
}
var derpMap tailcfg.DERPMap
if err := json.Unmarshal(resp.Msg.Value, &derpMap); err != nil {
return err
}
fmt.Println("DERP Map updated successfully")
return nil
}
return command
}
func resetDERPMap() *coral.Command {
command := &coral.Command{
Use: "reset-derp-map",
Short: "Reset the DERP Map to the default configuration",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
if _, err := client.ResetDERPMap(context.Background(), connect.NewRequest(&api.ResetDERPMapRequest{TailnetId: tailnet.Id})); err != nil {
return err
}
fmt.Println("DERP Map updated successfully")
return nil
}
return command
}
func enableFileSharingCommand() *coral.Command {
command := &coral.Command{
Use: "enable-file-sharing",
Aliases: []string{"enable-taildrop"},
Short: "Enable Taildrop, the file sharing feature",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
req := api.EnableFileSharingRequest{
TailnetId: tailnet.Id,
}
if _, err := client.EnabledFileSharing(context.Background(), connect.NewRequest(&req)); err != nil {
return err
}
return nil
}
return command
}
func disableFileSharingCommand() *coral.Command {
command := &coral.Command{
Use: "disable-file-sharing",
Aliases: []string{"disable-taildrop"},
Short: "Disable Taildrop, the file sharing feature",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
req := api.DisableFileSharingRequest{
TailnetId: tailnet.Id,
}
if _, err := client.DisableFileSharing(context.Background(), connect.NewRequest(&req)); err != nil {
return err
}
return nil
}
return command
}
func enableServiceCollectionCommand() *coral.Command {
command := &coral.Command{
Use: "enable-service-collection",
Short: "Enable monitoring live services running on your networks machines.",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
req := api.EnableServiceCollectionRequest{
TailnetId: tailnet.Id,
}
if _, err := client.EnabledServiceCollection(context.Background(), connect.NewRequest(&req)); err != nil {
return err
}
return nil
}
return command
}
func disableServiceCollectionCommand() *coral.Command {
command := &coral.Command{
Use: "disable-service-collection",
Short: "Disable monitoring live services running on your networks machines.",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
req := api.DisableServiceCollectionRequest{
TailnetId: tailnet.Id,
}
if _, err := client.DisableServiceCollection(context.Background(), connect.NewRequest(&req)); err != nil {
return err
}
return nil
}
return command
}
func enableSSHCommand() *coral.Command {
command := &coral.Command{
Use: "enable-ssh",
Short: "Enable ssh access using tailnet and ACLs.",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
req := api.EnableSSHRequest{
TailnetId: tailnet.Id,
}
if _, err := client.EnabledSSH(context.Background(), connect.NewRequest(&req)); err != nil {
return err
}
return nil
}
return command
}
func disableSSHCommand() *coral.Command {
command := &coral.Command{
Use: "disable-ssh",
Short: "Disable ssh access using tailnet and ACLs.",
SilenceUsage: true,
}
var tailnetID uint64
var tailnetName string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.")
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 {
client, err := target.createGRPCClient()
if err != nil {
return err
}
tailnet, err := findTailnet(client, tailnetName, tailnetID)
if err != nil {
return err
}
req := api.DisableSSHRequest{
TailnetId: tailnet.Id,
}
if _, err := client.DisableSSH(context.Background(), connect.NewRequest(&req)); err != nil {
return err
}
return nil
}
return command
}
+1
View File
@@ -12,6 +12,7 @@ import (
func userCommands() *coral.Command {
command := &coral.Command{
Use: "users",
Aliases: []string{"user"},
Short: "Manage ionscale users",
SilenceUsage: true,
}
+132 -116
View File
@@ -2,7 +2,10 @@ package config
import (
"fmt"
"github.com/caarlos0/env/v6"
"github.com/caddyserver/certmagic"
"github.com/imdario/mergo"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/key"
"github.com/jsiebens/ionscale/internal/util"
"github.com/mitchellh/go-homedir"
@@ -14,16 +17,31 @@ import (
"time"
)
var (
KeepAliveInterval = 1 * time.Minute
const (
defaultKeepAliveInterval = 1 * time.Minute
defaultMagicDNSSuffix = "ionscale.net"
)
func LoadConfig(path string) (*Config, error) {
config, err := defaultConfig()
var (
keepAliveInterval = defaultKeepAliveInterval
magicDNSSuffix = defaultMagicDNSSuffix
certDNSSuffix = ""
)
if err != nil {
return nil, err
}
func KeepAliveInterval() time.Duration {
return keepAliveInterval
}
func MagicDNSSuffix() string {
return magicDNSSuffix
}
func CertDNSSuffix() string {
return certDNSSuffix
}
func LoadConfig(path string) (*Config, error) {
cfg := defaultConfig()
if len(path) != 0 {
expandedPath, err := homedir.Expand(path)
@@ -41,88 +59,62 @@ func LoadConfig(path string) (*Config, error) {
return nil, err
}
if err := yaml.Unmarshal(b, config); err != nil {
if err := yaml.Unmarshal(b, cfg); err != nil {
return nil, err
}
}
KeepAliveInterval = config.PollNet.KeepAliveInterval
return config, nil
}
const (
httpListenAddrKey = "IONSCALE_HTTP_LISTEN_ADDR"
httpsListenAddrKey = "IONSCALE_HTTPS_LISTEN_ADDR"
serverUrlKey = "IONSCALE_SERVER_URL"
keysSystemAdminKeyKey = "IONSCALE_SYSTEM_ADMIN_KEY"
keysControlKeyKey = "IONSCALE_CONTROL_KEY"
keysLegacyControlKeyKey = "IONSCALE_LEGACY_CONTROL_KEY"
databaseUrlKey = "IONSCALE_DB_URL"
tlsDisableKey = "IONSCALE_TLS_DISABLE"
tlsForceHttpsKey = "IONSCALE_TLS_FORCE_HTTPS"
tlsCertFileKey = "IONSCALE_TLS_CERT_FILE"
tlsKeyFileKey = "IONSCALE_TLS_KEY_FILE"
tlsAcmeKey = "IONSCALE_TLS_ACME"
tlsAcmeCAKey = "IONSCALE_TLS_ACME_CA"
tlsAcmeEmailKey = "IONSCALE_TLS_ACME_EMAIL"
tlsAcmePath = "IONSCALE_TLS_ACME_PATH"
pollNetKeepAliveInterval = "IONSCALE_POLL_NET_KEEP_ALIVE_INTERVAL"
metricsListenAddrKey = "IONSCALE_METRICS_LISTEN_ADDR"
loggingLevelKey = "IONSCALE_LOGGING_LEVEL"
loggingFormatKey = "IONSCALE_LOGGING_FORMAT"
loggingFileKey = "IONSCALE_LOGGING_FILE"
authProviderIssuerKey = "IONSCALE_AUTH_PROVIDER_ISSUER"
authProviderClientIdKey = "IONSCALE_AUTH_PROVIDER_CLIENT_ID"
authProviderClientSecretKey = "IONSCALE_AUTH_PROVIDER_CLIENT_SECRET"
authProviderScopesKey = "IONSCALE_AUTH_PROVIDER_SCOPES"
)
func defaultConfig() (*Config, error) {
defaultKeepAliveInterval, err := GetDuration(pollNetKeepAliveInterval, 1*time.Minute)
if err != nil {
envCfg := &Config{}
if err := env.Parse(envCfg, env.Options{Prefix: "IONSCALE_"}); err != nil {
return nil, err
}
c := &Config{
HttpListenAddr: GetString(httpListenAddrKey, ":8080"),
HttpsListenAddr: GetString(httpsListenAddrKey, ":8443"),
MetricsListenAddr: GetString(metricsListenAddrKey, ":9091"),
ServerUrl: GetString(serverUrlKey, "https://localhost:8443"),
Keys: Keys{
SystemAdminKey: GetString(keysSystemAdminKeyKey, ""),
ControlKey: GetString(keysControlKeyKey, ""),
LegacyControlKey: GetString(keysLegacyControlKeyKey, ""),
},
// merge env configuration on top of the default/file configuration
if err := mergo.Merge(cfg, envCfg, mergo.WithOverride); err != nil {
return nil, err
}
keepAliveInterval = cfg.PollNet.KeepAliveInterval
magicDNSSuffix = cfg.DNS.MagicDNSSuffix
if cfg.DNS.Provider.Zone != "" {
if cfg.DNS.Provider.Subdomain == "" {
certDNSSuffix = cfg.DNS.Provider.Zone
} else {
certDNSSuffix = fmt.Sprintf("%s.%s", cfg.DNS.Provider.Subdomain, cfg.DNS.Provider.Zone)
}
}
return cfg, nil
}
func defaultConfig() *Config {
return &Config{
HttpListenAddr: ":8080",
HttpsListenAddr: ":8443",
MetricsListenAddr: ":9091",
ServerUrl: "https://localhost:8843",
Database: Database{
Url: GetString(databaseUrlKey, "ionscale.db"),
Type: "sqlite",
Url: "./ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)",
},
Tls: Tls{
Disable: GetBool(tlsDisableKey, false),
ForceHttps: GetBool(tlsForceHttpsKey, true),
CertFile: GetString(tlsCertFileKey, ""),
KeyFile: GetString(tlsKeyFileKey, ""),
AcmeEnabled: GetBool(tlsAcmeKey, false),
AcmeCA: GetString(tlsAcmeCAKey, certmagic.LetsEncryptProductionCA),
AcmeEmail: GetString(tlsAcmeEmailKey, ""),
AcmePath: GetString(tlsAcmePath, ""),
Disable: false,
ForceHttps: true,
AcmeEnabled: false,
AcmeCA: certmagic.LetsEncryptProductionCA,
AcmePath: "./acme",
},
PollNet: PollNet{
KeepAliveInterval: defaultKeepAliveInterval,
},
AuthProvider: AuthProvider{
Issuer: GetString(authProviderIssuerKey, ""),
ClientID: GetString(authProviderClientIdKey, ""),
ClientSecret: GetString(authProviderClientSecretKey, ""),
Scopes: GetStrings(authProviderScopesKey, nil),
DNS: DNS{
MagicDNSSuffix: defaultMagicDNSSuffix,
},
Logging: Logging{
Level: GetString(loggingLevelKey, "info"),
Format: GetString(loggingFormatKey, ""),
File: GetString(loggingFileKey, ""),
Level: "info",
},
}
return c, nil
}
type ServerKeys struct {
@@ -132,62 +124,79 @@ type ServerKeys struct {
}
type Config struct {
HttpListenAddr string `yaml:"http_listen_addr,omitempty"`
HttpsListenAddr string `yaml:"https_listen_addr,omitempty"`
MetricsListenAddr string `yaml:"metrics_listen_addr,omitempty"`
ServerUrl string `yaml:"server_url,omitempty"`
Tls Tls `yaml:"tls,omitempty"`
PollNet PollNet `yaml:"poll_net,omitempty"`
Keys Keys `yaml:"keys,omitempty"`
Database Database `yaml:"database,omitempty"`
AuthProvider AuthProvider `yaml:"auth_provider,omitempty"`
Logging Logging `yaml:"logging,omitempty"`
HttpListenAddr string `yaml:"http_listen_addr,omitempty" env:"HTTP_LISTEN_ADDR"`
HttpsListenAddr string `yaml:"https_listen_addr,omitempty" env:"HTTPS_LISTEN_ADDR"`
MetricsListenAddr string `yaml:"metrics_listen_addr,omitempty" env:"METRICS_LISTEN_ADDR"`
ServerUrl string `yaml:"server_url,omitempty" env:"SERVER_URL"`
Tls Tls `yaml:"tls,omitempty" envPrefix:"TLS_"`
PollNet PollNet `yaml:"poll_net,omitempty" envPrefix:"POLL_NET_"`
Keys Keys `yaml:"keys,omitempty" envPrefix:"KEYS_"`
Database Database `yaml:"database,omitempty" envPrefix:"DB_"`
Auth Auth `yaml:"auth,omitempty" envPrefix:"AUTH_"`
DNS DNS `yaml:"dns,omitempty"`
Logging Logging `yaml:"logging,omitempty" envPrefix:"LOGGING_"`
}
type Tls struct {
Disable bool `yaml:"disable"`
ForceHttps bool `yaml:"force_https"`
CertFile string `yaml:"cert_file,omitempty"`
KeyFile string `yaml:"key_file,omitempty"`
AcmeEnabled bool `yaml:"acme,omitempty"`
AcmeEmail string `yaml:"acme_email,omitempty"`
AcmeCA string `yaml:"acme_ca,omitempty"`
AcmePath string `yaml:"acme_path,omitempty"`
Disable bool `yaml:"disable" env:"DISABLE"`
ForceHttps bool `yaml:"force_https" env:"FORCE_HTTPS"`
CertFile string `yaml:"cert_file,omitempty" env:"CERT_FILE"`
KeyFile string `yaml:"key_file,omitempty" env:"KEY_FILE"`
AcmeEnabled bool `yaml:"acme,omitempty" env:"ACME_ENABLED"`
AcmeEmail string `yaml:"acme_email,omitempty" env:"ACME_EMAIL"`
AcmeCA string `yaml:"acme_ca,omitempty" env:"ACME_CA"`
AcmePath string `yaml:"acme_path,omitempty" env:"ACME_PATH"`
}
type PollNet struct {
KeepAliveInterval time.Duration `yaml:"keep_alive_interval"`
KeepAliveInterval time.Duration `yaml:"keep_alive_interval" env:"KEEP_ALIVE_INTERVAL"`
}
type Logging struct {
Level string `yaml:"level,omitempty"`
Format string `yaml:"format,omitempty"`
File string `yaml:"file,omitempty"`
Level string `yaml:"level,omitempty" env:"LEVEL"`
Format string `yaml:"format,omitempty" env:"FORMAT"`
File string `yaml:"file,omitempty" env:"FILE"`
}
type Database struct {
Type string `yaml:"type,omitempty"`
Url string `yaml:"url,omitempty"`
Type string `yaml:"type,omitempty" env:"TYPE"`
Url string `yaml:"url,omitempty" env:"URL"`
}
type Keys struct {
ControlKey string `yaml:"control_key,omitempty"`
LegacyControlKey string `yaml:"legacy_control_key,omitempty"`
SystemAdminKey string `yaml:"system_admin_key,omitempty"`
ControlKey string `yaml:"control_key,omitempty" env:"CONTROL_KEY"`
LegacyControlKey string `yaml:"legacy_control_key,omitempty" env:"LEGACY_CONTROL_KEY"`
SystemAdminKey string `yaml:"system_admin_key,omitempty" env:"SYSTEM_ADMIN_KEY"`
}
type AuthProvider struct {
Issuer string `yaml:"issuer"`
ClientID string `yaml:"client_id"`
ClientSecret string `yaml:"client_secret"`
Scopes []string `yaml:"additional_scopes"`
type Auth struct {
Provider AuthProvider `yaml:"provider,omitempty" env:"PROVIDER"`
SystemAdminPolicy SystemAdminPolicy `yaml:"system_admins"`
}
type AuthProvider struct {
Issuer string `yaml:"issuer" env:"ISSUER"`
ClientID string `yaml:"client_id" env:"CLIENT_ID"`
ClientSecret string `yaml:"client_secret" env:"CLIENT_SECRET"`
Scopes []string `yaml:"additional_scopes" env:"SCOPES"`
}
type DNS struct {
MagicDNSSuffix string `yaml:"magic_dns_suffix"`
Provider DNSProvider `yaml:"provider,omitempty"`
}
type DNSProvider struct {
Name string `yaml:"name"`
Zone string `yaml:"zone"`
Subdomain string `yaml:"subdomain"`
Configuration map[string]string `yaml:"config"`
}
type SystemAdminPolicy struct {
Subs []string `json:"subs,omitempty"`
Emails []string `json:"emails,omitempty"`
Filters []string `json:"filters,omitempty"`
Subs []string `yaml:"subs,omitempty"`
Emails []string `yaml:"emails,omitempty"`
Filters []string `yaml:"filters,omitempty"`
}
func (c *Config) CreateUrl(format string, a ...interface{}) string {
@@ -195,8 +204,11 @@ func (c *Config) CreateUrl(format string, a ...interface{}) string {
return strings.TrimSuffix(c.ServerUrl, "/") + "/" + strings.TrimPrefix(path, "/")
}
func (c *Config) ReadServerKeys() (*ServerKeys, error) {
keys := &ServerKeys{}
func (c *Config) ReadServerKeys(defaultKeys *domain.ControlKeys) (*ServerKeys, error) {
keys := &ServerKeys{
ControlKey: defaultKeys.ControlKey,
LegacyControlKey: defaultKeys.LegacyControlKey,
}
if len(c.Keys.SystemAdminKey) != 0 {
systemAdminKey, err := key.ParsePrivateKey(c.Keys.SystemAdminKey)
@@ -207,17 +219,21 @@ func (c *Config) ReadServerKeys() (*ServerKeys, error) {
keys.SystemAdminKey = systemAdminKey
}
controlKey, err := util.ParseMachinePrivateKey(c.Keys.ControlKey)
if err != nil {
return nil, fmt.Errorf("error reading control key: %v", err)
if len(c.Keys.ControlKey) != 0 {
controlKey, err := util.ParseMachinePrivateKey(c.Keys.ControlKey)
if err != nil {
return nil, fmt.Errorf("error reading control key: %v", err)
}
keys.ControlKey = *controlKey
}
keys.ControlKey = *controlKey
legacyControlKey, err := util.ParseMachinePrivateKey(c.Keys.LegacyControlKey)
if err != nil {
return nil, fmt.Errorf("error reading legacy control key: %v", err)
if len(c.Keys.LegacyControlKey) != 0 {
legacyControlKey, err := util.ParseMachinePrivateKey(c.Keys.LegacyControlKey)
if err != nil {
return nil, fmt.Errorf("error reading legacy control key: %v", err)
}
keys.LegacyControlKey = *legacyControlKey
}
keys.LegacyControlKey = *legacyControlKey
return keys, nil
}
-21
View File
@@ -3,7 +3,6 @@ package config
import (
"os"
"strings"
"time"
)
func GetBool(key string, defaultValue bool) bool {
@@ -21,23 +20,3 @@ func GetString(key, defaultValue string) string {
}
return defaultValue
}
func GetStrings(key string, defaultValue []string) []string {
v := os.Getenv(key)
if v != "" {
return strings.Split(v, ",")
}
return defaultValue
}
func GetDuration(key string, defaultValue time.Duration) (time.Duration, error) {
v := os.Getenv(key)
if len(v) > 0 {
duration, err := time.ParseDuration(v)
if err != nil {
return defaultValue, err
}
return duration, nil
}
return defaultValue, nil
}
+56
View File
@@ -8,6 +8,8 @@ import (
"github.com/hashicorp/go-hclog"
"github.com/jsiebens/ionscale/internal/broker"
"github.com/jsiebens/ionscale/internal/database/migration"
"github.com/jsiebens/ionscale/internal/util"
"tailscale.com/types/key"
"time"
"github.com/jsiebens/ionscale/internal/config"
@@ -77,6 +79,60 @@ func migrate(db *gorm.DB) error {
return err
}
ctx := context.Background()
repository := domain.NewRepository(db)
if err := createServerKey(ctx, repository); err != nil {
return err
}
if err := createJSONWebKeySet(ctx, repository); err != nil {
return err
}
return nil
}
func createServerKey(ctx context.Context, repository domain.Repository) error {
serverKey, err := repository.GetControlKeys(ctx)
if err != nil {
return err
}
if serverKey != nil {
return nil
}
keys := domain.ControlKeys{
ControlKey: key.NewMachine(),
LegacyControlKey: key.NewMachine(),
}
if err := repository.SetControlKeys(ctx, &keys); err != nil {
return err
}
return nil
}
func createJSONWebKeySet(ctx context.Context, repository domain.Repository) error {
jwks, err := repository.GetJSONWebKeySet(ctx)
if err != nil {
return err
}
if jwks != nil {
return nil
}
privateKey, id, err := util.NewPrivateKey()
if err != nil {
return err
}
jsonWebKey := domain.JSONWebKey{Id: id, PrivateKey: *privateKey}
if err := repository.SetJSONWebKeySet(ctx, &domain.JSONWebKeys{Key: jsonWebKey}); err != nil {
return err
}
return nil
}
@@ -14,26 +14,26 @@ func m202209070900_initial_schema() *gormigrate.Migration {
// it's a good practice to copy the struct inside the function,
// so side effects are prevented if the original struct changes during the time
type ServerConfig struct {
Key string `gorm:"primary_key"`
Key string `gorm:"primaryKey"`
Value []byte
}
type Tailnet struct {
ID uint64 `gorm:"primary_key;autoIncrement:false"`
Name string `gorm:"type:varchar(64);unique_index"`
ID uint64 `gorm:"primaryKey;autoIncrement:false"`
Name string `gorm:"type:varchar(64);uniqueIndex"`
DNSConfig domain.DNSConfig
IAMPolicy domain.IAMPolicy
ACLPolicy domain.ACLPolicy
}
type Account struct {
ID uint64 `gorm:"primary_key;autoIncrement:false"`
ID uint64 `gorm:"primaryKey;autoIncrement:false"`
ExternalID string
LoginName string
}
type User struct {
ID uint64 `gorm:"primary_key;autoIncrement:false"`
ID uint64 `gorm:"primaryKey;autoIncrement:false"`
Name string
UserType domain.UserType
TailnetID uint64
@@ -43,8 +43,8 @@ func m202209070900_initial_schema() *gormigrate.Migration {
}
type SystemApiKey struct {
ID uint64 `gorm:"primary_key;autoIncrement:false"`
Key string `gorm:"type:varchar(64);unique_index"`
ID uint64 `gorm:"primaryKey;autoIncrement:false"`
Key string `gorm:"type:varchar(64);uniqueIndex"`
Hash string
CreatedAt time.Time
@@ -55,8 +55,8 @@ func m202209070900_initial_schema() *gormigrate.Migration {
}
type ApiKey struct {
ID uint64 `gorm:"primary_key;autoIncrement:false"`
Key string `gorm:"type:varchar(64);unique_index"`
ID uint64 `gorm:"primaryKey;autoIncrement:false"`
Key string `gorm:"type:varchar(64);uniqueIndex"`
Hash string
CreatedAt time.Time
@@ -70,8 +70,8 @@ func m202209070900_initial_schema() *gormigrate.Migration {
}
type AuthKey struct {
ID uint64 `gorm:"primary_key;autoIncrement:false"`
Key string `gorm:"type:varchar(64);unique_index"`
ID uint64 `gorm:"primaryKey;autoIncrement:false"`
Key string `gorm:"type:varchar(64);uniqueIndex"`
Hash string
Ephemeral bool
Tags domain.Tags
@@ -87,7 +87,7 @@ func m202209070900_initial_schema() *gormigrate.Migration {
}
type Machine struct {
ID uint64 `gorm:"primary_key;autoIncrement:false"`
ID uint64 `gorm:"primaryKey;autoIncrement:false"`
Name string
NameIdx uint64
MachineKey string
@@ -117,8 +117,8 @@ func m202209070900_initial_schema() *gormigrate.Migration {
}
type RegistrationRequest struct {
MachineKey string `gorm:"primary_key;autoIncrement:false"`
Key string `gorm:"type:varchar(64);unique_index"`
MachineKey string `gorm:"primaryKey;autoIncrement:false"`
Key string `gorm:"type:varchar(64);uniqueIndex"`
Data domain.RegistrationRequestData
CreatedAt time.Time
Authenticated bool
@@ -126,7 +126,7 @@ func m202209070900_initial_schema() *gormigrate.Migration {
}
type AuthenticationRequest struct {
Key string `gorm:"primary_key;autoIncrement:false"`
Key string `gorm:"primaryKey;autoIncrement:false"`
Token string
TailnetID *uint64
Error string
@@ -0,0 +1,23 @@
package migration
import (
"github.com/go-gormigrate/gormigrate/v2"
"github.com/jsiebens/ionscale/internal/domain"
"gorm.io/gorm"
)
func m202209251530_add_autoallowips_column() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202209251530",
Migrate: func(db *gorm.DB) error {
type Machine struct {
AutoAllowIPs domain.AllowIPs
}
return db.AutoMigrate(
&Machine{},
)
},
Rollback: nil,
}
}
@@ -0,0 +1,39 @@
package migration
import (
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
)
func m202209251532_add_alias_column() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202209251532a",
Migrate: func(db *gorm.DB) error {
type Tailnet struct {
Alias *string `gorm:"type:varchar(64)"`
}
return db.AutoMigrate(
&Tailnet{},
)
},
Rollback: nil,
}
}
func m202229251530_add_alias_column_constraint() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202209251532b",
Migrate: func(db *gorm.DB) error {
type Tailnet struct {
Name string `gorm:"uniqueIndex"`
Alias *string `gorm:"uniqueIndex"`
}
return db.AutoMigrate(
&Tailnet{},
)
},
Rollback: nil,
}
}
@@ -0,0 +1,25 @@
package migration
import (
"github.com/go-gormigrate/gormigrate/v2"
"github.com/jsiebens/ionscale/internal/domain"
"gorm.io/gorm"
)
func m202210040828_add_derpmap_colum() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202210040828",
Migrate: func(db *gorm.DB) error {
type Tailnet struct {
Name string `gorm:"uniqueIndex"`
Alias *string `gorm:"uniqueIndex"`
DERPMap domain.DERPMap
}
return db.AutoMigrate(
&Tailnet{},
)
},
Rollback: nil,
}
}
@@ -0,0 +1,25 @@
package migration
import (
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
)
func m202210070814_add_filesharing_and_servicecollection_columns() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202210070814",
Migrate: func(db *gorm.DB) error {
type Tailnet struct {
Name string `gorm:"uniqueIndex"`
Alias *string `gorm:"uniqueIndex"`
ServiceCollectionEnabled bool
FileSharingEnabled bool
}
return db.AutoMigrate(
&Tailnet{},
)
},
Rollback: nil,
}
}
@@ -0,0 +1,34 @@
package migration
import (
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
"time"
)
func m202210080700_ssh_action_request() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202210080700",
Migrate: func(db *gorm.DB) error {
type Tailnet struct {
Name string `gorm:"uniqueIndex"`
Alias *string `gorm:"uniqueIndex"`
SSHEnabled bool
}
type SSHActionRequest struct {
Key string `gorm:"primary_key"`
Action string
SrcMachineID uint64
DstMachineID uint64
CreatedAt time.Time
}
return db.AutoMigrate(
&Tailnet{},
&SSHActionRequest{},
)
},
Rollback: nil,
}
}
@@ -7,6 +7,12 @@ import (
func Migrations() []*gormigrate.Migration {
var migrations = []*gormigrate.Migration{
m202209070900_initial_schema(),
m202209251530_add_autoallowips_column(),
m202209251532_add_alias_column(),
m202229251530_add_alias_column_constraint(),
m202210040828_add_derpmap_colum(),
m202210070814_add_filesharing_and_servicecollection_columns(),
m202210080700_ssh_action_request(),
}
return migrations
}
+66
View File
@@ -0,0 +1,66 @@
package dns
import (
"context"
"fmt"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/mapping"
"github.com/libdns/azure"
"github.com/libdns/cloudflare"
"github.com/libdns/digitalocean"
"github.com/libdns/googleclouddns"
"github.com/libdns/libdns"
"github.com/libdns/route53"
"strings"
"time"
)
type Provider interface {
SetRecord(ctx context.Context, recordType, recordName, value string) error
}
func NewProvider(config config.DNSProvider) (Provider, error) {
if len(config.Zone) == 0 {
return nil, nil
}
switch config.Name {
case "azure":
return configureProvider(config.Zone, config.Configuration, &azure.Provider{})
case "cloudflare":
return configureProvider(config.Zone, config.Configuration, &cloudflare.Provider{})
case "digitalocean":
return configureProvider(config.Zone, config.Configuration, &digitalocean.Provider{})
case "googleclouddns":
return configureProvider(config.Zone, config.Configuration, &googleclouddns.Provider{})
case "route53":
return configureProvider(config.Zone, config.Configuration, &route53.Provider{})
default:
return nil, fmt.Errorf("unknown dns provider: %s", config.Name)
}
}
func configureProvider(zone string, v map[string]string, setter libdns.RecordSetter) (Provider, error) {
if err := mapping.CopyViaJson(v, setter); err != nil {
return nil, err
}
return &externalProvider{
zone: zone,
setter: setter,
}, nil
}
type externalProvider struct {
zone string
setter libdns.RecordSetter
}
func (p *externalProvider) SetRecord(ctx context.Context, recordType, recordName, value string) error {
_, err := p.setter.SetRecords(ctx, fmt.Sprintf("%s.", p.zone), []libdns.Record{{
Type: recordType,
Name: strings.TrimSuffix(recordName, p.zone),
Value: value,
TTL: 1 * time.Minute,
}})
return err
}
+244 -50
View File
@@ -8,16 +8,30 @@ import (
"gorm.io/gorm"
"gorm.io/gorm/schema"
"net/netip"
"sort"
"strconv"
"strings"
"tailscale.com/tailcfg"
)
const (
AutoGroupSelf = "autogroup:self"
AutoGroupMembers = "autogroup:members"
AutoGroupInternet = "autogroup:internet"
)
type AutoApprovers struct {
Routes map[string][]string `json:"routes"`
ExitNode []string `json:"exitNode"`
}
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:"tag_owners"`
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"`
}
type ACL struct {
@@ -26,6 +40,13 @@ type ACL struct {
Dst []string `json:"dst"`
}
type SSHRule struct {
Action string `json:"action"`
Src []string `json:"src"`
Dst []string `json:"dst"`
Users []string `json:"users"`
}
func DefaultPolicy() ACLPolicy {
return ACLPolicy{
ACLs: []ACL{
@@ -38,31 +59,95 @@ func DefaultPolicy() ACLPolicy {
}
}
func (a ACLPolicy) CheckTags(tags []string) error {
var result *multierror.Error
for _, t := range tags {
if _, ok := a.TagOwners[t]; !ok {
result = multierror.Append(result, fmt.Errorf("tag [%s] is invalid or not permitted", t))
func (a ACLPolicy) FindAutoApprovedIPs(routableIPs []netip.Prefix, tags []string, u *User) []netip.Prefix {
if len(routableIPs) == 0 {
return nil
}
matches := func(values []string) bool {
for _, alias := range values {
if alias == u.Name {
return true
}
group, ok := a.Groups[alias]
if ok {
for _, g := range group {
if g == u.Name {
return true
}
}
}
if strings.HasPrefix(alias, "tag:") {
for _, tag := range tags {
if alias == tag {
return true
}
}
}
}
return false
}
isAutoApproved := func(candidate netip.Prefix, approvedIPs []netip.Prefix) bool {
for _, approvedIP := range approvedIPs {
if candidate.Bits() >= approvedIP.Bits() && approvedIP.Contains(candidate.Masked().Addr()) {
return true
}
}
return false
}
autoApprovedIPs := []netip.Prefix{}
for route, autoApprovers := range a.AutoApprovers.Routes {
candidate, err := netip.ParsePrefix(route)
if err != nil {
return nil
}
if matches(autoApprovers) {
autoApprovedIPs = append(autoApprovedIPs, candidate)
}
}
return result.ErrorOrNil()
result := []netip.Prefix{}
for _, c := range routableIPs {
if c.Bits() == 0 && matches(a.AutoApprovers.ExitNode) {
result = append(result, c)
}
if isAutoApproved(c, autoApprovedIPs) {
result = append(result, c)
}
}
return result
}
func (a ACLPolicy) IsTagOwner(tags []string, p *User) bool {
for _, t := range tags {
if a.isTagOwner(t, p) {
return true
}
}
return false
}
func (a ACLPolicy) CheckTagOwners(tags []string, p *User) error {
var result *multierror.Error
for _, t := range tags {
if ok := a.IsTagOwner(t, p); !ok {
if ok := a.isTagOwner(t, p); !ok {
result = multierror.Append(result, fmt.Errorf("tag [%s] is invalid or not permitted", t))
}
}
return result.ErrorOrNil()
}
func (a ACLPolicy) IsTagOwner(tag string, p *User) bool {
func (a ACLPolicy) isTagOwner(tag string, p *User) bool {
if p.UserType == UserTypeService {
return true
}
if tagOwners, ok := a.TagOwners[tag]; ok {
if p.UserType == UserTypeService {
return true
}
return a.validateTagOwners(tagOwners, p)
}
return false
@@ -93,33 +178,34 @@ func (a ACLPolicy) IsValidPeer(src *Machine, dest *Machine) bool {
}
for _, acl := range a.ACLs {
allDestPorts := a.expandMachineToDstPorts(dest, acl.Dst)
if len(allDestPorts) == 0 {
continue
selfDestPorts, allDestPorts := a.expandMachineToDstPorts(dest, acl.Dst)
if len(selfDestPorts) != 0 {
for _, alias := range acl.Src {
if len(a.expandMachineAlias(src, alias, true, &dest.User)) != 0 {
return true
}
}
}
for _, alias := range acl.Src {
if len(a.expandMachineAlias(src, alias, true)) != 0 {
return true
if len(allDestPorts) != 0 {
for _, alias := range acl.Src {
if len(a.expandMachineAlias(src, alias, true, nil)) != 0 {
return true
}
}
}
}
return false
}
func (a ACLPolicy) BuildFilterRules(srcs []Machine, dst *Machine) []tailcfg.FilterRule {
var rules []tailcfg.FilterRule
for _, acl := range a.ACLs {
allDestPorts := a.expandMachineToDstPorts(dst, acl.Dst)
if len(allDestPorts) == 0 {
continue
}
transform := func(src []string, destPorts []tailcfg.NetPortRange, u *User) tailcfg.FilterRule {
var allSrcIPsSet = &StringSet{}
for _, alias := range acl.Src {
for _, alias := range src {
for _, src := range srcs {
srcIPs := a.expandMachineAlias(&src, alias, true)
srcIPs := a.expandMachineAlias(&src, alias, true, u)
allSrcIPsSet.Add(srcIPs...)
}
}
@@ -130,12 +216,20 @@ func (a ACLPolicy) BuildFilterRules(srcs []Machine, dst *Machine) []tailcfg.Filt
allSrcIPs = nil
}
rule := tailcfg.FilterRule{
return tailcfg.FilterRule{
SrcIPs: allSrcIPs,
DstPorts: allDestPorts,
DstPorts: destPorts,
}
}
rules = append(rules, rule)
for _, acl := range a.ACLs {
selfDestPorts, allDestPorts := a.expandMachineToDstPorts(dst, acl.Dst)
if len(selfDestPorts) != 0 {
rules = append(rules, transform(acl.Src, selfDestPorts, &dst.User))
}
if len(allDestPorts) != 0 {
rules = append(rules, transform(acl.Src, allDestPorts, nil))
}
}
if len(rules) == 0 {
@@ -145,19 +239,24 @@ func (a ACLPolicy) BuildFilterRules(srcs []Machine, dst *Machine) []tailcfg.Filt
return rules
}
func (a ACLPolicy) expandMachineToDstPorts(m *Machine, ports []string) []tailcfg.NetPortRange {
allDestRanges := []tailcfg.NetPortRange{}
func (a ACLPolicy) expandMachineToDstPorts(m *Machine, ports []string) ([]tailcfg.NetPortRange, []tailcfg.NetPortRange) {
selfDestRanges := []tailcfg.NetPortRange{}
otherDestRanges := []tailcfg.NetPortRange{}
for _, d := range ports {
ranges := a.expandMachineDestToNetPortRanges(m, d)
allDestRanges = append(allDestRanges, ranges...)
self, ranges := a.expandMachineDestToNetPortRanges(m, d)
if self {
selfDestRanges = append(selfDestRanges, ranges...)
} else {
otherDestRanges = append(otherDestRanges, ranges...)
}
}
return allDestRanges
return selfDestRanges, otherDestRanges
}
func (a ACLPolicy) expandMachineDestToNetPortRanges(m *Machine, dest string) []tailcfg.NetPortRange {
func (a ACLPolicy) expandMachineDestToNetPortRanges(m *Machine, dest string) (bool, []tailcfg.NetPortRange) {
tokens := strings.Split(dest, ":")
if len(tokens) < 2 || len(tokens) > 3 {
return nil
return false, nil
}
var alias string
@@ -169,12 +268,12 @@ func (a ACLPolicy) expandMachineDestToNetPortRanges(m *Machine, dest string) []t
ports, err := a.expandValuePortToPortRange(tokens[len(tokens)-1])
if err != nil {
return nil
return false, nil
}
ips := a.expandMachineAlias(m, alias, false)
ips := a.expandMachineAlias(m, alias, false, nil)
if len(ips) == 0 {
return nil
return false, nil
}
dests := []tailcfg.NetPortRange{}
@@ -188,18 +287,40 @@ func (a ACLPolicy) expandMachineDestToNetPortRanges(m *Machine, dest string) []t
}
}
return dests
return alias == AutoGroupSelf, dests
}
func (a ACLPolicy) expandMachineAlias(m *Machine, alias string, src bool) []string {
func (a ACLPolicy) expandMachineAlias(m *Machine, alias string, src bool, u *User) []string {
if u != nil && m.HasTags() {
return []string{}
}
if u != nil && !m.HasUser(u.Name) {
return []string{}
}
if alias == "*" && u != nil {
return m.IPs()
}
if alias == "*" {
if alias == "*" {
return []string{"*"}
return []string{"*"}
}
if alias == AutoGroupMembers || alias == AutoGroupSelf {
if !m.HasTags() {
return m.IPs()
} else {
return []string{}
}
}
if alias == AutoGroupInternet && m.IsExitNode() {
return autogroupInternetRanges()
}
if strings.Contains(alias, "@") && !m.HasTags() && m.HasUser(alias) {
return []string{m.IPv4.String(), m.IPv6.String()}
return m.IPs()
}
if strings.HasPrefix(alias, "group:") && !m.HasTags() {
@@ -211,7 +332,7 @@ func (a ACLPolicy) expandMachineAlias(m *Machine, alias string, src bool) []stri
for _, u := range users {
if m.HasUser(u) {
return []string{m.IPv4.String(), m.IPv6.String()}
return m.IPs()
}
}
@@ -219,7 +340,7 @@ func (a ACLPolicy) expandMachineAlias(m *Machine, alias string, src bool) []stri
}
if strings.HasPrefix(alias, "tag:") && m.HasTag(alias) {
return []string{m.IPv4.String(), m.IPv6.String()}
return m.IPs()
}
if h, ok := a.Hosts[alias]; ok {
@@ -283,6 +404,25 @@ func (a ACLPolicy) expandValuePortToPortRange(s string) ([]tailcfg.PortRange, er
return ports, nil
}
func (a ACLPolicy) isGroupMember(group string, m *Machine) bool {
if m.HasTags() {
return false
}
users, ok := a.Groups[group]
if !ok {
return false
}
for _, u := range users {
if m.HasUser(u) {
return true
}
}
return false
}
func (i *ACLPolicy) Scan(destination interface{}) error {
switch value := destination.(type) {
case []byte:
@@ -332,5 +472,59 @@ func (s *StringSet) Items() []string {
for i := range s.items {
items = append(items, i)
}
sort.Strings(items)
return items
}
func autogroupInternetRanges() []string {
return []string{
"0.0.0.0/5",
"8.0.0.0/7",
"11.0.0.0/8",
"12.0.0.0/6",
"16.0.0.0/4",
"32.0.0.0/3",
"64.0.0.0/3",
"96.0.0.0/6",
"100.0.0.0/10",
"100.128.0.0/9",
"101.0.0.0/8",
"102.0.0.0/7",
"104.0.0.0/5",
"112.0.0.0/4",
"128.0.0.0/3",
"160.0.0.0/5",
"168.0.0.0/8",
"169.0.0.0/9",
"169.128.0.0/10",
"169.192.0.0/11",
"169.224.0.0/12",
"169.240.0.0/13",
"169.248.0.0/14",
"169.252.0.0/15",
"169.255.0.0/16",
"170.0.0.0/7",
"172.0.0.0/12",
"172.32.0.0/11",
"172.64.0.0/10",
"172.128.0.0/9",
"173.0.0.0/8",
"174.0.0.0/7",
"176.0.0.0/4",
"192.0.0.0/9",
"192.128.0.0/11",
"192.160.0.0/13",
"192.169.0.0/16",
"192.170.0.0/15",
"192.172.0.0/14",
"192.176.0.0/12",
"192.192.0.0/10",
"193.0.0.0/8",
"194.0.0.0/7",
"196.0.0.0/6",
"200.0.0.0/5",
"208.0.0.0/4",
"224.0.0.0/3",
"2000::/3",
}
}
+150
View File
@@ -0,0 +1,150 @@
package domain
import (
"strings"
"tailscale.com/tailcfg"
)
func (a ACLPolicy) BuildSSHPolicy(srcs []Machine, dst *Machine) *tailcfg.SSHPolicy {
var rules []*tailcfg.SSHRule
expandSrcAliases := func(aliases []string, u *User) []*tailcfg.SSHPrincipal {
var allSrcIPsSet = &StringSet{}
for _, alias := range aliases {
for _, src := range srcs {
srcIPs := a.expandSSHSrcAlias(&src, alias, u)
allSrcIPsSet.Add(srcIPs...)
}
}
var result = []*tailcfg.SSHPrincipal{}
for _, i := range allSrcIPsSet.Items() {
result = append(result, &tailcfg.SSHPrincipal{NodeIP: i})
}
return result
}
for _, rule := range a.SSHRules {
if rule.Action != "accept" && rule.Action != "check" {
continue
}
var action = &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
}
if rule.Action == "check" {
action = &tailcfg.SSHAction{
HoldAndDelegate: "https://unused/machine/ssh/action/$SRC_NODE_ID/to/$DST_NODE_ID",
}
}
selfUsers, otherUsers := a.expandSSHDstToSSHUsers(dst, rule)
if len(selfUsers) != 0 {
principals := expandSrcAliases(rule.Src, &dst.User)
if len(principals) != 0 {
rules = append(rules, &tailcfg.SSHRule{
Principals: principals,
SSHUsers: selfUsers,
Action: action,
})
}
}
if len(otherUsers) != 0 {
principals := expandSrcAliases(rule.Src, nil)
if len(principals) != 0 {
rules = append(rules, &tailcfg.SSHRule{
Principals: principals,
SSHUsers: otherUsers,
Action: action,
})
}
}
}
return &tailcfg.SSHPolicy{Rules: rules}
}
func (a ACLPolicy) expandSSHSrcAlias(m *Machine, alias string, dstUser *User) []string {
if dstUser != nil {
if !m.HasUser(dstUser.Name) || m.HasTags() {
return []string{}
}
if alias == AutoGroupMembers {
return m.IPs()
}
if strings.Contains(alias, "@") && m.HasUser(alias) {
return m.IPs()
}
if strings.HasPrefix(alias, "group:") && a.isGroupMember(alias, m) {
return m.IPs()
}
return []string{}
}
if alias == AutoGroupMembers && !m.HasTags() {
return m.IPs()
}
if strings.Contains(alias, "@") && !m.HasTags() && m.HasUser(alias) {
return m.IPs()
}
if strings.HasPrefix(alias, "group:") && !m.HasTags() && a.isGroupMember(alias, m) {
return m.IPs()
}
if strings.HasPrefix(alias, "tag:") && m.HasTag(alias) {
return m.IPs()
}
return []string{}
}
func (a ACLPolicy) expandSSHDstToSSHUsers(m *Machine, rule SSHRule) (map[string]string, map[string]string) {
users := buildSSHUsers(rule.Users)
var selfUsers map[string]string
var otherUsers map[string]string
for _, d := range rule.Dst {
if strings.HasPrefix(d, "tag:") && m.HasTag(d) {
otherUsers = users
}
if m.HasUser(d) || d == AutoGroupSelf {
selfUsers = users
}
}
return selfUsers, otherUsers
}
func buildSSHUsers(users []string) map[string]string {
var autogroupNonRoot = false
m := make(map[string]string)
for _, u := range users {
if u == "autogroup:nonroot" {
m["*"] = "="
autogroupNonRoot = true
} else {
m[u] = u
}
}
// disable root when autogroup:nonroot is used and root is not explicitly enabled
if _, exists := m["root"]; !exists && autogroupNonRoot {
m["root"] = ""
}
return m
}
+364
View File
@@ -0,0 +1,364 @@
package domain
import (
"encoding/json"
"fmt"
"github.com/stretchr/testify/assert"
"tailscale.com/tailcfg"
"testing"
)
func TestACLPolicy_BuildSSHPolicy_(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"autogroup:members"},
Dst: []string{"autogroup:self"},
Users: []string{"autogroup:nonroot"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst)
expectedRules := []*tailcfg.SSHRule{
{
Principals: []*tailcfg.SSHPrincipal{
{NodeIP: p1.IPv4.String()},
{NodeIP: p1.IPv6.String()},
},
SSHUsers: map[string]string{
"*": "=",
"root": "",
},
Action: &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
},
},
}
assert.Equal(t, expectedRules, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithGroup(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
Groups: map[string][]string{
"group:sre": {
"john@example.com",
},
},
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"group:sre"},
Dst: []string{"tag:web"},
Users: []string{"autogroup:nonroot", "root"},
},
},
}
dst := createMachine("john@example.com", "tag:web")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst)
expectedRules := []*tailcfg.SSHRule{
{
Principals: []*tailcfg.SSHPrincipal{
{NodeIP: p1.IPv4.String()},
{NodeIP: p1.IPv6.String()},
},
SSHUsers: map[string]string{
"*": "=",
"root": "root",
},
Action: &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
},
},
}
assert.Equal(t, expectedRules, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithMatchingUsers(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"john@example.com"},
Dst: []string{"john@example.com"},
Users: []string{"autogroup:nonroot", "root"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst)
expectedRules := []*tailcfg.SSHRule{
{
Principals: sshPrincipalsFromMachines(*p1),
SSHUsers: map[string]string{
"*": "=",
"root": "root",
},
Action: &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
},
},
}
assert.Equal(t, expectedRules, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithMatchingUsersInGroup(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
Groups: map[string][]string{
"group:sre": {"jane@example.com", "john@example.com"},
},
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"group:sre"},
Dst: []string{"john@example.com"},
Users: []string{"autogroup:nonroot", "root"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst)
expectedRules := []*tailcfg.SSHRule{
{
Principals: sshPrincipalsFromMachines(*p1),
SSHUsers: map[string]string{
"*": "=",
"root": "root",
},
Action: &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
},
},
}
assert.Equal(t, expectedRules, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithNoMatchingUsers(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"jane@example.com"},
Dst: []string{"john@example.com"},
Users: []string{"autogroup:nonroot", "root"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst)
assert.Nil(t, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithTags(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("nick@example.com")
p3 := createMachine("nick@example.com", "tag:web")
policy := ACLPolicy{
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"john@example.com", "tag:web"},
Dst: []string{"tag:web"},
Users: []string{"ubuntu"},
},
},
}
dst := createMachine("john@example.com", "tag:web")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2, *p3}, dst)
expectedRules := []*tailcfg.SSHRule{
{
Principals: sshPrincipalsFromMachines(*p1, *p3),
SSHUsers: map[string]string{
"ubuntu": "ubuntu",
},
Action: &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
},
},
}
assert.Equal(t, expectedRules, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithTagsInDstAndAutogroupMemberInSrc(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("nick@example.com")
p3 := createMachine("nick@example.com", "tag:web")
policy := ACLPolicy{
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"autogroup:members"},
Dst: []string{"tag:web"},
Users: []string{"ubuntu"},
},
},
}
dst := createMachine("john@example.com", "tag:web")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2, *p3}, dst)
expectedRules := []*tailcfg.SSHRule{
{
Principals: sshPrincipalsFromMachines(*p1, *p2),
SSHUsers: map[string]string{
"ubuntu": "ubuntu",
},
Action: &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
},
},
}
assert.Equal(t, expectedRules, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithUserInDstAndNonMatchingSrc(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"jane@example.com"},
Dst: []string{"john@example.com"},
Users: []string{"autogroup:nonroot"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst)
assert.Nil(t, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithUserInDstAndAutogroupMembersSrc(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"autogroup:members"},
Dst: []string{"john@example.com"},
Users: []string{"autogroup:nonroot"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst)
expectedRules := []*tailcfg.SSHRule{
{
Principals: sshPrincipalsFromMachines(*p1),
SSHUsers: map[string]string{
"*": "=",
"root": "",
},
Action: &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
},
},
}
assert.Equal(t, expectedRules, actualRules.Rules)
}
func TestACLPolicy_BuildSSHPolicy_WithAutogroupSelfAndTagSrc(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com", "tag:web")
policy := ACLPolicy{
SSHRules: []SSHRule{
{
Action: "accept",
Src: []string{"tag:web"},
Dst: []string{"autogroup:self"},
Users: []string{"autogroup:nonroot"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst)
assert.Nil(t, actualRules.Rules)
}
func printRules(rules []*tailcfg.SSHRule) {
indent, err := json.MarshalIndent(rules, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(indent))
}
func sshPrincipalsFromMachines(machines ...Machine) []*tailcfg.SSHPrincipal {
x := StringSet{}
for _, m := range machines {
x.Add(m.IPv4.String(), m.IPv6.String())
}
var result = []*tailcfg.SSHPrincipal{}
for _, i := range x.Items() {
result = append(result, &tailcfg.SSHPrincipal{NodeIP: i})
}
return result
}
+573
View File
@@ -1,10 +1,483 @@
package domain
import (
"github.com/jsiebens/ionscale/internal/addr"
"github.com/stretchr/testify/assert"
"net/netip"
"sort"
"tailscale.com/tailcfg"
"testing"
)
func TestACLPolicy_BuildFilterRulesWildcards(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"*:*"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{"*"},
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesWithGroups(t *testing.T) {
p1 := createMachine("jane@example.com")
p2 := createMachine("nick@example.com")
p3 := createMachine("joe@example.com")
policy := ACLPolicy{
Groups: map[string][]string{
"group:admin": []string{"jane@example.com"},
"group:audit": []string{"nick@example.com"},
},
ACLs: []ACL{
{
Action: "accept",
Src: []string{"group:admin"},
Dst: []string{"*:22"},
},
{
Action: "accept",
Src: []string{"group:audit"},
Dst: []string{"*:8000-8080"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2, *p3}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 22,
Last: 22,
},
},
},
},
{
SrcIPs: []string{
p2.IPv4.String(),
p2.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 8000,
Last: 8080,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesWithAutoGroupMembers(t *testing.T) {
p1 := createMachine("jane@example.com")
p2 := createMachine("nick@example.com")
p3 := createMachine("joe@example.com", "tag:web")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"autogroup:members"},
Dst: []string{"*:22"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2, *p3}, dst)
expectedSrcIPs := []string{
p1.IPv4.String(), p1.IPv6.String(),
p2.IPv4.String(), p2.IPv6.String(),
}
sort.Strings(expectedSrcIPs)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: expectedSrcIPs,
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 22,
Last: 22,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupSelf(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"autogroup:self:*"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: dst.IPv4.String(),
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
{
IP: dst.IPv6.String(),
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupSelfAndTags(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("john@example.com", "tag:web")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"autogroup:self:*"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: dst.IPv4.String(),
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
{
IP: dst.IPv6.String(),
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupSelfAndOtherDestinations(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("john@example.com", "tag:web")
p3 := createMachine("jane@example.com")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"autogroup:self:22", "john@example.com:80"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2, *p3}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: p1.IPs(),
DstPorts: []tailcfg.NetPortRange{
{
IP: dst.IPv4.String(),
Ports: tailcfg.PortRange{
First: 22,
Last: 22,
},
},
{
IP: dst.IPv6.String(),
Ports: tailcfg.PortRange{
First: 22,
Last: 22,
},
},
},
},
{
SrcIPs: []string{"*"},
DstPorts: []tailcfg.NetPortRange{
{
IP: dst.IPv4.String(),
Ports: tailcfg.PortRange{
First: 80,
Last: 80,
},
},
{
IP: dst.IPv6.String(),
Ports: tailcfg.PortRange{
First: 80,
Last: 80,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupMember(t *testing.T) {
p1 := createMachine("jane@example.com")
p2 := createMachine("jane@example.com", "tag:web")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"autogroup:members"},
Dst: []string{"*:*"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupInternet(t *testing.T) {
p1 := createMachine("nick@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"nick@example.com"},
Dst: []string{"autogroup:internet:*"},
},
},
}
dst := createMachine("john@example.com")
dst.AllowIPs = []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
}
expectedDstPorts := []tailcfg.NetPortRange{}
for _, r := range autogroupInternetRanges() {
expectedDstPorts = append(expectedDstPorts, tailcfg.NetPortRange{
IP: r,
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
})
}
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: expectedDstPorts,
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestWithUser(t *testing.T) {
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"john@example.com:*"},
},
},
}
src := createMachine("john@example.com")
assert.True(t, policy.IsValidPeer(src, createMachine("john@example.com")))
assert.False(t, policy.IsValidPeer(src, createMachine("john@example.com", "tag:web")))
assert.False(t, policy.IsValidPeer(src, createMachine("jane@example.com")))
}
func TestWithGroup(t *testing.T) {
policy := ACLPolicy{
Groups: map[string][]string{
"group:admin": {"john@example.com"},
},
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"group:admin:*"},
},
},
}
src := createMachine("john@example.com")
assert.True(t, policy.IsValidPeer(src, createMachine("john@example.com")))
assert.False(t, policy.IsValidPeer(src, createMachine("jane@example.com")))
}
func TestWithTags(t *testing.T) {
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"tag:web:*"},
},
},
}
src := createMachine("john@example.com")
assert.True(t, policy.IsValidPeer(src, createMachine("john@example.com", "tag:web")))
assert.False(t, policy.IsValidPeer(src, createMachine("john@example.com", "tag:ci")))
}
func TestWithHosts(t *testing.T) {
dst1 := createMachine("john@example.com")
dst2 := createMachine("john@example.com")
policy := ACLPolicy{
Hosts: map[string]string{
"dst1": dst1.IPv4.String(),
},
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"dst1:*"},
},
},
}
src := createMachine("jane@example.com")
assert.True(t, policy.IsValidPeer(src, dst1))
assert.False(t, policy.IsValidPeer(src, dst2))
}
func createMachine(user string, tags ...string) *Machine {
ipv4, ipv6, err := addr.SelectIP(func(addr netip.Addr) (bool, error) {
return true, nil
})
if err != nil {
return nil
}
return &Machine{
IPv4: IP{ipv4},
IPv6: IP{ipv6},
User: User{
Name: user,
},
Tags: tags,
}
}
func TestACLPolicy_IsTagOwner(t *testing.T) {
policy := ACLPolicy{
Groups: map[string][]string{
@@ -28,6 +501,13 @@ func TestACLPolicy_IsTagOwner(t *testing.T) {
userType: UserTypeService,
expectErr: false,
},
{
name: "system admin is always a valid owner",
tag: "tag:unknown",
userName: "system admin",
userType: UserTypeService,
expectErr: false,
},
{
name: "direct tag owner",
tag: "tag:web",
@@ -69,3 +549,96 @@ func TestACLPolicy_IsTagOwner(t *testing.T) {
})
}
}
func TestACLPolicy_FindAutoApprovedIPs(t *testing.T) {
route1 := netip.MustParsePrefix("10.160.0.0/20")
route2 := netip.MustParsePrefix("10.161.0.0/20")
route3 := netip.MustParsePrefix("10.162.0.0/20")
policy := ACLPolicy{
Groups: map[string][]string{
"group:admins": {"jane@example.com"},
},
AutoApprovers: AutoApprovers{
Routes: map[string][]string{
route1.String(): {"group:admins"},
route2.String(): {"john@example.com", "tag:router"},
},
ExitNode: []string{"nick@example.com"},
},
}
testCases := []struct {
name string
tag []string
userName string
routableIPs []netip.Prefix
expected []netip.Prefix
}{
{
name: "nil",
tag: []string{},
userName: "john@example.com",
routableIPs: nil,
expected: nil,
},
{
name: "empty",
tag: []string{},
userName: "john@example.com",
routableIPs: []netip.Prefix{},
expected: nil,
},
{
name: "by user",
tag: []string{},
userName: "john@example.com",
routableIPs: []netip.Prefix{route1, route2, route3},
expected: []netip.Prefix{route2},
},
{
name: "partial by user",
tag: []string{},
userName: "john@example.com",
routableIPs: []netip.Prefix{netip.MustParsePrefix("10.161.4.0/22")},
expected: []netip.Prefix{netip.MustParsePrefix("10.161.4.0/22")},
},
{
name: "by tag",
tag: []string{"tag:router"},
routableIPs: []netip.Prefix{route1, route2, route3},
expected: []netip.Prefix{route2},
},
{
name: "by group",
userName: "jane@example.com",
routableIPs: []netip.Prefix{route1, route2, route3},
expected: []netip.Prefix{route1},
},
{
name: "no match",
userName: "nick@example.com",
routableIPs: []netip.Prefix{route1, route2, route3},
expected: []netip.Prefix{},
},
{
name: "exit",
userName: "nick@example.com",
routableIPs: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")},
expected: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")},
},
{
name: "exit no match",
userName: "john@example.com",
routableIPs: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")},
expected: []netip.Prefix{},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actualAllowedIPs := policy.FindAutoApprovedIPs(tc.routableIPs, tc.tag, &User{Name: tc.userName})
assert.Equal(t, tc.expected, actualAllowedIPs)
})
}
}
+48
View File
@@ -0,0 +1,48 @@
package domain
import (
"context"
"database/sql/driver"
"encoding/json"
"fmt"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"tailscale.com/tailcfg"
)
type DERPMap struct {
Checksum string
DERPMap tailcfg.DERPMap
}
func (hi *DERPMap) Scan(destination interface{}) error {
switch value := destination.(type) {
case []byte:
return json.Unmarshal(value, hi)
default:
return fmt.Errorf("unexpected data type %T", destination)
}
}
func (hi DERPMap) Value() (driver.Value, error) {
bytes, err := json.Marshal(hi)
return bytes, err
}
// GormDataType gorm common data type
func (DERPMap) GormDataType() string {
return "json"
}
// GormDBDataType gorm db data type
func (DERPMap) GormDBDataType(db *gorm.DB, field *schema.Field) string {
switch db.Dialector.Name() {
case "sqlite":
return "JSON"
}
return ""
}
type DefaultDERPMap interface {
GetDERPMap(ctx context.Context) (*DERPMap, error)
}
+5 -4
View File
@@ -9,10 +9,11 @@ import (
)
type DNSConfig struct {
MagicDNS bool `json:"magic_dns"`
OverrideLocalDNS bool `json:"override_local_dns"`
Nameservers []string `json:"nameservers"`
Routes map[string][]string `json:"routes"`
HttpsCertsEnabled bool `json:"http_certs"`
MagicDNS bool `json:"magic_dns"`
OverrideLocalDNS bool `json:"override_local_dns"`
Nameservers []string `json:"nameservers"`
Routes map[string][]string `json:"routes"`
}
func (i *DNSConfig) Scan(destination interface{}) error {
+87 -3
View File
@@ -25,9 +25,10 @@ type Machine struct {
Tags Tags
KeyExpiryDisabled bool
HostInfo HostInfo
Endpoints Endpoints
AllowIPs AllowIPs
HostInfo HostInfo
Endpoints Endpoints
AllowIPs AllowIPs
AutoAllowIPs AllowIPs
IPv4 IP
IPv6 IP
@@ -45,6 +46,17 @@ type Machine struct {
type Machines []Machine
func (m *Machine) CompleteName() string {
if m.NameIdx != 0 {
return fmt.Sprintf("%s-%d", m.Name, m.NameIdx)
}
return m.Name
}
func (m *Machine) IPs() []string {
return []string{m.IPv4.String(), m.IPv6.String()}
}
func (m *Machine) IsExpired() bool {
return !m.KeyExpiryDisabled && !m.ExpiresAt.IsZero() && m.ExpiresAt.Before(time.Now())
}
@@ -70,6 +82,54 @@ func (m *Machine) HasTags() bool {
return len(m.Tags) != 0
}
func (m *Machine) IsAdvertisedExitNode() bool {
for _, r := range m.HostInfo.RoutableIPs {
if r.Bits() == 0 {
return true
}
}
return false
}
func (m *Machine) IsAllowedExitNode() bool {
for _, r := range m.AllowIPs {
if r.Bits() == 0 {
return true
}
}
for _, r := range m.AutoAllowIPs {
if r.Bits() == 0 {
return true
}
}
return false
}
func (m *Machine) AdvertisedPrefixes() []string {
result := []string{}
for _, r := range m.HostInfo.RoutableIPs {
if r.Bits() != 0 {
result = append(result, r.String())
}
}
return result
}
func (m *Machine) AllowedPrefixes() []string {
result := StringSet{}
for _, r := range m.AllowIPs {
if r.Bits() != 0 {
result.Add(r.String())
}
}
for _, r := range m.AutoAllowIPs {
if r.Bits() != 0 {
result.Add(r.String())
}
}
return result.Items()
}
func (m *Machine) IsAllowedIP(i netip.Addr) bool {
if m.HasIP(i) {
return true
@@ -79,6 +139,11 @@ func (m *Machine) IsAllowedIP(i netip.Addr) bool {
return true
}
}
for _, t := range m.AutoAllowIPs {
if t.Contains(i) {
return true
}
}
return false
}
@@ -88,6 +153,25 @@ func (m *Machine) IsAllowedIPPrefix(i netip.Prefix) bool {
return true
}
}
for _, t := range m.AutoAllowIPs {
if t.Overlaps(i) {
return true
}
}
return false
}
func (m *Machine) IsExitNode() bool {
for _, t := range m.AllowIPs {
if t.Bits() == 0 {
return true
}
}
for _, t := range m.AutoAllowIPs {
if t.Bits() == 0 {
return true
}
}
return false
}
+21 -6
View File
@@ -3,6 +3,7 @@ package domain
import (
"context"
"encoding/json"
"github.com/jsiebens/ionscale/internal/util"
"gorm.io/gorm"
"net/http"
"sync"
@@ -11,15 +12,22 @@ import (
)
type Repository interface {
GetDERPMap(ctx context.Context) (*tailcfg.DERPMap, error)
SetDERPMap(ctx context.Context, v *tailcfg.DERPMap) error
GetControlKeys(ctx context.Context) (*ControlKeys, error)
SetControlKeys(ctx context.Context, keys *ControlKeys) error
GetJSONWebKeySet(ctx context.Context) (*JSONWebKeys, error)
SetJSONWebKeySet(ctx context.Context, keys *JSONWebKeys) error
GetDERPMap(ctx context.Context) (*DERPMap, error)
SetDERPMap(ctx context.Context, v *DERPMap) error
GetAccount(ctx context.Context, accountID uint64) (*Account, error)
GetOrCreateAccount(ctx context.Context, externalID, loginName string) (*Account, bool, error)
SaveTailnet(ctx context.Context, tailnet *Tailnet) error
GetOrCreateTailnet(ctx context.Context, name string) (*Tailnet, bool, 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)
DeleteTailnet(ctx context.Context, id uint64) error
@@ -70,6 +78,10 @@ type Repository interface {
GetAuthenticationRequest(ctx context.Context, key string) (*AuthenticationRequest, error)
DeleteAuthenticationRequest(ctx context.Context, key string) error
SaveSSHActionRequest(ctx context.Context, session *SSHActionRequest) error
GetSSHActionRequest(ctx context.Context, key string) (*SSHActionRequest, error)
DeleteSSHActionRequest(ctx context.Context, key string) error
Transaction(func(rp Repository) error) error
}
@@ -97,10 +109,10 @@ func (r *repository) Transaction(action func(Repository) error) error {
type derpMapCache struct {
sync.RWMutex
value *tailcfg.DERPMap
value *DERPMap
}
func (d *derpMapCache) Get() (*tailcfg.DERPMap, error) {
func (d *derpMapCache) Get() (*DERPMap, error) {
d.RLock()
if d.value != nil {
@@ -128,7 +140,10 @@ func (d *derpMapCache) Get() (*tailcfg.DERPMap, error) {
return nil, err
}
d.value = m
d.value = &DERPMap{
Checksum: util.Checksum(m),
DERPMap: *m,
}
return d.value, nil
}
+71 -5
View File
@@ -2,25 +2,87 @@ package domain
import (
"context"
"crypto"
"crypto/rsa"
"encoding/json"
"errors"
"gorm.io/gorm"
"tailscale.com/tailcfg"
tkey "tailscale.com/types/key"
"time"
)
type configKey string
const (
derpMapConfigKey configKey = "derp_map"
derpMapConfigKey configKey = "derp_map"
controlKeysConfigKey configKey = "control_keys"
jwksConfigKey configKey = "jwks"
)
type JSONWebKeys struct {
Key JSONWebKey
}
type JSONWebKey struct {
Id string
PrivateKey rsa.PrivateKey
CreatedAt time.Time
}
func (j JSONWebKey) Public() crypto.PublicKey {
return j.PrivateKey.Public()
}
type ServerConfig struct {
Key configKey `gorm:"primary_key"`
Value []byte
}
func (r *repository) GetDERPMap(ctx context.Context) (*tailcfg.DERPMap, error) {
var m tailcfg.DERPMap
type ControlKeys struct {
ControlKey tkey.MachinePrivate
LegacyControlKey tkey.MachinePrivate
}
func (r *repository) GetControlKeys(ctx context.Context) (*ControlKeys, error) {
var m ControlKeys
err := r.getServerConfig(ctx, controlKeysConfigKey, &m)
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
if err != nil {
return nil, err
}
return &m, nil
}
func (r *repository) SetControlKeys(ctx context.Context, v *ControlKeys) error {
return r.setServerConfig(ctx, controlKeysConfigKey, v)
}
func (r *repository) GetJSONWebKeySet(ctx context.Context) (*JSONWebKeys, error) {
var m JSONWebKeys
err := r.getServerConfig(ctx, jwksConfigKey, &m)
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
if err != nil {
return nil, err
}
return &m, nil
}
func (r *repository) SetJSONWebKeySet(ctx context.Context, v *JSONWebKeys) error {
return r.setServerConfig(ctx, jwksConfigKey, v)
}
func (r *repository) GetDERPMap(ctx context.Context) (*DERPMap, error) {
var m DERPMap
err := r.getServerConfig(ctx, derpMapConfigKey, &m)
@@ -28,6 +90,10 @@ func (r *repository) GetDERPMap(ctx context.Context) (*tailcfg.DERPMap, error) {
return r.defaultDERPMap.Get()
}
if m.Checksum == "" {
return r.defaultDERPMap.Get()
}
if err != nil {
return nil, err
}
@@ -35,7 +101,7 @@ func (r *repository) GetDERPMap(ctx context.Context) (*tailcfg.DERPMap, error) {
return &m, nil
}
func (r *repository) SetDERPMap(ctx context.Context, v *tailcfg.DERPMap) error {
func (r *repository) SetDERPMap(ctx context.Context, v *DERPMap) error {
return r.setServerConfig(ctx, "derp_map", v)
}
+46
View File
@@ -0,0 +1,46 @@
package domain
import (
"context"
"errors"
"gorm.io/gorm"
"time"
)
type SSHActionRequest struct {
Key string `gorm:"primary_key"`
Action string
SrcMachineID uint64
DstMachineID uint64
CreatedAt time.Time
}
func (r *repository) SaveSSHActionRequest(ctx context.Context, session *SSHActionRequest) error {
tx := r.withContext(ctx).Save(session)
if tx.Error != nil {
return tx.Error
}
return nil
}
func (r *repository) GetSSHActionRequest(ctx context.Context, key string) (*SSHActionRequest, error) {
var m SSHActionRequest
tx := r.withContext(ctx).First(&m, "key = ?", key)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
if tx.Error != nil {
return nil, tx.Error
}
return &m, nil
}
func (r *repository) DeleteSSHActionRequest(ctx context.Context, key string) error {
tx := r.withContext(ctx).Delete(&SSHActionRequest{Key: key})
return tx.Error
}
+55 -7
View File
@@ -5,14 +5,47 @@ import (
"errors"
"github.com/jsiebens/ionscale/internal/util"
"gorm.io/gorm"
"net/mail"
"strings"
"tailscale.com/util/dnsname"
)
type Tailnet struct {
ID uint64 `gorm:"primary_key"`
Name string
DNSConfig DNSConfig
IAMPolicy IAMPolicy
ACLPolicy ACLPolicy
ID uint64 `gorm:"primary_key"`
Name string
Alias *string
DNSConfig DNSConfig
IAMPolicy IAMPolicy
ACLPolicy ACLPolicy
DERPMap DERPMap
ServiceCollectionEnabled bool
FileSharingEnabled bool
SSHEnabled bool
}
func (t Tailnet) GetDERPMap(ctx context.Context, fallack DefaultDERPMap) (*DERPMap, error) {
if t.DERPMap.Checksum == "" {
return fallack.GetDERPMap(ctx)
} else {
return &t.DERPMap, nil
}
}
func SanitizeTailnetName(name string) string {
name = strings.ToLower(name)
a, err := mail.ParseAddress(name)
if err == nil && a.Address == name {
s := strings.Split(name, "@")
return strings.Join([]string{dnsname.SanitizeLabel(s[0]), s[1]}, ".")
}
labels := strings.Split(name, ".")
for i, s := range labels {
labels[i] = dnsname.SanitizeLabel(s)
}
return strings.Join(labels, ".")
}
func (r *repository) SaveTailnet(ctx context.Context, tailnet *Tailnet) error {
@@ -25,13 +58,13 @@ func (r *repository) SaveTailnet(ctx context.Context, tailnet *Tailnet) error {
return nil
}
func (r *repository) GetOrCreateTailnet(ctx context.Context, name string) (*Tailnet, bool, error) {
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()}).
Attrs(Tailnet{ID: id, ACLPolicy: DefaultPolicy(), IAMPolicy: iamPolicy}).
FirstOrCreate(tailnet)
if tx.Error != nil {
@@ -56,6 +89,21 @@ func (r *repository) GetTailnet(ctx context.Context, id uint64) (*Tailnet, error
return &t, nil
}
func (r *repository) GetTailnetByAlias(ctx context.Context, alias string) (*Tailnet, error) {
var t Tailnet
tx := r.withContext(ctx).Take(&t, "alias = ?", alias)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
if tx.Error != nil {
return nil, tx.Error
}
return &t, nil
}
func (r *repository) ListTailnets(ctx context.Context) ([]Tailnet, error) {
var tailnets = []Tailnet{}
tx := r.withContext(ctx).Find(&tailnets)
+15
View File
@@ -0,0 +1,15 @@
package domain
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestSanitizeTailnetName(t *testing.T) {
assert.Equal(t, "john.example.com", SanitizeTailnetName("john@example.com"))
assert.Equal(t, "john.example.com", SanitizeTailnetName("john@examPle.Com"))
assert.Equal(t, "john-doe.example.com", SanitizeTailnetName("john.doe@example.com"))
assert.Equal(t, "johns-network", SanitizeTailnetName("John's Network"))
assert.Equal(t, "example.com", SanitizeTailnetName("example.com"))
assert.Equal(t, "johns-example.com", SanitizeTailnetName("John's example.com"))
}
+58 -7
View File
@@ -58,17 +58,26 @@ type oauthState struct {
func (h *AuthenticationHandlers) StartCliAuth(c echo.Context) error {
ctx := c.Request().Context()
flow := c.Param("flow")
key := c.Param("key")
if s, err := h.repository.GetAuthenticationRequest(ctx, key); err != nil || s == nil {
return c.Redirect(http.StatusFound, "/a/error")
if flow == "c" {
if s, err := h.repository.GetAuthenticationRequest(ctx, key); err != nil || s == nil {
return c.Redirect(http.StatusFound, "/a/error")
}
}
if flow == "s" {
if s, err := h.repository.GetSSHActionRequest(ctx, key); err != nil || s == nil {
return c.Redirect(http.StatusFound, "/a/error")
}
}
if h.authProvider == nil {
return c.Redirect(http.StatusFound, "/a/error")
}
state, err := h.createState("c", key)
state, err := h.createState(flow, key)
if err != nil {
return err
}
@@ -134,12 +143,48 @@ func (h *AuthenticationHandlers) Callback(c echo.Context) error {
return err
}
tailnets, err := h.listAvailableTailnets(ctx, user)
account, _, err := h.repository.GetOrCreateAccount(ctx, user.ID, user.Name)
if err != nil {
return err
}
account, _, err := h.repository.GetOrCreateAccount(ctx, user.ID, user.Name)
if state.Flow == "s" {
sshActionReq, err := h.repository.GetSSHActionRequest(ctx, state.Key)
if err != nil || sshActionReq == nil {
return c.Redirect(http.StatusFound, "/a/error?e=ua")
}
machine, err := h.repository.GetMachine(ctx, sshActionReq.SrcMachineID)
if err != nil || sshActionReq == nil {
return c.Redirect(http.StatusFound, "/a/error")
}
policy := machine.Tailnet.ACLPolicy
if machine.HasTags() && policy.IsTagOwner(machine.Tags, &domain.User{Name: account.LoginName, UserType: domain.UserTypePerson}) {
sshActionReq.Action = "accept"
if err := h.repository.SaveSSHActionRequest(ctx, sshActionReq); err != nil {
return c.Redirect(http.StatusFound, "/a/error")
}
return c.Redirect(http.StatusFound, "/a/success")
}
if machine.User.AccountID != nil && *machine.User.AccountID == account.ID {
sshActionReq.Action = "accept"
if err := h.repository.SaveSSHActionRequest(ctx, sshActionReq); err != nil {
return c.Redirect(http.StatusFound, "/a/error")
}
return c.Redirect(http.StatusFound, "/a/success")
}
sshActionReq.Action = "reject"
if err := h.repository.SaveSSHActionRequest(ctx, sshActionReq); err != nil {
return c.Redirect(http.StatusFound, "/a/error")
}
return c.Redirect(http.StatusFound, "/a/error?e=nmo")
}
tailnets, err := h.listAvailableTailnets(ctx, user)
if err != nil {
return err
}
@@ -248,6 +293,8 @@ func (h *AuthenticationHandlers) Error(c echo.Context) error {
return c.Render(http.StatusForbidden, "unauthorized.html", nil)
case "nto":
return c.Render(http.StatusForbidden, "notagowner.html", nil)
case "nmo":
return c.Render(http.StatusForbidden, "notmachineowner.html", nil)
}
return c.Render(http.StatusOK, "error.html", nil)
}
@@ -393,6 +440,8 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
return c.Redirect(http.StatusFound, "/a/error?e=nto")
}
autoAllowIPs := tailnet.ACLPolicy.FindAutoApprovedIPs(req.Hostinfo.RoutableIPs, tags, user)
var m *domain.Machine
m, err := h.repository.GetMachineByKey(ctx, tailnet.ID, machineKey)
@@ -419,9 +468,10 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
NameIdx: nameIdx,
MachineKey: machineKey,
NodeKey: nodeKey,
Ephemeral: ephemeral,
Ephemeral: ephemeral || req.Ephemeral,
RegisteredTags: registeredTags,
Tags: domain.SanitizeTags(tags),
AutoAllowIPs: autoAllowIPs,
CreatedAt: now,
ExpiresAt: now.Add(180 * 24 * time.Hour).UTC(),
KeyExpiryDisabled: len(tags) != 0,
@@ -451,9 +501,10 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
m.NameIdx = nameIdx
}
m.NodeKey = nodeKey
m.Ephemeral = ephemeral
m.Ephemeral = ephemeral || req.Ephemeral
m.RegisteredTags = registeredTags
m.Tags = domain.SanitizeTags(tags)
m.AutoAllowIPs = autoAllowIPs
m.UserID = user.ID
m.User = *user
m.TailnetID = tailnet.ID
+73
View File
@@ -0,0 +1,73 @@
package handlers
import (
"github.com/jsiebens/ionscale/internal/bind"
"github.com/jsiebens/ionscale/internal/dns"
"github.com/labstack/echo/v4"
"net"
"net/http"
"strings"
"tailscale.com/tailcfg"
"time"
)
func NewDNSHandlers(createBinder bind.Factory, provider dns.Provider) *DNSHandlers {
return &DNSHandlers{
createBinder: createBinder,
provider: provider,
}
}
type DNSHandlers struct {
createBinder bind.Factory
provider dns.Provider
}
func (h *DNSHandlers) SetDNS(c echo.Context) error {
ctx := c.Request().Context()
binder, err := h.createBinder(c)
if err != nil {
return err
}
req := &tailcfg.SetDNSRequest{}
if err := binder.BindRequest(c, req); err != nil {
return err
}
if h.provider == nil {
return echo.NewHTTPError(http.StatusNotFound)
}
if err := h.provider.SetRecord(ctx, req.Type, req.Name, req.Value); err != nil {
return err
}
if strings.HasPrefix(req.Name, "_acme-challenge") && req.Type == "TXT" {
// Listen to connection close
notify := ctx.Done()
timeout := time.After(5 * time.Minute)
tick := time.NewTicker(5 * time.Second)
defer func() { tick.Stop() }()
for {
select {
case <-tick.C:
txtrecords, _ := net.LookupTXT(req.Name)
for _, txt := range txtrecords {
if txt == req.Value {
return binder.WriteResponse(c, http.StatusOK, tailcfg.SetDNSResponse{})
}
}
case <-timeout:
return binder.WriteResponse(c, http.StatusOK, tailcfg.SetDNSResponse{})
case <-notify:
return nil
}
}
}
return binder.WriteResponse(c, http.StatusOK, tailcfg.SetDNSResponse{})
}
+148
View File
@@ -0,0 +1,148 @@
package handlers
import (
"fmt"
"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/util"
"github.com/labstack/echo/v4"
"gopkg.in/square/go-jose.v2"
"net/http"
"tailscale.com/tailcfg"
"time"
)
func NewIDTokenHandlers(createBinder bind.Factory, config *config.Config, repository domain.Repository) *IDTokenHandlers {
return &IDTokenHandlers{
issuer: config.ServerUrl,
jwksUri: config.CreateUrl("/.well-known/jwks"),
createBinder: createBinder,
repository: repository,
}
}
type IDTokenHandlers struct {
issuer string
jwksUri string
createBinder bind.Factory
repository domain.Repository
}
func (h *IDTokenHandlers) OpenIDConfig(c echo.Context) error {
v := map[string]interface{}{}
v["issuer"] = h.issuer
v["jwks_uri"] = h.jwksUri
v["subject_types_supported"] = []string{"public"}
v["response_types_supported"] = []string{"id_token"}
v["scopes_supported"] = []string{"openid"}
v["id_token_signing_alg_values_supported"] = []string{"RS256"}
v["claims_supported"] = []string{
"sub",
"aud",
"exp",
"iat",
"iss",
"jti",
"nbf",
}
return c.JSON(http.StatusOK, v)
}
func (h *IDTokenHandlers) Jwks(c echo.Context) error {
keySet, err := h.repository.GetJSONWebKeySet(c.Request().Context())
if err != nil {
return err
}
pub := jose.JSONWebKey{Key: keySet.Key.Public(), KeyID: keySet.Key.Id, Algorithm: "RS256", Use: "sig"}
set := jose.JSONWebKeySet{Keys: []jose.JSONWebKey{pub}}
return c.JSON(http.StatusOK, set)
}
func (h *IDTokenHandlers) FetchToken(c echo.Context) error {
ctx := c.Request().Context()
keySet, err := h.repository.GetJSONWebKeySet(c.Request().Context())
if err != nil {
return err
}
binder, err := h.createBinder(c)
if err != nil {
return err
}
req := &tailcfg.TokenRequest{}
if err := binder.BindRequest(c, req); err != nil {
return err
}
machineKey := binder.Peer().String()
nodeKey := req.NodeKey.String()
var m *domain.Machine
m, err = h.repository.GetMachineByKeys(ctx, machineKey, nodeKey)
if err != nil {
return err
}
if m == nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
_, tailnetDomain, sub := h.names(m)
now := time.Now()
claims := jwt.MapClaims{
"jit": fmt.Sprintf("%d", util.NextID()),
"iss": h.issuer,
"sub": sub,
"aud": []string{req.Audience},
"exp": jwt.NewNumericDate(now.Add(5 * time.Minute)),
"nbf": jwt.NewNumericDate(now),
"iat": jwt.NewNumericDate(now),
"key": m.NodeKey,
"addresses": []string{m.IPv4.String(), m.IPv6.String()},
"nid": m.ID,
"node": sub,
"domain": tailnetDomain,
}
if m.HasTags() {
tags := []string{}
for _, t := range m.Tags {
tags = append(tags, fmt.Sprintf("%s:%s", tailnetDomain, t))
}
claims["tags"] = tags
} else {
claims["user"] = fmt.Sprintf("%s:%s", tailnetDomain, m.User.Name)
claims["uid"] = m.UserID
}
unsignedToken := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
unsignedToken.Header["kid"] = keySet.Key.Id
jwtB64, err := unsignedToken.SignedString(&keySet.Key.PrivateKey)
if err != nil {
return err
}
resp := tailcfg.TokenResponse{IDToken: jwtB64}
return binder.WriteResponse(c, http.StatusOK, resp)
}
func (h *IDTokenHandlers) names(m *domain.Machine) (string, string, string) {
var name = m.Name
if m.NameIdx != 0 {
name = fmt.Sprintf("%s-%d", m.Name, m.NameIdx)
}
sanitizedTailnetName := domain.SanitizeTailnetName(m.Tailnet.Name)
return name, sanitizedTailnetName, fmt.Sprintf("%s.%s", name, sanitizedTailnetName)
}
+1 -2
View File
@@ -1,7 +1,6 @@
package handlers
import (
"context"
"github.com/labstack/echo/v4"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
@@ -26,7 +25,7 @@ func NewNoiseHandlers(controlKey key.MachinePrivate, createPeerHandler CreatePee
}
func (h *NoiseHandlers) Upgrade(c echo.Context) error {
conn, err := controlhttp.AcceptHTTP(context.Background(), c.Response(), c.Request(), h.controlKey)
conn, err := controlhttp.AcceptHTTP(c.Request().Context(), c.Response(), c.Request(), h.controlKey)
if err != nil {
return err
}
+57 -38
View File
@@ -10,7 +10,7 @@ import (
"github.com/labstack/echo/v4"
"net/http"
"tailscale.com/tailcfg"
"tailscale.com/util/dnsname"
"tailscale.com/types/opt"
"time"
)
@@ -93,8 +93,9 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
}
var syncedPeers = make(map[uint64]bool)
var derpMapChecksum = ""
response, syncedPeers, err := h.createMapResponse(m, binder, mapRequest, false, make(map[uint64]bool))
response, syncedPeers, derpMapChecksum, err := h.createMapResponse(m, binder, mapRequest, false, make(map[uint64]bool), derpMapChecksum)
if err != nil {
return err
}
@@ -114,7 +115,7 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
if err != nil {
return err
}
keepAliveTicker := time.NewTicker(config.KeepAliveInterval)
keepAliveTicker := time.NewTicker(config.KeepAliveInterval())
syncTicker := time.NewTicker(5 * time.Second)
c.Response().WriteHeader(http.StatusOK)
@@ -163,7 +164,7 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
var payload []byte
var payloadErr error
payload, syncedPeers, payloadErr = h.createMapResponse(machine, binder, mapRequest, true, syncedPeers)
payload, syncedPeers, derpMapChecksum, payloadErr = h.createMapResponse(machine, binder, mapRequest, true, syncedPeers, derpMapChecksum)
if payloadErr != nil {
return payloadErr
@@ -192,7 +193,7 @@ func (h *PollNetMapHandler) handleReadOnly(c echo.Context, binder bind.Binder, m
return err
}
response, _, err := h.createMapResponse(m, binder, request, false, map[uint64]bool{})
response, _, _, err := h.createMapResponse(m, binder, request, false, map[uint64]bool{}, "")
if err != nil {
return err
}
@@ -217,27 +218,29 @@ func (h *PollNetMapHandler) createKeepAliveResponse(binder bind.Binder, request
return binder.Marshal(request.Compress, mapResponse)
}
func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Binder, request *tailcfg.MapRequest, delta bool, prevSyncedPeerIDs map[uint64]bool) ([]byte, map[uint64]bool, error) {
func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Binder, request *tailcfg.MapRequest, delta bool, prevSyncedPeerIDs map[uint64]bool, prevDerpMapChecksum string) ([]byte, map[uint64]bool, string, error) {
ctx := context.TODO()
node, user, err := mapping.ToNode(m)
if err != nil {
return nil, nil, err
}
tailnet, err := h.repository.GetTailnet(ctx, m.TailnetID)
if err != nil {
return nil, nil, err
return nil, nil, "", err
}
hostinfo := tailcfg.Hostinfo(m.HostInfo)
node, user, err := mapping.ToNode(m, tailnet, false)
if err != nil {
return nil, nil, "", err
}
policies := tailnet.ACLPolicy
var users = []tailcfg.UserProfile{*user}
var changedPeers []*tailcfg.Node
var removedPeers []tailcfg.NodeID
var validPeers []domain.Machine
candidatePeers, err := h.repository.ListMachinePeers(ctx, m.TailnetID, m.MachineKey)
if err != nil {
return nil, nil, err
return nil, nil, "", err
}
syncedPeerIDs := map[uint64]bool{}
@@ -248,9 +251,10 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
continue
}
if policies.IsValidPeer(m, &peer) || policies.IsValidPeer(&peer, m) {
n, u, err := mapping.ToNode(&peer)
validPeers = append(validPeers, peer)
n, u, err := mapping.ToNode(&peer, tailnet, true)
if err != nil {
return nil, nil, err
return nil, nil, "", err
}
changedPeers = append(changedPeers, n)
syncedPeerIDs[peer.ID] = true
@@ -269,43 +273,52 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
dnsConfig := tailnet.DNSConfig
derpMap, err := h.repository.GetDERPMap(ctx)
derpMap, err := m.Tailnet.GetDERPMap(ctx, h.repository)
if err != nil {
return nil, nil, err
return nil, nil, "", err
}
rules := policies.BuildFilterRules(candidatePeers, m)
filterRules := policies.BuildFilterRules(candidatePeers, m)
controlTime := time.Now().UTC()
var mapResponse *tailcfg.MapResponse
if !delta {
mapResponse = &tailcfg.MapResponse{
KeepAlive: false,
Node: node,
DNSConfig: mapping.ToDNSConfig(&m.Tailnet, &dnsConfig),
PacketFilter: rules,
DERPMap: derpMap,
Domain: dnsname.SanitizeHostname(m.Tailnet.Name),
Peers: changedPeers,
UserProfiles: users,
ControlTime: &controlTime,
KeepAlive: false,
Node: node,
DNSConfig: mapping.ToDNSConfig(m, validPeers, &m.Tailnet, &dnsConfig),
PacketFilter: filterRules,
DERPMap: &derpMap.DERPMap,
Domain: domain.SanitizeTailnetName(m.Tailnet.Name),
Peers: changedPeers,
UserProfiles: users,
ControlTime: &controlTime,
CollectServices: optBool(tailnet.ServiceCollectionEnabled),
Debug: &tailcfg.Debug{
DisableLogTail: true,
},
}
} else {
mapResponse = &tailcfg.MapResponse{
Node: node,
DNSConfig: mapping.ToDNSConfig(&m.Tailnet, &dnsConfig),
PacketFilter: rules,
DERPMap: derpMap,
Domain: dnsname.SanitizeHostname(m.Tailnet.Name),
PeersChanged: changedPeers,
PeersRemoved: removedPeers,
UserProfiles: users,
ControlTime: &controlTime,
Node: node,
DNSConfig: mapping.ToDNSConfig(m, validPeers, &m.Tailnet, &dnsConfig),
PacketFilter: filterRules,
Domain: domain.SanitizeTailnetName(m.Tailnet.Name),
PeersChanged: changedPeers,
PeersRemoved: removedPeers,
UserProfiles: users,
ControlTime: &controlTime,
CollectServices: optBool(tailnet.ServiceCollectionEnabled),
}
if prevDerpMapChecksum != derpMap.Checksum {
mapResponse.DERPMap = &derpMap.DERPMap
}
}
if tailnet.SSHEnabled && hostinfo.TailscaleSSHEnabled() {
mapResponse.SSHPolicy = policies.BuildSSHPolicy(candidatePeers, m)
}
if request.OmitPeers {
@@ -316,7 +329,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
payload, err := binder.Marshal(request.Compress, mapResponse)
return payload, syncedPeerIDs, nil
return payload, syncedPeerIDs, derpMap.Checksum, nil
}
func NewOfflineTimers(repository domain.Repository, pubsub broker.Pubsub) *OfflineTimers {
@@ -355,7 +368,7 @@ func (o *OfflineTimers) scheduleOfflineMessage(tailnetID, machineID uint64) {
delete(o.data, machineID)
}
timer := time.NewTimer(config.KeepAliveInterval)
timer := time.NewTimer(config.KeepAliveInterval())
go func() {
<-timer.C
o.pubsub.Publish(tailnetID, &broker.Signal{PeerUpdated: &machineID})
@@ -372,3 +385,9 @@ func (o *OfflineTimers) cancelOfflineMessage(machineID uint64) {
delete(o.data, machineID)
}
}
func optBool(v bool) opt.Bool {
b := opt.Bool("")
b.Set(v)
return b
}
+10 -10
View File
@@ -156,6 +156,12 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
return binder.WriteResponse(c, http.StatusOK, response)
}
registeredTags := authKey.Tags
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
tags := append(registeredTags, advertisedTags...)
autoAllowIPs := tailnet.ACLPolicy.FindAutoApprovedIPs(req.Hostinfo.RoutableIPs, tags, &user)
var m *domain.Machine
m, err = h.repository.GetMachineByKey(ctx, tailnet.ID, machineKey)
@@ -166,10 +172,6 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
now := time.Now().UTC()
if m == nil {
registeredTags := authKey.Tags
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
tags := append(registeredTags, advertisedTags...)
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
if err != nil {
@@ -182,9 +184,10 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
NameIdx: nameIdx,
MachineKey: machineKey,
NodeKey: nodeKey,
Ephemeral: authKey.Ephemeral,
Ephemeral: authKey.Ephemeral || req.Ephemeral,
RegisteredTags: registeredTags,
Tags: domain.SanitizeTags(tags),
AutoAllowIPs: autoAllowIPs,
CreatedAt: now,
ExpiresAt: now.Add(180 * 24 * time.Hour).UTC(),
KeyExpiryDisabled: len(tags) != 0,
@@ -204,10 +207,6 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
m.IPv4 = domain.IP{Addr: ipv4}
m.IPv6 = domain.IP{Addr: ipv6}
} else {
registeredTags := authKey.Tags
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
tags := append(registeredTags, advertisedTags...)
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
if m.Name != sanitizeHostname {
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
@@ -218,9 +217,10 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
m.NameIdx = nameIdx
}
m.NodeKey = nodeKey
m.Ephemeral = authKey.Ephemeral
m.Ephemeral = authKey.Ephemeral || req.Ephemeral
m.RegisteredTags = registeredTags
m.Tags = domain.SanitizeTags(tags)
m.AutoAllowIPs = autoAllowIPs
m.UserID = user.ID
m.User = user
m.TailnetID = tailnet.ID
+113
View File
@@ -0,0 +1,113 @@
package handlers
import (
"fmt"
"github.com/jsiebens/ionscale/internal/bind"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/util"
"github.com/labstack/echo/v4"
"net/http"
"tailscale.com/tailcfg"
"time"
)
func NewSSHActionHandlers(createBinder bind.Factory, config *config.Config, repository domain.Repository) *SSHActionHandlers {
return &SSHActionHandlers{
createBinder: createBinder,
repository: repository,
config: config,
}
}
type SSHActionHandlers struct {
createBinder bind.Factory
repository domain.Repository
config *config.Config
}
type sshActionRequestData struct {
SrcMachineID uint64 `param:"src_machine_id"`
DstMachineID uint64 `param:"dst_machine_id"`
}
func (h *SSHActionHandlers) StartAuth(c echo.Context) error {
ctx := c.Request().Context()
binder, err := h.createBinder(c)
if err != nil {
return err
}
data := new(sshActionRequestData)
if err = c.Bind(data); err != nil {
return c.String(http.StatusBadRequest, "bad request")
}
key := util.RandStringBytes(8)
request := &domain.SSHActionRequest{
Key: key,
SrcMachineID: data.SrcMachineID,
DstMachineID: data.DstMachineID,
CreatedAt: time.Now().UTC(),
}
authUrl := h.config.CreateUrl("/a/s/%s", key)
if err := h.repository.SaveSSHActionRequest(ctx, request); err != nil {
return err
}
resp := &tailcfg.SSHAction{
Message: fmt.Sprintf("# Tailscale SSH requires an additional check.\n# To authenticate, visit: %s\n", authUrl),
HoldAndDelegate: fmt.Sprintf("https://unused/machine/ssh/action/check/%s", key),
}
return binder.WriteResponse(c, http.StatusOK, resp)
}
func (h *SSHActionHandlers) CheckAuth(c echo.Context) error {
// Listen to connection close
ctx := c.Request().Context()
notify := ctx.Done()
binder, err := h.createBinder(c)
if err != nil {
return err
}
tick := time.NewTicker(2 * time.Second)
defer func() { tick.Stop() }()
key := c.Param("key")
for {
select {
case <-tick.C:
m, err := h.repository.GetSSHActionRequest(ctx, key)
if err != nil || m == nil {
return binder.WriteResponse(c, http.StatusOK, &tailcfg.SSHAction{Reject: true})
}
if m.Action == "accept" {
action := &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
}
_ = h.repository.DeleteSSHActionRequest(ctx, key)
return binder.WriteResponse(c, http.StatusOK, action)
}
if m.Action == "reject" {
action := &tailcfg.SSHAction{Reject: true}
_ = h.repository.DeleteSSHActionRequest(ctx, key)
return binder.WriteResponse(c, http.StatusOK, action)
}
case <-notify:
return nil
}
}
}
+83 -29
View File
@@ -11,12 +11,9 @@ import (
"tailscale.com/tailcfg"
"tailscale.com/types/dnstype"
"tailscale.com/types/key"
"tailscale.com/util/dnsname"
"time"
)
const NetworkMagicDNSSuffix = "ionscale.net"
func CopyViaJson[F any, T any](f F, t T) error {
raw, err := json.Marshal(f)
if err != nil {
@@ -30,8 +27,17 @@ func CopyViaJson[F any, T any](f F, t T) error {
return nil
}
func ToDNSConfig(tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfig {
tailnetDomain := dnsname.SanitizeHostname(tailnet.Name)
func ToDNSConfig(m *domain.Machine, peers []domain.Machine, tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfig {
certDNSSuffix := config.CertDNSSuffix()
certsEnabled := c.HttpsCertsEnabled && len(certDNSSuffix) != 0
tailnetDomain := domain.SanitizeTailnetName(tailnet.Name)
var certDomain = ""
if certsEnabled {
certDomain = domain.SanitizeTailnetName(*tailnet.Alias)
}
resolvers := []*dnstype.Resolver{}
for _, r := range c.Nameservers {
resolver := &dnstype.Resolver{
@@ -40,23 +46,34 @@ func ToDNSConfig(tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfi
resolvers = append(resolvers, resolver)
}
config := &tailcfg.DNSConfig{}
dnsConfig := &tailcfg.DNSConfig{}
var domains []string
var certDomains []string
if c.MagicDNS {
domains = append(domains, fmt.Sprintf("%s.%s", tailnetDomain, NetworkMagicDNSSuffix))
config.Proxied = true
domains = append(domains, fmt.Sprintf("%s.%s", tailnetDomain, config.MagicDNSSuffix()))
dnsConfig.Proxied = true
if certsEnabled {
domains = append(domains, fmt.Sprintf("%s.%s", certDomain, certDNSSuffix))
certDomains = append(certDomains, fmt.Sprintf("%s.%s.%s", m.CompleteName(), certDomain, certDNSSuffix))
}
}
if c.OverrideLocalDNS {
config.Resolvers = resolvers
dnsConfig.Resolvers = resolvers
} else {
config.FallbackResolvers = resolvers
dnsConfig.FallbackResolvers = resolvers
}
if len(c.Routes) != 0 {
if len(c.Routes) != 0 || certsEnabled {
routes := make(map[string][]*dnstype.Resolver)
if certsEnabled {
routes[fmt.Sprintf("%s.", certDNSSuffix)] = nil
}
for r, s := range c.Routes {
routeResolver := []*dnstype.Resolver{}
for _, addr := range s {
@@ -66,15 +83,50 @@ func ToDNSConfig(tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfi
routes[r] = routeResolver
domains = append(domains, r)
}
config.Routes = routes
dnsConfig.Routes = routes
}
config.Domains = domains
dnsConfig.Domains = domains
dnsConfig.CertDomains = certDomains
return config
if certsEnabled {
var extraRecords = []tailcfg.DNSRecord{{
Name: fmt.Sprintf("%s.%s.%s", m.CompleteName(), certDomain, certDNSSuffix),
Value: m.IPv4.String(),
}}
for _, p := range peers {
extraRecords = append(extraRecords, tailcfg.DNSRecord{
Name: fmt.Sprintf("%s.%s.%s", p.CompleteName(), certDomain, certDNSSuffix),
Value: p.IPv4.String(),
})
}
dnsConfig.ExtraRecords = extraRecords
}
return dnsConfig
}
func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
func ToNode(m *domain.Machine, tailnet *domain.Tailnet, peer bool) (*tailcfg.Node, *tailcfg.UserProfile, error) {
role := tailnet.IAMPolicy.GetRole(m.User)
var capabilities []string
if !peer {
if !m.HasTags() && role == domain.UserRoleAdmin {
capabilities = append(capabilities, tailcfg.CapabilityAdmin)
}
if tailnet.FileSharingEnabled {
capabilities = append(capabilities, tailcfg.CapabilityFileSharing)
}
if tailnet.SSHEnabled {
capabilities = append(capabilities, tailcfg.CapabilitySSH)
}
}
nKey, err := util.ParseNodePublicKey(m.NodeKey)
if err != nil {
return nil, nil, err
@@ -119,6 +171,7 @@ func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
}
allowedIPs = append(allowedIPs, m.AllowIPs...)
allowedIPs = append(allowedIPs, m.AutoAllowIPs...)
var derp string
if hostinfo.NetInfo != nil {
@@ -127,23 +180,20 @@ func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
derp = "127.3.3.40:0"
}
var name = m.Name
if m.NameIdx != 0 {
name = fmt.Sprintf("%s-%d", m.Name, m.NameIdx)
}
var name = m.CompleteName()
sanitizedTailnetName := dnsname.SanitizeHostname(m.Tailnet.Name)
sanitizedTailnetName := domain.SanitizeTailnetName(m.Tailnet.Name)
hostInfo := tailcfg.Hostinfo{
OS: hostinfo.OS,
Hostname: hostinfo.Hostname,
Services: hostinfo.Services,
Services: filterServices(hostinfo.Services),
}
n := tailcfg.Node{
ID: tailcfg.NodeID(m.ID),
StableID: tailcfg.StableNodeID(strconv.FormatUint(m.ID, 10)),
Name: fmt.Sprintf("%s.%s.%s.", name, sanitizedTailnetName, NetworkMagicDNSSuffix),
Name: fmt.Sprintf("%s.%s.%s.", name, sanitizedTailnetName, config.MagicDNSSuffix()),
Key: *nKey,
Machine: *mKey,
DiscoKey: discoKey,
@@ -152,7 +202,8 @@ func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
Endpoints: endpoints,
DERP: derp,
Hostinfo: hostInfo.View(),
Hostinfo: hostInfo.View(),
Capabilities: capabilities,
Created: m.CreatedAt.UTC(),
@@ -171,7 +222,7 @@ func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
if m.LastSeen != nil {
l := m.LastSeen.UTC()
online := m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval))
online := m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval()))
n.LastSeen = &l
n.Online = &online
}
@@ -199,10 +250,13 @@ func ToUserProfile(u domain.User) tailcfg.UserProfile {
return profile
}
func ToUserProfiles(users domain.Users) []tailcfg.UserProfile {
var profiles []tailcfg.UserProfile
for _, u := range users {
profiles = append(profiles, ToUserProfile(u))
func filterServices(services []tailcfg.Service) []tailcfg.Service {
result := []tailcfg.Service{}
for _, s := range services {
if s.Proto == tailcfg.TCP || s.Proto == tailcfg.UDP {
continue
}
result = append(result, s)
}
return profiles
return result
}
+4
View File
@@ -85,10 +85,14 @@ func (p *OIDCProvider) Exchange(redirectURI, code string) (*User, error) {
return nil, err
}
domain := strings.Split(email, "@")[1]
return &User{
ID: sub,
Name: email,
Attr: map[string]interface{}{
"email": email,
"domain": domain,
"token": tokenClaims,
"userinfo": userInfoClaims,
},
+45 -13
View File
@@ -9,6 +9,7 @@ import (
"github.com/jsiebens/ionscale/internal/bind"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/database"
"github.com/jsiebens/ionscale/internal/dns"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/handlers"
"github.com/jsiebens/ionscale/internal/provider"
@@ -37,12 +38,17 @@ func Start(c *config.Config) error {
logger.Info("Starting ionscale server")
serverKey, err := c.ReadServerKeys()
repository, brokers, err := database.OpenDB(&c.Database, logger)
if err != nil {
return err
}
repository, brokers, err := database.OpenDB(&c.Database, logger)
defaultControlKeys, err := repository.GetControlKeys(context.Background())
if err != nil {
return err
}
serverKey, err := c.ReadServerKeys(defaultControlKeys)
if err != nil {
return err
}
@@ -76,27 +82,41 @@ func Start(c *config.Config) error {
c.HttpsListenAddr = fmt.Sprintf(":%d", certmagic.HTTPSPort)
}
authProvider, systemIAMPolicy, err := setupAuthProvider(c.Auth)
if err != nil {
return fmt.Errorf("error configuring OIDC provider: %v", err)
}
dnsProvider, err := dns.NewProvider(c.DNS.Provider)
if err != nil {
return err
}
createPeerHandler := func(p key.MachinePublic) http.Handler {
registrationHandlers := handlers.NewRegistrationHandlers(bind.DefaultBinder(p), c, brokers, repository)
pollNetMapHandler := handlers.NewPollNetMapHandler(bind.DefaultBinder(p), brokers, repository, offlineTimers)
dnsHandlers := handlers.NewDNSHandlers(bind.DefaultBinder(p), dnsProvider)
idTokenHandlers := handlers.NewIDTokenHandlers(bind.DefaultBinder(p), c, repository)
sshActionHandlers := handlers.NewSSHActionHandlers(bind.DefaultBinder(p), c, repository)
e := echo.New()
e.Use(EchoLogger(logger))
e.Use(EchoRecover(logger))
e.POST("/machine/register", registrationHandlers.Register)
e.POST("/machine/map", pollNetMapHandler.PollNetMap)
e.POST("/machine/set-dns", dnsHandlers.SetDNS)
e.POST("/machine/id-token", idTokenHandlers.FetchToken)
e.GET("/machine/ssh/action/:src_machine_id/to/:dst_machine_id", sshActionHandlers.StartAuth)
e.GET("/machine/ssh/action/check/:key", sshActionHandlers.CheckAuth)
return e
}
authProvider, systemIAMPolicy, err := setupAuthProvider(c.AuthProvider)
if err != nil {
return err
}
noiseHandlers := handlers.NewNoiseHandlers(serverKey.ControlKey, createPeerHandler)
registrationHandlers := handlers.NewRegistrationHandlers(bind.BoxBinder(serverKey.LegacyControlKey), c, brokers, repository)
pollNetMapHandler := handlers.NewPollNetMapHandler(bind.BoxBinder(serverKey.LegacyControlKey), brokers, repository, offlineTimers)
dnsHandlers := handlers.NewDNSHandlers(bind.BoxBinder(serverKey.LegacyControlKey), dnsProvider)
idTokenHandlers := handlers.NewIDTokenHandlers(bind.BoxBinder(serverKey.LegacyControlKey), c, repository)
authenticationHandlers := handlers.NewAuthenticationHandlers(
c,
authProvider,
@@ -134,6 +154,9 @@ func Start(c *config.Config) error {
tlsAppHandler.POST("/ts2021", noiseHandlers.Upgrade)
tlsAppHandler.POST("/machine/:id", registrationHandlers.Register)
tlsAppHandler.POST("/machine/:id/map", pollNetMapHandler.PollNetMap)
tlsAppHandler.POST("/machine/:id/set-dns", dnsHandlers.SetDNS)
tlsAppHandler.GET("/.well-known/jwks", idTokenHandlers.Jwks)
tlsAppHandler.GET("/.well-known/openid-configuration", idTokenHandlers.OpenIDConfig)
auth := tlsAppHandler.Group("/a")
auth.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
@@ -141,7 +164,7 @@ func Start(c *config.Config) error {
}))
auth.GET("/:key", authenticationHandlers.StartAuth)
auth.POST("/:key", authenticationHandlers.ProcessAuth)
auth.GET("/c/:key", authenticationHandlers.StartCliAuth)
auth.GET("/:flow/:key", authenticationHandlers.StartCliAuth)
auth.GET("/callback", authenticationHandlers.Callback)
auth.POST("/callback", authenticationHandlers.EndOAuth)
auth.GET("/success", authenticationHandlers.Success)
@@ -187,12 +210,12 @@ func Start(c *config.Config) error {
return g.Wait()
}
func setupAuthProvider(config config.AuthProvider) (provider.AuthProvider, *domain.IAMPolicy, error) {
if len(config.Issuer) == 0 {
func setupAuthProvider(config config.Auth) (provider.AuthProvider, *domain.IAMPolicy, error) {
if len(config.Provider.Issuer) == 0 {
return nil, &domain.IAMPolicy{}, nil
}
authProvider, err := provider.NewOIDCProvider(&config)
authProvider, err := provider.NewOIDCProvider(&config.Provider)
if err != nil {
return nil, nil, err
}
@@ -220,9 +243,18 @@ func tlsListener(config *config.Config) (net.Listener, error) {
return tls.Listen("tcp", config.HttpsListenAddr, tlsConfig)
}
cer, err := tls.LoadX509KeyPair(config.Tls.CertFile, config.Tls.KeyFile)
certPEMBlock, err := os.ReadFile(config.Tls.CertFile)
if err != nil {
return nil, err
return nil, fmt.Errorf("error reading cert file: %v", err)
}
keyPEMBlock, err := os.ReadFile(config.Tls.KeyFile)
if err != nil {
return nil, fmt.Errorf("error reading key file: %v", err)
}
cer, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
if err != nil {
return nil, fmt.Errorf("error reading cert and key file: %v", err)
}
tlsConfig := &tls.Config{Certificates: []tls.Certificate{cer}}
+1 -5
View File
@@ -134,11 +134,7 @@ func (s *Service) CreateAuthKey(ctx context.Context, req *connect.Request[api.Cr
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if principal.IsSystemAdmin() {
if err := tailnet.ACLPolicy.CheckTags(req.Msg.Tags); err != nil {
return nil, connect.NewError(connect.CodeInvalidArgument, err)
}
} else {
if !principal.IsSystemAdmin() {
if err := tailnet.ACLPolicy.CheckTagOwners(req.Msg.Tags, principal.User); err != nil {
return nil, connect.NewError(connect.CodeInvalidArgument, err)
}
+39 -9
View File
@@ -6,38 +6,48 @@ import (
"errors"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/broker"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/util"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"tailscale.com/tailcfg"
)
func (s *Service) GetDERPMap(ctx context.Context, _ *connect.Request[api.GetDERPMapRequest]) (*connect.Response[api.GetDERPMapResponse], error) {
func (s *Service) GetDefaultDERPMap(ctx context.Context, _ *connect.Request[api.GetDefaultDERPMapRequest]) (*connect.Response[api.GetDefaultDERPMapResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
derpMap, err := s.repository.GetDERPMap(ctx)
dm, err := s.repository.GetDERPMap(ctx)
if err != nil {
return nil, err
}
raw, err := json.Marshal(derpMap)
raw, err := json.Marshal(dm.DERPMap)
if err != nil {
return nil, err
}
return connect.NewResponse(&api.GetDERPMapResponse{Value: raw}), nil
return connect.NewResponse(&api.GetDefaultDERPMapResponse{Value: raw}), nil
}
func (s *Service) SetDERPMap(ctx context.Context, req *connect.Request[api.SetDERPMapRequest]) (*connect.Response[api.SetDERPMapResponse], error) {
func (s *Service) SetDefaultDERPMap(ctx context.Context, req *connect.Request[api.SetDefaultDERPMapRequest]) (*connect.Response[api.SetDefaultDERPMapResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
var derpMap tailcfg.DERPMap
err := json.Unmarshal(req.Msg.Value, &derpMap)
if err != nil {
if err := json.Unmarshal(req.Msg.Value, &derpMap); err != nil {
return nil, err
}
dp := domain.DERPMap{
Checksum: util.Checksum(&derpMap),
DERPMap: derpMap,
}
if err := s.repository.SetDERPMap(ctx, &dp); err != nil {
return nil, err
}
@@ -46,7 +56,27 @@ func (s *Service) SetDERPMap(ctx context.Context, req *connect.Request[api.SetDE
return nil, err
}
if err := s.repository.SetDERPMap(ctx, &derpMap); err != nil {
for _, t := range tailnets {
s.pubsub.Publish(t.ID, &broker.Signal{})
}
return connect.NewResponse(&api.SetDefaultDERPMapResponse{Value: req.Msg.Value}), nil
}
func (s *Service) ResetDefaultDERPMap(ctx context.Context, req *connect.Request[api.ResetDefaultDERPMapRequest]) (*connect.Response[api.ResetDefaultDERPMapResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
dp := domain.DERPMap{}
if err := s.repository.SetDERPMap(ctx, &dp); err != nil {
return nil, err
}
tailnets, err := s.repository.ListTailnets(ctx)
if err != nil {
return nil, err
}
@@ -54,5 +84,5 @@ func (s *Service) SetDERPMap(ctx context.Context, req *connect.Request[api.SetDE
s.pubsub.Publish(t.ID, &broker.Signal{})
}
return connect.NewResponse(&api.SetDERPMapResponse{Value: req.Msg.Value}), nil
return connect.NewResponse(&api.ResetDefaultDERPMapResponse{}), nil
}
+84 -12
View File
@@ -6,8 +6,8 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/broker"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/mapping"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"tailscale.com/util/dnsname"
)
@@ -26,16 +26,16 @@ func (s *Service) GetDNSConfig(ctx context.Context, req *connect.Request[api.Get
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
config := tailnet.DNSConfig
tailnetDomain := dnsname.SanitizeHostname(tailnet.Name)
dnsConfig := tailnet.DNSConfig
tailnetDomain := domain.SanitizeTailnetName(tailnet.Name)
resp := &api.GetDNSConfigResponse{
Config: &api.DNSConfig{
MagicDns: config.MagicDNS,
MagicDnsSuffix: fmt.Sprintf("%s.%s", tailnetDomain, mapping.NetworkMagicDNSSuffix),
OverrideLocalDns: config.OverrideLocalDNS,
Nameservers: config.Nameservers,
Routes: domainRoutesToApiRoutes(config.Routes),
MagicDns: dnsConfig.MagicDNS,
MagicDnsSuffix: fmt.Sprintf("%s.%s", tailnetDomain, config.MagicDNSSuffix()),
OverrideLocalDns: dnsConfig.OverrideLocalDNS,
Nameservers: dnsConfig.Nameservers,
Routes: domainRoutesToApiRoutes(dnsConfig.Routes),
},
}
@@ -50,10 +50,6 @@ func (s *Service) SetDNSConfig(ctx context.Context, req *connect.Request[api.Set
dnsConfig := req.Msg.Config
if dnsConfig.MagicDns && len(dnsConfig.Nameservers) == 0 {
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("at least one global nameserver is required when enabling magic dns"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
@@ -80,6 +76,82 @@ func (s *Service) SetDNSConfig(ctx context.Context, req *connect.Request[api.Set
return connect.NewResponse(resp), nil
}
func (s *Service) EnableHttpsCertificates(ctx context.Context, req *connect.Request[api.EnableHttpsCertificatesRequest]) (*connect.Response[api.EnableHttpsCertificatesResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
alias := dnsname.SanitizeLabel(req.Msg.Alias)
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if !tailnet.DNSConfig.MagicDNS {
return nil, connect.NewError(connect.CodeFailedPrecondition, errors.New("MagicDNS must be enabled for this tailnet"))
}
if tailnet.Alias == nil && len(alias) == 0 {
return nil, connect.NewError(connect.CodeFailedPrecondition, errors.New("when enabling HTTPS certificates for the first time, a Tailnet alias is required"))
}
if tailnet.Alias != nil && len(alias) != 0 && *tailnet.Alias != alias {
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("a Tailnet alias was already configured previously"))
}
tailnet.DNSConfig.HttpsCertsEnabled = true
if tailnet.Alias == nil && len(alias) != 0 {
t, err := s.repository.GetTailnetByAlias(ctx, alias)
if err != nil {
return nil, err
}
if t != nil && t.ID != tailnet.ID {
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("given alias is already in use"))
}
tailnet.Alias = &alias
}
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{DNSUpdated: true})
return connect.NewResponse(&api.EnableHttpsCertificatesResponse{}), nil
}
func (s *Service) DisableHttpsCertificates(ctx context.Context, req *connect.Request[api.DisableHttpsCertificatesRequest]) (*connect.Response[api.DisableHttpsCertificatesResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
tailnet.DNSConfig.HttpsCertsEnabled = false
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{DNSUpdated: true})
return connect.NewResponse(&api.DisableHttpsCertificatesResponse{}), nil
}
func domainRoutesToApiRoutes(routes map[string][]string) map[string]*api.Routes {
var result = map[string]*api.Routes{}
for k, v := range routes {
+100 -36
View File
@@ -25,17 +25,7 @@ func (s *Service) machineToApi(m *domain.Machine) *api.Machine {
online := false
if m.LastSeen != nil {
lastSeen = timestamppb.New(*m.LastSeen)
online = m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval))
}
var advertisedRoutes []string
for _, r := range m.HostInfo.RoutableIPs {
advertisedRoutes = append(advertisedRoutes, r.String())
}
var enabledRoutes []string
for _, r := range m.AllowIPs {
enabledRoutes = append(enabledRoutes, r.String())
online = m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval()))
}
return &api.Machine{
@@ -63,8 +53,10 @@ func (s *Service) machineToApi(m *domain.Machine) *api.Machine {
ClientConnectivity: &api.ClientConnectivity{
Endpoints: m.Endpoints,
},
AdvertisedRoutes: advertisedRoutes,
EnabledRoutes: enabledRoutes,
AdvertisedRoutes: m.AdvertisedPrefixes(),
EnabledRoutes: m.AllowedPrefixes(),
AdvertisedExitNode: m.IsAdvertisedExitNode(),
EnabledExitNode: m.IsAllowedExitNode(),
}
}
@@ -169,19 +161,11 @@ func (s *Service) ExpireMachine(ctx context.Context, req *connect.Request[api.Ex
}
func (s *Service) createMachineRoutesResponse(m *domain.Machine) (*connect.Response[api.GetMachineRoutesResponse], error) {
var advertisedRoutes []string
for _, r := range m.HostInfo.RoutableIPs {
advertisedRoutes = append(advertisedRoutes, r.String())
}
var enabledRoutes []string
for _, r := range m.AllowIPs {
enabledRoutes = append(enabledRoutes, r.String())
}
response := api.GetMachineRoutesResponse{
AdvertisedRoutes: advertisedRoutes,
EnabledRoutes: enabledRoutes,
AdvertisedRoutes: m.AdvertisedPrefixes(),
EnabledRoutes: m.AllowedPrefixes(),
AdvertisedExitNode: m.IsAdvertisedExitNode(),
EnabledExitNode: m.IsAllowedExitNode(),
}
return connect.NewResponse(&response), nil
@@ -222,23 +206,24 @@ func (s *Service) EnableMachineRoutes(ctx context.Context, req *connect.Request[
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
var enabledRoutes = domain.NewAllowIPsSet(m.AllowIPs)
var allowIPs = domain.NewAllowIPsSet(m.AllowIPs)
var autoAllowIPs = domain.NewAllowIPsSet(m.AutoAllowIPs)
if req.Msg.Replace {
enabledRoutes = domain.NewAllowIPsSet([]netip.Prefix{})
allowIPs = domain.NewAllowIPsSet([]netip.Prefix{})
autoAllowIPs = domain.NewAllowIPsSet([]netip.Prefix{})
}
var routesToBeRemoved []netip.Prefix
for _, r := range req.Msg.Routes {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return nil, err
}
enabledRoutes.Add(prefix)
routesToBeRemoved = append(routesToBeRemoved, prefix)
allowIPs.Add(prefix)
}
m.AllowIPs = enabledRoutes.Items()
m.AllowIPs = allowIPs.Items()
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
@@ -264,19 +249,98 @@ func (s *Service) DisableMachineRoutes(ctx context.Context, req *connect.Request
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
enabledRoutes := domain.NewAllowIPsSet(m.AllowIPs)
allowIPs := domain.NewAllowIPsSet(m.AllowIPs)
autoAllowIPs := domain.NewAllowIPsSet(m.AutoAllowIPs)
var routesToBeRemoved []netip.Prefix
for _, r := range req.Msg.Routes {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return nil, err
}
enabledRoutes.Remove(prefix)
routesToBeRemoved = append(routesToBeRemoved, prefix)
allowIPs.Remove(prefix)
autoAllowIPs.Remove(prefix)
}
m.AllowIPs = enabledRoutes.Items()
m.AllowIPs = allowIPs.Items()
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
s.pubsub.Publish(m.TailnetID, &broker.Signal{PeerUpdated: &m.ID})
return s.createMachineRoutesResponse(m)
}
func (s *Service) EnableExitNode(ctx context.Context, req *connect.Request[api.EnableExitNodeRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
principal := CurrentPrincipal(ctx)
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, err
}
if m == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
}
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(m.TailnetID) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
if !m.IsAdvertisedExitNode() {
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("machine is not a valid exit node"))
}
prefix4 := netip.MustParsePrefix("0.0.0.0/0")
prefix6 := netip.MustParsePrefix("::/0")
allowIPs := domain.NewAllowIPsSet(m.AllowIPs)
allowIPs.Add(prefix4, prefix6)
m.AllowIPs = allowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
s.pubsub.Publish(m.TailnetID, &broker.Signal{PeerUpdated: &m.ID})
return s.createMachineRoutesResponse(m)
}
func (s *Service) DisableExitNode(ctx context.Context, req *connect.Request[api.DisableExitNodeRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
principal := CurrentPrincipal(ctx)
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, err
}
if m == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
}
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(m.TailnetID) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
if !m.IsAdvertisedExitNode() {
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("machine is not a valid exit node"))
}
prefix4 := netip.MustParsePrefix("0.0.0.0/0")
prefix6 := netip.MustParsePrefix("::/0")
allowIPs := domain.NewAllowIPsSet(m.AllowIPs)
allowIPs.Remove(prefix4, prefix6)
autoAllowIPs := domain.NewAllowIPsSet(m.AutoAllowIPs)
autoAllowIPs.Remove(prefix4, prefix6)
m.AllowIPs = allowIPs.Items()
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
+258 -1
View File
@@ -2,12 +2,15 @@ package service
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/broker"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/util"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"tailscale.com/tailcfg"
)
func (s *Service) CreateTailnet(ctx context.Context, req *connect.Request[api.CreateTailnetRequest]) (*connect.Response[api.CreateTailnetResponse], error) {
@@ -16,7 +19,15 @@ func (s *Service) CreateTailnet(ctx context.Context, req *connect.Request[api.Cr
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, created, err := s.repository.GetOrCreateTailnet(ctx, req.Msg.Name)
name := req.Msg.Name
iamPolicy := domain.IAMPolicy{
Subs: req.Msg.IamPolicy.Subs,
Emails: req.Msg.IamPolicy.Emails,
Filters: req.Msg.IamPolicy.Filters,
Roles: apiRolesMapToDomainRolesMap(req.Msg.IamPolicy.Roles),
}
tailnet, created, err := s.repository.GetOrCreateTailnet(ctx, name, iamPolicy)
if err != nil {
return nil, err
}
@@ -129,3 +140,249 @@ func (s *Service) DeleteTailnet(ctx context.Context, req *connect.Request[api.De
return connect.NewResponse(&api.DeleteTailnetResponse{}), nil
}
func (s *Service) SetDERPMap(ctx context.Context, req *connect.Request[api.SetDERPMapRequest]) (*connect.Response[api.SetDERPMapResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
derpMap := tailcfg.DERPMap{}
if err := json.Unmarshal(req.Msg.Value, &derpMap); err != nil {
return nil, err
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
tailnet.DERPMap = domain.DERPMap{
Checksum: util.Checksum(&derpMap),
DERPMap: derpMap,
}
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{})
raw, err := json.Marshal(derpMap)
if err != nil {
return nil, err
}
return connect.NewResponse(&api.SetDERPMapResponse{Value: raw}), nil
}
func (s *Service) ResetDERPMap(ctx context.Context, req *connect.Request[api.ResetDERPMapRequest]) (*connect.Response[api.ResetDERPMapResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
tailnet.DERPMap = domain.DERPMap{}
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{})
return connect.NewResponse(&api.ResetDERPMapResponse{}), nil
}
func (s *Service) GetDERPMap(ctx context.Context, req *connect.Request[api.GetDERPMapRequest]) (*connect.Response[api.GetDERPMapResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
derpMap, err := tailnet.GetDERPMap(ctx, s.repository)
if err != nil {
return nil, err
}
raw, err := json.Marshal(derpMap.DERPMap)
if err != nil {
return nil, err
}
return connect.NewResponse(&api.GetDERPMapResponse{Value: raw}), nil
}
func (s *Service) EnabledFileSharing(ctx context.Context, req *connect.Request[api.EnableFileSharingRequest]) (*connect.Response[api.EnableFileSharingResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if !tailnet.FileSharingEnabled {
tailnet.FileSharingEnabled = true
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{})
}
return connect.NewResponse(&api.EnableFileSharingResponse{}), nil
}
func (s *Service) DisableFileSharing(ctx context.Context, req *connect.Request[api.DisableFileSharingRequest]) (*connect.Response[api.DisableFileSharingResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if tailnet.FileSharingEnabled {
tailnet.FileSharingEnabled = false
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{})
}
return connect.NewResponse(&api.DisableFileSharingResponse{}), nil
}
func (s *Service) EnabledServiceCollection(ctx context.Context, req *connect.Request[api.EnableServiceCollectionRequest]) (*connect.Response[api.EnableServiceCollectionResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if !tailnet.ServiceCollectionEnabled {
tailnet.ServiceCollectionEnabled = true
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{})
}
return connect.NewResponse(&api.EnableServiceCollectionResponse{}), nil
}
func (s *Service) DisableServiceCollection(ctx context.Context, req *connect.Request[api.DisableServiceCollectionRequest]) (*connect.Response[api.DisableServiceCollectionResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if tailnet.ServiceCollectionEnabled {
tailnet.ServiceCollectionEnabled = false
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{})
}
return connect.NewResponse(&api.DisableServiceCollectionResponse{}), nil
}
func (s *Service) EnabledSSH(ctx context.Context, req *connect.Request[api.EnableSSHRequest]) (*connect.Response[api.EnableSSHResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if !tailnet.SSHEnabled {
tailnet.SSHEnabled = true
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{})
}
return connect.NewResponse(&api.EnableSSHResponse{}), nil
}
func (s *Service) DisableSSH(ctx context.Context, req *connect.Request[api.DisableSSHRequest]) (*connect.Response[api.DisableSSHResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, err
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if tailnet.SSHEnabled {
tailnet.SSHEnabled = false
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, err
}
s.pubsub.Publish(tailnet.ID, &broker.Signal{})
}
return connect.NewResponse(&api.DisableSSHResponse{}), nil
}
+63
View File
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body {
width: 100%;
height: 100vh;
padding: 10px;
background: #379683;
}
.wrapper {
background: #fff;
max-width: 400px;
width: 100%;
margin: 120px auto;
padding: 25px;
border-radius: 5px;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
}
.selectionList li {
position: relative;
list-style: none;
height: 45px;
line-height: 45px;
margin-bottom: 8px;
background: #f2f2f2;
border-radius: 3px;
overflow: hidden;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1);
}
.selectionList li button {
margin: 0;
display: block;
width: 100%;
height: 100%;
border: none;
}
</style>
<title>ionscale</title>
</head>
<body>
<div class="wrapper">
<div style="text-align: center">
<p><b>Authentication successful</b></p>
<small>but you're <b style="color: red">not</b> a valid owner of the machine</small>
</div>
</div>
</body>
</html>
+37 -13
View File
@@ -1,36 +1,60 @@
package util
import (
"math/rand"
"time"
"crypto/md5"
"crypto/rand"
"crypto/rsa"
"encoding/hex"
"encoding/json"
"math/big"
)
var entropy *rand.Rand
func init() {
seed := time.Now().UnixNano()
source := rand.NewSource(seed)
entropy = rand.New(source)
}
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func RandStringBytes(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(letterBytes))))
if err != nil {
panic(err)
}
b[i] = letterBytes[idx.Int64()]
}
return string(b)
}
func RandUint64(n uint64) uint64 {
return entropy.Uint64() % n
val, err := rand.Int(rand.Reader, big.NewInt(int64(n)))
if err != nil {
panic(err)
}
return val.Uint64()
}
func RandomBytes(size int) ([]byte, error) {
buf := make([]byte, size)
if _, err := entropy.Read(buf); err != nil {
if _, err := rand.Read(buf); err != nil {
return nil, err
}
return buf, nil
}
func NewPrivateKey() (*rsa.PrivateKey, string, error) {
id := RandStringBytes(22)
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, "", err
}
return privateKey, id, nil
}
func Checksum(v interface{}) string {
marshal, err := json.Marshal(v)
if err != nil {
panic(err)
}
sum := md5.Sum(marshal)
return hex.EncodeToString(sum[:])
}
+253 -55
View File
@@ -213,10 +213,12 @@ type ACLPolicy struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Hosts map[string]string `protobuf:"bytes,1,rep,name=hosts,proto3" json:"hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Groups map[string]*structpb.ListValue `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Acls []*ACL `protobuf:"bytes,3,rep,name=acls,proto3" json:"acls,omitempty"`
TagOwners map[string]*structpb.ListValue `protobuf:"bytes,4,rep,name=tag_owners,json=tagOwners,proto3" json:"tag_owners,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Hosts map[string]string `protobuf:"bytes,1,rep,name=hosts,proto3" json:"hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Groups map[string]*structpb.ListValue `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Acls []*ACL `protobuf:"bytes,3,rep,name=acls,proto3" json:"acls,omitempty"`
Tagowners map[string]*structpb.ListValue `protobuf:"bytes,4,rep,name=tagowners,proto3" json:"tagowners,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Autoapprovers *AutoApprovers `protobuf:"bytes,5,opt,name=autoapprovers,proto3" json:"autoapprovers,omitempty"`
Ssh []*SSHRule `protobuf:"bytes,6,rep,name=ssh,proto3" json:"ssh,omitempty"`
}
func (x *ACLPolicy) Reset() {
@@ -272,9 +274,23 @@ func (x *ACLPolicy) GetAcls() []*ACL {
return nil
}
func (x *ACLPolicy) GetTagOwners() map[string]*structpb.ListValue {
func (x *ACLPolicy) GetTagowners() map[string]*structpb.ListValue {
if x != nil {
return x.TagOwners
return x.Tagowners
}
return nil
}
func (x *ACLPolicy) GetAutoapprovers() *AutoApprovers {
if x != nil {
return x.Autoapprovers
}
return nil
}
func (x *ACLPolicy) GetSsh() []*SSHRule {
if x != nil {
return x.Ssh
}
return nil
}
@@ -342,6 +358,132 @@ func (x *ACL) GetDst() []string {
return nil
}
type AutoApprovers struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Routes map[string]*structpb.ListValue `protobuf:"bytes,1,rep,name=routes,proto3" json:"routes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Exitnode []string `protobuf:"bytes,2,rep,name=exitnode,proto3" json:"exitnode,omitempty"`
}
func (x *AutoApprovers) Reset() {
*x = AutoApprovers{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_acl_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AutoApprovers) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AutoApprovers) ProtoMessage() {}
func (x *AutoApprovers) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_acl_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AutoApprovers.ProtoReflect.Descriptor instead.
func (*AutoApprovers) Descriptor() ([]byte, []int) {
return file_ionscale_v1_acl_proto_rawDescGZIP(), []int{6}
}
func (x *AutoApprovers) GetRoutes() map[string]*structpb.ListValue {
if x != nil {
return x.Routes
}
return nil
}
func (x *AutoApprovers) GetExitnode() []string {
if x != nil {
return x.Exitnode
}
return nil
}
type SSHRule struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Action string `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"`
Src []string `protobuf:"bytes,2,rep,name=src,proto3" json:"src,omitempty"`
Dst []string `protobuf:"bytes,3,rep,name=dst,proto3" json:"dst,omitempty"`
Users []string `protobuf:"bytes,4,rep,name=users,proto3" json:"users,omitempty"`
}
func (x *SSHRule) Reset() {
*x = SSHRule{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_acl_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SSHRule) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SSHRule) ProtoMessage() {}
func (x *SSHRule) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_acl_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SSHRule.ProtoReflect.Descriptor instead.
func (*SSHRule) Descriptor() ([]byte, []int) {
return file_ionscale_v1_acl_proto_rawDescGZIP(), []int{7}
}
func (x *SSHRule) GetAction() string {
if x != nil {
return x.Action
}
return ""
}
func (x *SSHRule) GetSrc() []string {
if x != nil {
return x.Src
}
return nil
}
func (x *SSHRule) GetDst() []string {
if x != nil {
return x.Dst
}
return nil
}
func (x *SSHRule) GetUsers() []string {
if x != nil {
return x.Users
}
return nil
}
var File_ionscale_v1_acl_proto protoreflect.FileDescriptor
var file_ionscale_v1_acl_proto_rawDesc = []byte{
@@ -366,7 +508,7 @@ var file_ionscale_v1_acl_proto_rawDesc = []byte{
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x43, 0x4c, 0x50,
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x16, 0x0a,
0x14, 0x53, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd7, 0x03, 0x0a, 0x09, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc0, 0x04, 0x0a, 0x09, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c,
0x69, 0x63, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73,
@@ -376,35 +518,60 @@ var file_ionscale_v1_acl_proto_rawDesc = []byte{
0x6c, 0x69, 0x63, 0x79, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x24, 0x0a, 0x04, 0x61, 0x63, 0x6c, 0x73,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x43, 0x4c, 0x52, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x12, 0x44,
0x0a, 0x0a, 0x74, 0x61, 0x67, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x54, 0x61, 0x67, 0x4f, 0x77,
0x6e, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x61, 0x67, 0x4f, 0x77,
0x6e, 0x65, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x55,
0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x58, 0x0a, 0x0e, 0x54, 0x61, 0x67, 0x4f, 0x77, 0x6e, 0x65,
0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
0x41, 0x0a, 0x03, 0x41, 0x43, 0x4c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10,
0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63,
0x12, 0x10, 0x0a, 0x03, 0x64, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x64,
0x73, 0x74, 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, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x43, 0x4c, 0x52, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x12, 0x43,
0x0a, 0x09, 0x74, 0x61, 0x67, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x54, 0x61, 0x67, 0x6f, 0x77, 0x6e,
0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x61, 0x67, 0x6f, 0x77, 0x6e,
0x65, 0x72, 0x73, 0x12, 0x40, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x61, 0x70, 0x70, 0x72, 0x6f,
0x76, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x41, 0x70, 0x70,
0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x61, 0x70, 0x70, 0x72,
0x6f, 0x76, 0x65, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x73, 0x73, 0x68, 0x18, 0x06, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x53, 0x48, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x03, 0x73, 0x73, 0x68, 0x1a, 0x38, 0x0a,
0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x55, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x58,
0x0a, 0x0e, 0x54, 0x61, 0x67, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41, 0x0a, 0x03, 0x41, 0x43, 0x4c, 0x12,
0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x02,
0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x73, 0x74,
0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x64, 0x73, 0x74, 0x22, 0xc2, 0x01, 0x0a, 0x0d,
0x41, 0x75, 0x74, 0x6f, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3e, 0x0a,
0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f,
0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x0a,
0x08, 0x65, 0x78, 0x69, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
0x08, 0x65, 0x78, 0x69, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x1a, 0x55, 0x0a, 0x0b, 0x52, 0x6f, 0x75,
0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
0x22, 0x5b, 0x0a, 0x07, 0x53, 0x53, 0x48, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03,
0x28, 0x09, 0x52, 0x03, 0x64, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73,
0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 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 (
@@ -419,7 +586,7 @@ func file_ionscale_v1_acl_proto_rawDescGZIP() []byte {
return file_ionscale_v1_acl_proto_rawDescData
}
var file_ionscale_v1_acl_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_ionscale_v1_acl_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_ionscale_v1_acl_proto_goTypes = []interface{}{
(*GetACLPolicyRequest)(nil), // 0: ionscale.v1.GetACLPolicyRequest
(*GetACLPolicyResponse)(nil), // 1: ionscale.v1.GetACLPolicyResponse
@@ -427,25 +594,32 @@ var file_ionscale_v1_acl_proto_goTypes = []interface{}{
(*SetACLPolicyResponse)(nil), // 3: ionscale.v1.SetACLPolicyResponse
(*ACLPolicy)(nil), // 4: ionscale.v1.ACLPolicy
(*ACL)(nil), // 5: ionscale.v1.ACL
nil, // 6: ionscale.v1.ACLPolicy.HostsEntry
nil, // 7: ionscale.v1.ACLPolicy.GroupsEntry
nil, // 8: ionscale.v1.ACLPolicy.TagOwnersEntry
(*structpb.ListValue)(nil), // 9: google.protobuf.ListValue
(*AutoApprovers)(nil), // 6: ionscale.v1.AutoApprovers
(*SSHRule)(nil), // 7: ionscale.v1.SSHRule
nil, // 8: ionscale.v1.ACLPolicy.HostsEntry
nil, // 9: ionscale.v1.ACLPolicy.GroupsEntry
nil, // 10: ionscale.v1.ACLPolicy.TagownersEntry
nil, // 11: ionscale.v1.AutoApprovers.RoutesEntry
(*structpb.ListValue)(nil), // 12: google.protobuf.ListValue
}
var file_ionscale_v1_acl_proto_depIdxs = []int32{
4, // 0: ionscale.v1.GetACLPolicyResponse.policy:type_name -> ionscale.v1.ACLPolicy
4, // 1: ionscale.v1.SetACLPolicyRequest.policy:type_name -> ionscale.v1.ACLPolicy
6, // 2: ionscale.v1.ACLPolicy.hosts:type_name -> ionscale.v1.ACLPolicy.HostsEntry
7, // 3: ionscale.v1.ACLPolicy.groups:type_name -> ionscale.v1.ACLPolicy.GroupsEntry
5, // 4: ionscale.v1.ACLPolicy.acls:type_name -> ionscale.v1.ACL
8, // 5: ionscale.v1.ACLPolicy.tag_owners:type_name -> ionscale.v1.ACLPolicy.TagOwnersEntry
9, // 6: ionscale.v1.ACLPolicy.GroupsEntry.value:type_name -> google.protobuf.ListValue
9, // 7: ionscale.v1.ACLPolicy.TagOwnersEntry.value:type_name -> google.protobuf.ListValue
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
4, // 0: ionscale.v1.GetACLPolicyResponse.policy:type_name -> ionscale.v1.ACLPolicy
4, // 1: ionscale.v1.SetACLPolicyRequest.policy:type_name -> ionscale.v1.ACLPolicy
8, // 2: ionscale.v1.ACLPolicy.hosts:type_name -> ionscale.v1.ACLPolicy.HostsEntry
9, // 3: ionscale.v1.ACLPolicy.groups:type_name -> ionscale.v1.ACLPolicy.GroupsEntry
5, // 4: ionscale.v1.ACLPolicy.acls:type_name -> ionscale.v1.ACL
10, // 5: ionscale.v1.ACLPolicy.tagowners:type_name -> ionscale.v1.ACLPolicy.TagownersEntry
6, // 6: ionscale.v1.ACLPolicy.autoapprovers:type_name -> ionscale.v1.AutoApprovers
7, // 7: ionscale.v1.ACLPolicy.ssh:type_name -> ionscale.v1.SSHRule
11, // 8: ionscale.v1.AutoApprovers.routes:type_name -> ionscale.v1.AutoApprovers.RoutesEntry
12, // 9: ionscale.v1.ACLPolicy.GroupsEntry.value:type_name -> google.protobuf.ListValue
12, // 10: ionscale.v1.ACLPolicy.TagownersEntry.value:type_name -> google.protobuf.ListValue
12, // 11: ionscale.v1.AutoApprovers.RoutesEntry.value:type_name -> google.protobuf.ListValue
12, // [12:12] is the sub-list for method output_type
12, // [12:12] is the sub-list for method input_type
12, // [12:12] is the sub-list for extension type_name
12, // [12:12] is the sub-list for extension extendee
0, // [0:12] is the sub-list for field type_name
}
func init() { file_ionscale_v1_acl_proto_init() }
@@ -527,6 +701,30 @@ func file_ionscale_v1_acl_proto_init() {
return nil
}
}
file_ionscale_v1_acl_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AutoApprovers); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_acl_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SSHRule); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -534,7 +732,7 @@ func file_ionscale_v1_acl_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ionscale_v1_acl_proto_rawDesc,
NumEnums: 0,
NumMessages: 9,
NumMessages: 12,
NumExtensions: 0,
NumServices: 0,
},
+166 -59
View File
@@ -20,14 +20,14 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type GetDERPMapRequest struct {
type GetDefaultDERPMapRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *GetDERPMapRequest) Reset() {
*x = GetDERPMapRequest{}
func (x *GetDefaultDERPMapRequest) Reset() {
*x = GetDefaultDERPMapRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_derp_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -35,13 +35,13 @@ func (x *GetDERPMapRequest) Reset() {
}
}
func (x *GetDERPMapRequest) String() string {
func (x *GetDefaultDERPMapRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetDERPMapRequest) ProtoMessage() {}
func (*GetDefaultDERPMapRequest) ProtoMessage() {}
func (x *GetDERPMapRequest) ProtoReflect() protoreflect.Message {
func (x *GetDefaultDERPMapRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_derp_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -53,12 +53,12 @@ func (x *GetDERPMapRequest) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use GetDERPMapRequest.ProtoReflect.Descriptor instead.
func (*GetDERPMapRequest) Descriptor() ([]byte, []int) {
// Deprecated: Use GetDefaultDERPMapRequest.ProtoReflect.Descriptor instead.
func (*GetDefaultDERPMapRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_derp_proto_rawDescGZIP(), []int{0}
}
type GetDERPMapResponse struct {
type GetDefaultDERPMapResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
@@ -66,8 +66,8 @@ type GetDERPMapResponse struct {
Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *GetDERPMapResponse) Reset() {
*x = GetDERPMapResponse{}
func (x *GetDefaultDERPMapResponse) Reset() {
*x = GetDefaultDERPMapResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_derp_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -75,13 +75,13 @@ func (x *GetDERPMapResponse) Reset() {
}
}
func (x *GetDERPMapResponse) String() string {
func (x *GetDefaultDERPMapResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetDERPMapResponse) ProtoMessage() {}
func (*GetDefaultDERPMapResponse) ProtoMessage() {}
func (x *GetDERPMapResponse) ProtoReflect() protoreflect.Message {
func (x *GetDefaultDERPMapResponse) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_derp_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -93,19 +93,19 @@ func (x *GetDERPMapResponse) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use GetDERPMapResponse.ProtoReflect.Descriptor instead.
func (*GetDERPMapResponse) Descriptor() ([]byte, []int) {
// Deprecated: Use GetDefaultDERPMapResponse.ProtoReflect.Descriptor instead.
func (*GetDefaultDERPMapResponse) Descriptor() ([]byte, []int) {
return file_ionscale_v1_derp_proto_rawDescGZIP(), []int{1}
}
func (x *GetDERPMapResponse) GetValue() []byte {
func (x *GetDefaultDERPMapResponse) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
type SetDERPMapRequest struct {
type SetDefaultDERPMapRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
@@ -113,8 +113,8 @@ type SetDERPMapRequest struct {
Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *SetDERPMapRequest) Reset() {
*x = SetDERPMapRequest{}
func (x *SetDefaultDERPMapRequest) Reset() {
*x = SetDefaultDERPMapRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_derp_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -122,13 +122,13 @@ func (x *SetDERPMapRequest) Reset() {
}
}
func (x *SetDERPMapRequest) String() string {
func (x *SetDefaultDERPMapRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetDERPMapRequest) ProtoMessage() {}
func (*SetDefaultDERPMapRequest) ProtoMessage() {}
func (x *SetDERPMapRequest) ProtoReflect() protoreflect.Message {
func (x *SetDefaultDERPMapRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_derp_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -140,19 +140,19 @@ func (x *SetDERPMapRequest) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use SetDERPMapRequest.ProtoReflect.Descriptor instead.
func (*SetDERPMapRequest) Descriptor() ([]byte, []int) {
// Deprecated: Use SetDefaultDERPMapRequest.ProtoReflect.Descriptor instead.
func (*SetDefaultDERPMapRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_derp_proto_rawDescGZIP(), []int{2}
}
func (x *SetDERPMapRequest) GetValue() []byte {
func (x *SetDefaultDERPMapRequest) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
type SetDERPMapResponse struct {
type SetDefaultDERPMapResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
@@ -160,8 +160,8 @@ type SetDERPMapResponse struct {
Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *SetDERPMapResponse) Reset() {
*x = SetDERPMapResponse{}
func (x *SetDefaultDERPMapResponse) Reset() {
*x = SetDefaultDERPMapResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_derp_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -169,13 +169,13 @@ func (x *SetDERPMapResponse) Reset() {
}
}
func (x *SetDERPMapResponse) String() string {
func (x *SetDefaultDERPMapResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetDERPMapResponse) ProtoMessage() {}
func (*SetDefaultDERPMapResponse) ProtoMessage() {}
func (x *SetDERPMapResponse) ProtoReflect() protoreflect.Message {
func (x *SetDefaultDERPMapResponse) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_derp_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -187,38 +187,119 @@ func (x *SetDERPMapResponse) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use SetDERPMapResponse.ProtoReflect.Descriptor instead.
func (*SetDERPMapResponse) Descriptor() ([]byte, []int) {
// Deprecated: Use SetDefaultDERPMapResponse.ProtoReflect.Descriptor instead.
func (*SetDefaultDERPMapResponse) Descriptor() ([]byte, []int) {
return file_ionscale_v1_derp_proto_rawDescGZIP(), []int{3}
}
func (x *SetDERPMapResponse) GetValue() []byte {
func (x *SetDefaultDERPMapResponse) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
type ResetDefaultDERPMapRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *ResetDefaultDERPMapRequest) Reset() {
*x = ResetDefaultDERPMapRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_derp_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ResetDefaultDERPMapRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ResetDefaultDERPMapRequest) ProtoMessage() {}
func (x *ResetDefaultDERPMapRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_derp_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ResetDefaultDERPMapRequest.ProtoReflect.Descriptor instead.
func (*ResetDefaultDERPMapRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_derp_proto_rawDescGZIP(), []int{4}
}
type ResetDefaultDERPMapResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *ResetDefaultDERPMapResponse) Reset() {
*x = ResetDefaultDERPMapResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_derp_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ResetDefaultDERPMapResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ResetDefaultDERPMapResponse) ProtoMessage() {}
func (x *ResetDefaultDERPMapResponse) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_derp_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ResetDefaultDERPMapResponse.ProtoReflect.Descriptor instead.
func (*ResetDefaultDERPMapResponse) Descriptor() ([]byte, []int) {
return file_ionscale_v1_derp_proto_rawDescGZIP(), []int{5}
}
var File_ionscale_v1_derp_proto protoreflect.FileDescriptor
var file_ionscale_v1_derp_proto_rawDesc = []byte{
0x0a, 0x16, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65,
0x72, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50,
0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2a, 0x0a, 0x12, 0x47, 0x65,
0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61,
0x75, 0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x22, 0x31, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44,
0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x22, 0x30, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75,
0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x29, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x44, 0x45, 0x52,
0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x22, 0x2a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 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,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x44, 0x65, 0x66,
0x61, 0x75, 0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x73,
0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, 0x74,
0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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 (
@@ -233,12 +314,14 @@ func file_ionscale_v1_derp_proto_rawDescGZIP() []byte {
return file_ionscale_v1_derp_proto_rawDescData
}
var file_ionscale_v1_derp_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_ionscale_v1_derp_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_ionscale_v1_derp_proto_goTypes = []interface{}{
(*GetDERPMapRequest)(nil), // 0: ionscale.v1.GetDERPMapRequest
(*GetDERPMapResponse)(nil), // 1: ionscale.v1.GetDERPMapResponse
(*SetDERPMapRequest)(nil), // 2: ionscale.v1.SetDERPMapRequest
(*SetDERPMapResponse)(nil), // 3: ionscale.v1.SetDERPMapResponse
(*GetDefaultDERPMapRequest)(nil), // 0: ionscale.v1.GetDefaultDERPMapRequest
(*GetDefaultDERPMapResponse)(nil), // 1: ionscale.v1.GetDefaultDERPMapResponse
(*SetDefaultDERPMapRequest)(nil), // 2: ionscale.v1.SetDefaultDERPMapRequest
(*SetDefaultDERPMapResponse)(nil), // 3: ionscale.v1.SetDefaultDERPMapResponse
(*ResetDefaultDERPMapRequest)(nil), // 4: ionscale.v1.ResetDefaultDERPMapRequest
(*ResetDefaultDERPMapResponse)(nil), // 5: ionscale.v1.ResetDefaultDERPMapResponse
}
var file_ionscale_v1_derp_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
@@ -255,7 +338,7 @@ func file_ionscale_v1_derp_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_ionscale_v1_derp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetDERPMapRequest); i {
switch v := v.(*GetDefaultDERPMapRequest); i {
case 0:
return &v.state
case 1:
@@ -267,7 +350,7 @@ func file_ionscale_v1_derp_proto_init() {
}
}
file_ionscale_v1_derp_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetDERPMapResponse); i {
switch v := v.(*GetDefaultDERPMapResponse); i {
case 0:
return &v.state
case 1:
@@ -279,7 +362,7 @@ func file_ionscale_v1_derp_proto_init() {
}
}
file_ionscale_v1_derp_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SetDERPMapRequest); i {
switch v := v.(*SetDefaultDERPMapRequest); i {
case 0:
return &v.state
case 1:
@@ -291,7 +374,31 @@ func file_ionscale_v1_derp_proto_init() {
}
}
file_ionscale_v1_derp_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SetDERPMapResponse); i {
switch v := v.(*SetDefaultDERPMapResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_derp_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResetDefaultDERPMapRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_derp_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResetDefaultDERPMapResponse); i {
case 0:
return &v.state
case 1:
@@ -309,7 +416,7 @@ func file_ionscale_v1_derp_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ionscale_v1_derp_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},
+271 -27
View File
@@ -218,6 +218,184 @@ func (x *SetDNSConfigResponse) GetConfig() *DNSConfig {
return nil
}
type EnableHttpsCertificatesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
Alias string `protobuf:"bytes,2,opt,name=alias,proto3" json:"alias,omitempty"`
}
func (x *EnableHttpsCertificatesRequest) Reset() {
*x = EnableHttpsCertificatesRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_dns_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EnableHttpsCertificatesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EnableHttpsCertificatesRequest) ProtoMessage() {}
func (x *EnableHttpsCertificatesRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_dns_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EnableHttpsCertificatesRequest.ProtoReflect.Descriptor instead.
func (*EnableHttpsCertificatesRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_dns_proto_rawDescGZIP(), []int{4}
}
func (x *EnableHttpsCertificatesRequest) GetTailnetId() uint64 {
if x != nil {
return x.TailnetId
}
return 0
}
func (x *EnableHttpsCertificatesRequest) GetAlias() string {
if x != nil {
return x.Alias
}
return ""
}
type EnableHttpsCertificatesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *EnableHttpsCertificatesResponse) Reset() {
*x = EnableHttpsCertificatesResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_dns_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EnableHttpsCertificatesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EnableHttpsCertificatesResponse) ProtoMessage() {}
func (x *EnableHttpsCertificatesResponse) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_dns_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EnableHttpsCertificatesResponse.ProtoReflect.Descriptor instead.
func (*EnableHttpsCertificatesResponse) Descriptor() ([]byte, []int) {
return file_ionscale_v1_dns_proto_rawDescGZIP(), []int{5}
}
type DisableHttpsCertificatesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
}
func (x *DisableHttpsCertificatesRequest) Reset() {
*x = DisableHttpsCertificatesRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_dns_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DisableHttpsCertificatesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DisableHttpsCertificatesRequest) ProtoMessage() {}
func (x *DisableHttpsCertificatesRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_dns_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DisableHttpsCertificatesRequest.ProtoReflect.Descriptor instead.
func (*DisableHttpsCertificatesRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_dns_proto_rawDescGZIP(), []int{6}
}
func (x *DisableHttpsCertificatesRequest) GetTailnetId() uint64 {
if x != nil {
return x.TailnetId
}
return 0
}
type DisableHttpsCertificatesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *DisableHttpsCertificatesResponse) Reset() {
*x = DisableHttpsCertificatesResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_dns_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DisableHttpsCertificatesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DisableHttpsCertificatesResponse) ProtoMessage() {}
func (x *DisableHttpsCertificatesResponse) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_dns_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DisableHttpsCertificatesResponse.ProtoReflect.Descriptor instead.
func (*DisableHttpsCertificatesResponse) Descriptor() ([]byte, []int) {
return file_ionscale_v1_dns_proto_rawDescGZIP(), []int{7}
}
type DNSConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -233,7 +411,7 @@ type DNSConfig struct {
func (x *DNSConfig) Reset() {
*x = DNSConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_dns_proto_msgTypes[4]
mi := &file_ionscale_v1_dns_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -246,7 +424,7 @@ func (x *DNSConfig) String() string {
func (*DNSConfig) ProtoMessage() {}
func (x *DNSConfig) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_dns_proto_msgTypes[4]
mi := &file_ionscale_v1_dns_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -259,7 +437,7 @@ func (x *DNSConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use DNSConfig.ProtoReflect.Descriptor instead.
func (*DNSConfig) Descriptor() ([]byte, []int) {
return file_ionscale_v1_dns_proto_rawDescGZIP(), []int{4}
return file_ionscale_v1_dns_proto_rawDescGZIP(), []int{8}
}
func (x *DNSConfig) GetMagicDns() bool {
@@ -308,7 +486,7 @@ type Routes struct {
func (x *Routes) Reset() {
*x = Routes{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_dns_proto_msgTypes[5]
mi := &file_ionscale_v1_dns_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -321,7 +499,7 @@ func (x *Routes) String() string {
func (*Routes) ProtoMessage() {}
func (x *Routes) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_dns_proto_msgTypes[5]
mi := &file_ionscale_v1_dns_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -334,7 +512,7 @@ func (x *Routes) ProtoReflect() protoreflect.Message {
// Deprecated: Use Routes.ProtoReflect.Descriptor instead.
func (*Routes) Descriptor() ([]byte, []int) {
return file_ionscale_v1_dns_proto_rawDescGZIP(), []int{5}
return file_ionscale_v1_dns_proto_rawDescGZIP(), []int{9}
}
func (x *Routes) GetRoutes() []string {
@@ -372,7 +550,21 @@ var file_ionscale_v1_dns_proto_rawDesc = []byte{
0x65, 0x12, 0x2e, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x16, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x67, 0x22, 0x55, 0x0a, 0x1e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x74, 0x74, 0x70, 0x73,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x21, 0x0a, 0x1f, 0x45, 0x6e, 0x61, 0x62,
0x6c, 0x65, 0x48, 0x74, 0x74, 0x70, 0x73, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0x0a, 0x1f, 0x44,
0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x74, 0x74, 0x70, 0x73, 0x43, 0x65, 0x72, 0x74, 0x69,
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
0x0a, 0x0a, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x09, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x22, 0x22, 0x0a,
0x20, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x74, 0x74, 0x70, 0x73, 0x43, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01,
0x28, 0x08, 0x52, 0x08, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x44, 0x6e, 0x73, 0x12, 0x2c, 0x0a, 0x12,
0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x64,
@@ -412,27 +604,31 @@ func file_ionscale_v1_dns_proto_rawDescGZIP() []byte {
return file_ionscale_v1_dns_proto_rawDescData
}
var file_ionscale_v1_dns_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_ionscale_v1_dns_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_ionscale_v1_dns_proto_goTypes = []interface{}{
(*GetDNSConfigRequest)(nil), // 0: ionscale.v1.GetDNSConfigRequest
(*GetDNSConfigResponse)(nil), // 1: ionscale.v1.GetDNSConfigResponse
(*SetDNSConfigRequest)(nil), // 2: ionscale.v1.SetDNSConfigRequest
(*SetDNSConfigResponse)(nil), // 3: ionscale.v1.SetDNSConfigResponse
(*DNSConfig)(nil), // 4: ionscale.v1.DNSConfig
(*Routes)(nil), // 5: ionscale.v1.Routes
nil, // 6: ionscale.v1.DNSConfig.RoutesEntry
(*GetDNSConfigRequest)(nil), // 0: ionscale.v1.GetDNSConfigRequest
(*GetDNSConfigResponse)(nil), // 1: ionscale.v1.GetDNSConfigResponse
(*SetDNSConfigRequest)(nil), // 2: ionscale.v1.SetDNSConfigRequest
(*SetDNSConfigResponse)(nil), // 3: ionscale.v1.SetDNSConfigResponse
(*EnableHttpsCertificatesRequest)(nil), // 4: ionscale.v1.EnableHttpsCertificatesRequest
(*EnableHttpsCertificatesResponse)(nil), // 5: ionscale.v1.EnableHttpsCertificatesResponse
(*DisableHttpsCertificatesRequest)(nil), // 6: ionscale.v1.DisableHttpsCertificatesRequest
(*DisableHttpsCertificatesResponse)(nil), // 7: ionscale.v1.DisableHttpsCertificatesResponse
(*DNSConfig)(nil), // 8: ionscale.v1.DNSConfig
(*Routes)(nil), // 9: ionscale.v1.Routes
nil, // 10: ionscale.v1.DNSConfig.RoutesEntry
}
var file_ionscale_v1_dns_proto_depIdxs = []int32{
4, // 0: ionscale.v1.GetDNSConfigResponse.config:type_name -> ionscale.v1.DNSConfig
4, // 1: ionscale.v1.SetDNSConfigRequest.config:type_name -> ionscale.v1.DNSConfig
4, // 2: ionscale.v1.SetDNSConfigResponse.config:type_name -> ionscale.v1.DNSConfig
6, // 3: ionscale.v1.DNSConfig.routes:type_name -> ionscale.v1.DNSConfig.RoutesEntry
5, // 4: ionscale.v1.DNSConfig.RoutesEntry.value:type_name -> ionscale.v1.Routes
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
8, // 0: ionscale.v1.GetDNSConfigResponse.config:type_name -> ionscale.v1.DNSConfig
8, // 1: ionscale.v1.SetDNSConfigRequest.config:type_name -> ionscale.v1.DNSConfig
8, // 2: ionscale.v1.SetDNSConfigResponse.config:type_name -> ionscale.v1.DNSConfig
10, // 3: ionscale.v1.DNSConfig.routes:type_name -> ionscale.v1.DNSConfig.RoutesEntry
9, // 4: ionscale.v1.DNSConfig.RoutesEntry.value:type_name -> ionscale.v1.Routes
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_ionscale_v1_dns_proto_init() }
@@ -490,7 +686,7 @@ func file_ionscale_v1_dns_proto_init() {
}
}
file_ionscale_v1_dns_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DNSConfig); i {
switch v := v.(*EnableHttpsCertificatesRequest); i {
case 0:
return &v.state
case 1:
@@ -502,6 +698,54 @@ func file_ionscale_v1_dns_proto_init() {
}
}
file_ionscale_v1_dns_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EnableHttpsCertificatesResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_dns_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DisableHttpsCertificatesRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_dns_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DisableHttpsCertificatesResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_dns_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DNSConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_dns_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Routes); i {
case 0:
return &v.state
@@ -520,7 +764,7 @@ func file_ionscale_v1_dns_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ionscale_v1_dns_proto_rawDesc,
NumEnums: 0,
NumMessages: 7,
NumMessages: 11,
NumExtensions: 0,
NumServices: 0,
},
+401 -256
View File
@@ -48,7 +48,7 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31,
0x2f, 0x61, 0x63, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x72, 0x70, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x32, 0xbf, 0x13, 0x0a, 0x0f, 0x49, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53,
0x74, 0x6f, 0x32, 0xe5, 0x1e, 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,
@@ -60,272 +60,417 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e,
0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x30, 0x01, 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, 0x58, 0x0a, 0x0d, 0x43, 0x72, 0x65, 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, 0x43, 0x72, 0x65, 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, 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, 0x53, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x73, 0x12, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 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, 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, 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,
0x22, 0x00, 0x30, 0x01, 0x12, 0x64, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75,
0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x12, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75,
0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x26, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x11, 0x53, 0x65,
0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x12,
0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65,
0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44,
0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x6a, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x12, 0x27, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75,
0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52,
0x65, 0x73, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x45, 0x52, 0x50, 0x4d,
0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d,
0x43, 0x72, 0x65, 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, 0x43, 0x72, 0x65, 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, 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, 0x53, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x54,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 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, 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,
0x65, 0x0a, 0x12, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 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,
0x77, 0x0a, 0x18, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 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, 0x4d, 0x0a, 0x0a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 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, 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, 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,
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,
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, 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,
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, 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, 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, 0x67, 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, 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, 0x69, 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,
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, 0x67, 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, 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, 0x69, 0x0a, 0x14,
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, 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, 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,
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, 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, 0x5d, 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, 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, 0x5f, 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, 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, 0x76, 0x0a, 0x17, 0x45, 0x6e, 0x61, 0x62, 0x6c,
0x65, 0x48, 0x74, 0x74, 0x70, 0x73, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
0x65, 0x73, 0x12, 0x2b, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x74, 0x74, 0x70, 0x73, 0x43, 0x65, 0x72, 0x74,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 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, 0x48, 0x74, 0x74, 0x70, 0x73, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
0x63, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x79, 0x0a, 0x18, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x74, 0x74, 0x70, 0x73, 0x43,
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
0x65, 0x48, 0x74, 0x74, 0x70, 0x73, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
0x65, 0x73, 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, 0x48,
0x74, 0x74, 0x70, 0x73, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73,
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{}{
(*GetVersionRequest)(nil), // 0: ionscale.v1.GetVersionRequest
(*AuthenticationRequest)(nil), // 1: ionscale.v1.AuthenticationRequest
(*GetDERPMapRequest)(nil), // 2: ionscale.v1.GetDERPMapRequest
(*SetDERPMapRequest)(nil), // 3: ionscale.v1.SetDERPMapRequest
(*CreateTailnetRequest)(nil), // 4: ionscale.v1.CreateTailnetRequest
(*GetTailnetRequest)(nil), // 5: ionscale.v1.GetTailnetRequest
(*ListTailnetRequest)(nil), // 6: ionscale.v1.ListTailnetRequest
(*DeleteTailnetRequest)(nil), // 7: ionscale.v1.DeleteTailnetRequest
(*GetDNSConfigRequest)(nil), // 8: ionscale.v1.GetDNSConfigRequest
(*SetDNSConfigRequest)(nil), // 9: ionscale.v1.SetDNSConfigRequest
(*GetIAMPolicyRequest)(nil), // 10: ionscale.v1.GetIAMPolicyRequest
(*SetIAMPolicyRequest)(nil), // 11: ionscale.v1.SetIAMPolicyRequest
(*GetACLPolicyRequest)(nil), // 12: ionscale.v1.GetACLPolicyRequest
(*SetACLPolicyRequest)(nil), // 13: ionscale.v1.SetACLPolicyRequest
(*GetAuthKeyRequest)(nil), // 14: ionscale.v1.GetAuthKeyRequest
(*CreateAuthKeyRequest)(nil), // 15: ionscale.v1.CreateAuthKeyRequest
(*DeleteAuthKeyRequest)(nil), // 16: ionscale.v1.DeleteAuthKeyRequest
(*ListAuthKeysRequest)(nil), // 17: ionscale.v1.ListAuthKeysRequest
(*ListUsersRequest)(nil), // 18: ionscale.v1.ListUsersRequest
(*DeleteUserRequest)(nil), // 19: ionscale.v1.DeleteUserRequest
(*GetMachineRequest)(nil), // 20: ionscale.v1.GetMachineRequest
(*ListMachinesRequest)(nil), // 21: ionscale.v1.ListMachinesRequest
(*ExpireMachineRequest)(nil), // 22: ionscale.v1.ExpireMachineRequest
(*DeleteMachineRequest)(nil), // 23: ionscale.v1.DeleteMachineRequest
(*SetMachineKeyExpiryRequest)(nil), // 24: ionscale.v1.SetMachineKeyExpiryRequest
(*GetMachineRoutesRequest)(nil), // 25: ionscale.v1.GetMachineRoutesRequest
(*EnableMachineRoutesRequest)(nil), // 26: ionscale.v1.EnableMachineRoutesRequest
(*DisableMachineRoutesRequest)(nil), // 27: ionscale.v1.DisableMachineRoutesRequest
(*GetVersionResponse)(nil), // 28: ionscale.v1.GetVersionResponse
(*AuthenticationResponse)(nil), // 29: ionscale.v1.AuthenticationResponse
(*GetDERPMapResponse)(nil), // 30: ionscale.v1.GetDERPMapResponse
(*SetDERPMapResponse)(nil), // 31: ionscale.v1.SetDERPMapResponse
(*CreateTailnetResponse)(nil), // 32: ionscale.v1.CreateTailnetResponse
(*GetTailnetResponse)(nil), // 33: ionscale.v1.GetTailnetResponse
(*ListTailnetResponse)(nil), // 34: ionscale.v1.ListTailnetResponse
(*DeleteTailnetResponse)(nil), // 35: ionscale.v1.DeleteTailnetResponse
(*GetDNSConfigResponse)(nil), // 36: ionscale.v1.GetDNSConfigResponse
(*SetDNSConfigResponse)(nil), // 37: ionscale.v1.SetDNSConfigResponse
(*GetIAMPolicyResponse)(nil), // 38: ionscale.v1.GetIAMPolicyResponse
(*SetIAMPolicyResponse)(nil), // 39: ionscale.v1.SetIAMPolicyResponse
(*GetACLPolicyResponse)(nil), // 40: ionscale.v1.GetACLPolicyResponse
(*SetACLPolicyResponse)(nil), // 41: ionscale.v1.SetACLPolicyResponse
(*GetAuthKeyResponse)(nil), // 42: ionscale.v1.GetAuthKeyResponse
(*CreateAuthKeyResponse)(nil), // 43: ionscale.v1.CreateAuthKeyResponse
(*DeleteAuthKeyResponse)(nil), // 44: ionscale.v1.DeleteAuthKeyResponse
(*ListAuthKeysResponse)(nil), // 45: ionscale.v1.ListAuthKeysResponse
(*ListUsersResponse)(nil), // 46: ionscale.v1.ListUsersResponse
(*DeleteUserResponse)(nil), // 47: ionscale.v1.DeleteUserResponse
(*GetMachineResponse)(nil), // 48: ionscale.v1.GetMachineResponse
(*ListMachinesResponse)(nil), // 49: ionscale.v1.ListMachinesResponse
(*ExpireMachineResponse)(nil), // 50: ionscale.v1.ExpireMachineResponse
(*DeleteMachineResponse)(nil), // 51: ionscale.v1.DeleteMachineResponse
(*SetMachineKeyExpiryResponse)(nil), // 52: ionscale.v1.SetMachineKeyExpiryResponse
(*GetMachineRoutesResponse)(nil), // 53: ionscale.v1.GetMachineRoutesResponse
(*GetVersionRequest)(nil), // 0: ionscale.v1.GetVersionRequest
(*AuthenticationRequest)(nil), // 1: ionscale.v1.AuthenticationRequest
(*GetDefaultDERPMapRequest)(nil), // 2: ionscale.v1.GetDefaultDERPMapRequest
(*SetDefaultDERPMapRequest)(nil), // 3: ionscale.v1.SetDefaultDERPMapRequest
(*ResetDefaultDERPMapRequest)(nil), // 4: ionscale.v1.ResetDefaultDERPMapRequest
(*CreateTailnetRequest)(nil), // 5: ionscale.v1.CreateTailnetRequest
(*GetTailnetRequest)(nil), // 6: ionscale.v1.GetTailnetRequest
(*ListTailnetRequest)(nil), // 7: ionscale.v1.ListTailnetRequest
(*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
(*GetDNSConfigRequest)(nil), // 18: ionscale.v1.GetDNSConfigRequest
(*SetDNSConfigRequest)(nil), // 19: ionscale.v1.SetDNSConfigRequest
(*GetIAMPolicyRequest)(nil), // 20: ionscale.v1.GetIAMPolicyRequest
(*SetIAMPolicyRequest)(nil), // 21: ionscale.v1.SetIAMPolicyRequest
(*GetACLPolicyRequest)(nil), // 22: ionscale.v1.GetACLPolicyRequest
(*SetACLPolicyRequest)(nil), // 23: ionscale.v1.SetACLPolicyRequest
(*GetAuthKeyRequest)(nil), // 24: ionscale.v1.GetAuthKeyRequest
(*CreateAuthKeyRequest)(nil), // 25: ionscale.v1.CreateAuthKeyRequest
(*DeleteAuthKeyRequest)(nil), // 26: ionscale.v1.DeleteAuthKeyRequest
(*ListAuthKeysRequest)(nil), // 27: ionscale.v1.ListAuthKeysRequest
(*ListUsersRequest)(nil), // 28: ionscale.v1.ListUsersRequest
(*DeleteUserRequest)(nil), // 29: ionscale.v1.DeleteUserRequest
(*GetMachineRequest)(nil), // 30: ionscale.v1.GetMachineRequest
(*ListMachinesRequest)(nil), // 31: ionscale.v1.ListMachinesRequest
(*ExpireMachineRequest)(nil), // 32: ionscale.v1.ExpireMachineRequest
(*DeleteMachineRequest)(nil), // 33: ionscale.v1.DeleteMachineRequest
(*SetMachineKeyExpiryRequest)(nil), // 34: ionscale.v1.SetMachineKeyExpiryRequest
(*GetMachineRoutesRequest)(nil), // 35: ionscale.v1.GetMachineRoutesRequest
(*EnableMachineRoutesRequest)(nil), // 36: ionscale.v1.EnableMachineRoutesRequest
(*DisableMachineRoutesRequest)(nil), // 37: ionscale.v1.DisableMachineRoutesRequest
(*EnableExitNodeRequest)(nil), // 38: ionscale.v1.EnableExitNodeRequest
(*DisableExitNodeRequest)(nil), // 39: ionscale.v1.DisableExitNodeRequest
(*EnableHttpsCertificatesRequest)(nil), // 40: ionscale.v1.EnableHttpsCertificatesRequest
(*DisableHttpsCertificatesRequest)(nil), // 41: ionscale.v1.DisableHttpsCertificatesRequest
(*GetVersionResponse)(nil), // 42: ionscale.v1.GetVersionResponse
(*AuthenticationResponse)(nil), // 43: ionscale.v1.AuthenticationResponse
(*GetDefaultDERPMapResponse)(nil), // 44: ionscale.v1.GetDefaultDERPMapResponse
(*SetDefaultDERPMapResponse)(nil), // 45: ionscale.v1.SetDefaultDERPMapResponse
(*ResetDefaultDERPMapResponse)(nil), // 46: ionscale.v1.ResetDefaultDERPMapResponse
(*CreateTailnetResponse)(nil), // 47: ionscale.v1.CreateTailnetResponse
(*GetTailnetResponse)(nil), // 48: ionscale.v1.GetTailnetResponse
(*ListTailnetResponse)(nil), // 49: ionscale.v1.ListTailnetResponse
(*DeleteTailnetResponse)(nil), // 50: ionscale.v1.DeleteTailnetResponse
(*GetDERPMapResponse)(nil), // 51: ionscale.v1.GetDERPMapResponse
(*SetDERPMapResponse)(nil), // 52: ionscale.v1.SetDERPMapResponse
(*ResetDERPMapResponse)(nil), // 53: ionscale.v1.ResetDERPMapResponse
(*EnableFileSharingResponse)(nil), // 54: ionscale.v1.EnableFileSharingResponse
(*DisableFileSharingResponse)(nil), // 55: ionscale.v1.DisableFileSharingResponse
(*EnableServiceCollectionResponse)(nil), // 56: ionscale.v1.EnableServiceCollectionResponse
(*DisableServiceCollectionResponse)(nil), // 57: ionscale.v1.DisableServiceCollectionResponse
(*EnableSSHResponse)(nil), // 58: ionscale.v1.EnableSSHResponse
(*DisableSSHResponse)(nil), // 59: ionscale.v1.DisableSSHResponse
(*GetDNSConfigResponse)(nil), // 60: ionscale.v1.GetDNSConfigResponse
(*SetDNSConfigResponse)(nil), // 61: ionscale.v1.SetDNSConfigResponse
(*GetIAMPolicyResponse)(nil), // 62: ionscale.v1.GetIAMPolicyResponse
(*SetIAMPolicyResponse)(nil), // 63: ionscale.v1.SetIAMPolicyResponse
(*GetACLPolicyResponse)(nil), // 64: ionscale.v1.GetACLPolicyResponse
(*SetACLPolicyResponse)(nil), // 65: ionscale.v1.SetACLPolicyResponse
(*GetAuthKeyResponse)(nil), // 66: ionscale.v1.GetAuthKeyResponse
(*CreateAuthKeyResponse)(nil), // 67: ionscale.v1.CreateAuthKeyResponse
(*DeleteAuthKeyResponse)(nil), // 68: ionscale.v1.DeleteAuthKeyResponse
(*ListAuthKeysResponse)(nil), // 69: ionscale.v1.ListAuthKeysResponse
(*ListUsersResponse)(nil), // 70: ionscale.v1.ListUsersResponse
(*DeleteUserResponse)(nil), // 71: ionscale.v1.DeleteUserResponse
(*GetMachineResponse)(nil), // 72: ionscale.v1.GetMachineResponse
(*ListMachinesResponse)(nil), // 73: ionscale.v1.ListMachinesResponse
(*ExpireMachineResponse)(nil), // 74: ionscale.v1.ExpireMachineResponse
(*DeleteMachineResponse)(nil), // 75: ionscale.v1.DeleteMachineResponse
(*SetMachineKeyExpiryResponse)(nil), // 76: ionscale.v1.SetMachineKeyExpiryResponse
(*GetMachineRoutesResponse)(nil), // 77: ionscale.v1.GetMachineRoutesResponse
(*EnableHttpsCertificatesResponse)(nil), // 78: ionscale.v1.EnableHttpsCertificatesResponse
(*DisableHttpsCertificatesResponse)(nil), // 79: ionscale.v1.DisableHttpsCertificatesResponse
}
var file_ionscale_v1_ionscale_proto_depIdxs = []int32{
0, // 0: ionscale.v1.IonscaleService.GetVersion:input_type -> ionscale.v1.GetVersionRequest
1, // 1: ionscale.v1.IonscaleService.Authenticate:input_type -> ionscale.v1.AuthenticationRequest
2, // 2: ionscale.v1.IonscaleService.GetDERPMap:input_type -> ionscale.v1.GetDERPMapRequest
3, // 3: ionscale.v1.IonscaleService.SetDERPMap:input_type -> ionscale.v1.SetDERPMapRequest
4, // 4: ionscale.v1.IonscaleService.CreateTailnet:input_type -> ionscale.v1.CreateTailnetRequest
5, // 5: ionscale.v1.IonscaleService.GetTailnet:input_type -> ionscale.v1.GetTailnetRequest
6, // 6: ionscale.v1.IonscaleService.ListTailnets:input_type -> ionscale.v1.ListTailnetRequest
7, // 7: ionscale.v1.IonscaleService.DeleteTailnet:input_type -> ionscale.v1.DeleteTailnetRequest
8, // 8: ionscale.v1.IonscaleService.GetDNSConfig:input_type -> ionscale.v1.GetDNSConfigRequest
9, // 9: ionscale.v1.IonscaleService.SetDNSConfig:input_type -> ionscale.v1.SetDNSConfigRequest
10, // 10: ionscale.v1.IonscaleService.GetIAMPolicy:input_type -> ionscale.v1.GetIAMPolicyRequest
11, // 11: ionscale.v1.IonscaleService.SetIAMPolicy:input_type -> ionscale.v1.SetIAMPolicyRequest
12, // 12: ionscale.v1.IonscaleService.GetACLPolicy:input_type -> ionscale.v1.GetACLPolicyRequest
13, // 13: ionscale.v1.IonscaleService.SetACLPolicy:input_type -> ionscale.v1.SetACLPolicyRequest
14, // 14: ionscale.v1.IonscaleService.GetAuthKey:input_type -> ionscale.v1.GetAuthKeyRequest
15, // 15: ionscale.v1.IonscaleService.CreateAuthKey:input_type -> ionscale.v1.CreateAuthKeyRequest
16, // 16: ionscale.v1.IonscaleService.DeleteAuthKey:input_type -> ionscale.v1.DeleteAuthKeyRequest
17, // 17: ionscale.v1.IonscaleService.ListAuthKeys:input_type -> ionscale.v1.ListAuthKeysRequest
18, // 18: ionscale.v1.IonscaleService.ListUsers:input_type -> ionscale.v1.ListUsersRequest
19, // 19: ionscale.v1.IonscaleService.DeleteUser:input_type -> ionscale.v1.DeleteUserRequest
20, // 20: ionscale.v1.IonscaleService.GetMachine:input_type -> ionscale.v1.GetMachineRequest
21, // 21: ionscale.v1.IonscaleService.ListMachines:input_type -> ionscale.v1.ListMachinesRequest
22, // 22: ionscale.v1.IonscaleService.ExpireMachine:input_type -> ionscale.v1.ExpireMachineRequest
23, // 23: ionscale.v1.IonscaleService.DeleteMachine:input_type -> ionscale.v1.DeleteMachineRequest
24, // 24: ionscale.v1.IonscaleService.SetMachineKeyExpiry:input_type -> ionscale.v1.SetMachineKeyExpiryRequest
25, // 25: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest
26, // 26: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest
27, // 27: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest
28, // 28: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse
29, // 29: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticationResponse
30, // 30: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse
31, // 31: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse
32, // 32: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse
33, // 33: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse
34, // 34: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetResponse
35, // 35: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse
36, // 36: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse
37, // 37: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse
38, // 38: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse
39, // 39: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse
40, // 40: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse
41, // 41: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse
42, // 42: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse
43, // 43: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse
44, // 44: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse
45, // 45: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse
46, // 46: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse
47, // 47: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse
48, // 48: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse
49, // 49: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse
50, // 50: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse
51, // 51: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse
52, // 52: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse
53, // 53: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
53, // 54: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
53, // 55: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
28, // [28:56] is the sub-list for method output_type
0, // [0:28] is the sub-list for method input_type
2, // 2: ionscale.v1.IonscaleService.GetDefaultDERPMap:input_type -> ionscale.v1.GetDefaultDERPMapRequest
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.ListTailnetRequest
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.EnabledFileSharing:input_type -> ionscale.v1.EnableFileSharingRequest
13, // 13: ionscale.v1.IonscaleService.DisableFileSharing:input_type -> ionscale.v1.DisableFileSharingRequest
14, // 14: ionscale.v1.IonscaleService.EnabledServiceCollection:input_type -> ionscale.v1.EnableServiceCollectionRequest
15, // 15: ionscale.v1.IonscaleService.DisableServiceCollection:input_type -> ionscale.v1.DisableServiceCollectionRequest
16, // 16: ionscale.v1.IonscaleService.EnabledSSH:input_type -> ionscale.v1.EnableSSHRequest
17, // 17: ionscale.v1.IonscaleService.DisableSSH:input_type -> ionscale.v1.DisableSSHRequest
18, // 18: ionscale.v1.IonscaleService.GetDNSConfig:input_type -> ionscale.v1.GetDNSConfigRequest
19, // 19: ionscale.v1.IonscaleService.SetDNSConfig:input_type -> ionscale.v1.SetDNSConfigRequest
20, // 20: ionscale.v1.IonscaleService.GetIAMPolicy:input_type -> ionscale.v1.GetIAMPolicyRequest
21, // 21: ionscale.v1.IonscaleService.SetIAMPolicy:input_type -> ionscale.v1.SetIAMPolicyRequest
22, // 22: ionscale.v1.IonscaleService.GetACLPolicy:input_type -> ionscale.v1.GetACLPolicyRequest
23, // 23: ionscale.v1.IonscaleService.SetACLPolicy:input_type -> ionscale.v1.SetACLPolicyRequest
24, // 24: ionscale.v1.IonscaleService.GetAuthKey:input_type -> ionscale.v1.GetAuthKeyRequest
25, // 25: ionscale.v1.IonscaleService.CreateAuthKey:input_type -> ionscale.v1.CreateAuthKeyRequest
26, // 26: ionscale.v1.IonscaleService.DeleteAuthKey:input_type -> ionscale.v1.DeleteAuthKeyRequest
27, // 27: ionscale.v1.IonscaleService.ListAuthKeys:input_type -> ionscale.v1.ListAuthKeysRequest
28, // 28: ionscale.v1.IonscaleService.ListUsers:input_type -> ionscale.v1.ListUsersRequest
29, // 29: ionscale.v1.IonscaleService.DeleteUser:input_type -> ionscale.v1.DeleteUserRequest
30, // 30: ionscale.v1.IonscaleService.GetMachine:input_type -> ionscale.v1.GetMachineRequest
31, // 31: ionscale.v1.IonscaleService.ListMachines:input_type -> ionscale.v1.ListMachinesRequest
32, // 32: ionscale.v1.IonscaleService.ExpireMachine:input_type -> ionscale.v1.ExpireMachineRequest
33, // 33: ionscale.v1.IonscaleService.DeleteMachine:input_type -> ionscale.v1.DeleteMachineRequest
34, // 34: ionscale.v1.IonscaleService.SetMachineKeyExpiry:input_type -> ionscale.v1.SetMachineKeyExpiryRequest
35, // 35: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest
36, // 36: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest
37, // 37: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest
38, // 38: ionscale.v1.IonscaleService.EnableExitNode:input_type -> ionscale.v1.EnableExitNodeRequest
39, // 39: ionscale.v1.IonscaleService.DisableExitNode:input_type -> ionscale.v1.DisableExitNodeRequest
40, // 40: ionscale.v1.IonscaleService.EnableHttpsCertificates:input_type -> ionscale.v1.EnableHttpsCertificatesRequest
41, // 41: ionscale.v1.IonscaleService.DisableHttpsCertificates:input_type -> ionscale.v1.DisableHttpsCertificatesRequest
42, // 42: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse
43, // 43: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticationResponse
44, // 44: ionscale.v1.IonscaleService.GetDefaultDERPMap:output_type -> ionscale.v1.GetDefaultDERPMapResponse
45, // 45: ionscale.v1.IonscaleService.SetDefaultDERPMap:output_type -> ionscale.v1.SetDefaultDERPMapResponse
46, // 46: ionscale.v1.IonscaleService.ResetDefaultDERPMap:output_type -> ionscale.v1.ResetDefaultDERPMapResponse
47, // 47: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse
48, // 48: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse
49, // 49: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetResponse
50, // 50: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse
51, // 51: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse
52, // 52: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse
53, // 53: ionscale.v1.IonscaleService.ResetDERPMap:output_type -> ionscale.v1.ResetDERPMapResponse
54, // 54: ionscale.v1.IonscaleService.EnabledFileSharing:output_type -> ionscale.v1.EnableFileSharingResponse
55, // 55: ionscale.v1.IonscaleService.DisableFileSharing:output_type -> ionscale.v1.DisableFileSharingResponse
56, // 56: ionscale.v1.IonscaleService.EnabledServiceCollection:output_type -> ionscale.v1.EnableServiceCollectionResponse
57, // 57: ionscale.v1.IonscaleService.DisableServiceCollection:output_type -> ionscale.v1.DisableServiceCollectionResponse
58, // 58: ionscale.v1.IonscaleService.EnabledSSH:output_type -> ionscale.v1.EnableSSHResponse
59, // 59: ionscale.v1.IonscaleService.DisableSSH:output_type -> ionscale.v1.DisableSSHResponse
60, // 60: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse
61, // 61: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse
62, // 62: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse
63, // 63: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse
64, // 64: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse
65, // 65: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse
66, // 66: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse
67, // 67: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse
68, // 68: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse
69, // 69: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse
70, // 70: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse
71, // 71: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse
72, // 72: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse
73, // 73: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse
74, // 74: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse
75, // 75: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse
76, // 76: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse
77, // 77: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
77, // 78: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
77, // 79: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
77, // 80: ionscale.v1.IonscaleService.EnableExitNode:output_type -> ionscale.v1.GetMachineRoutesResponse
77, // 81: ionscale.v1.IonscaleService.DisableExitNode:output_type -> ionscale.v1.GetMachineRoutesResponse
78, // 82: ionscale.v1.IonscaleService.EnableHttpsCertificates:output_type -> ionscale.v1.EnableHttpsCertificatesResponse
79, // 83: ionscale.v1.IonscaleService.DisableHttpsCertificates:output_type -> ionscale.v1.DisableHttpsCertificatesResponse
42, // [42:84] is the sub-list for method output_type
0, // [0:42] 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
@@ -29,12 +29,22 @@ const (
type IonscaleServiceClient interface {
GetVersion(context.Context, *connect_go.Request[v1.GetVersionRequest]) (*connect_go.Response[v1.GetVersionResponse], error)
Authenticate(context.Context, *connect_go.Request[v1.AuthenticationRequest]) (*connect_go.ServerStreamForClient[v1.AuthenticationResponse], error)
GetDERPMap(context.Context, *connect_go.Request[v1.GetDERPMapRequest]) (*connect_go.Response[v1.GetDERPMapResponse], error)
SetDERPMap(context.Context, *connect_go.Request[v1.SetDERPMapRequest]) (*connect_go.Response[v1.SetDERPMapResponse], error)
GetDefaultDERPMap(context.Context, *connect_go.Request[v1.GetDefaultDERPMapRequest]) (*connect_go.Response[v1.GetDefaultDERPMapResponse], error)
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)
GetTailnet(context.Context, *connect_go.Request[v1.GetTailnetRequest]) (*connect_go.Response[v1.GetTailnetResponse], error)
ListTailnets(context.Context, *connect_go.Request[v1.ListTailnetRequest]) (*connect_go.Response[v1.ListTailnetResponse], error)
DeleteTailnet(context.Context, *connect_go.Request[v1.DeleteTailnetRequest]) (*connect_go.Response[v1.DeleteTailnetResponse], error)
GetDERPMap(context.Context, *connect_go.Request[v1.GetDERPMapRequest]) (*connect_go.Response[v1.GetDERPMapResponse], error)
SetDERPMap(context.Context, *connect_go.Request[v1.SetDERPMapRequest]) (*connect_go.Response[v1.SetDERPMapResponse], error)
ResetDERPMap(context.Context, *connect_go.Request[v1.ResetDERPMapRequest]) (*connect_go.Response[v1.ResetDERPMapResponse], error)
EnabledFileSharing(context.Context, *connect_go.Request[v1.EnableFileSharingRequest]) (*connect_go.Response[v1.EnableFileSharingResponse], error)
DisableFileSharing(context.Context, *connect_go.Request[v1.DisableFileSharingRequest]) (*connect_go.Response[v1.DisableFileSharingResponse], error)
EnabledServiceCollection(context.Context, *connect_go.Request[v1.EnableServiceCollectionRequest]) (*connect_go.Response[v1.EnableServiceCollectionResponse], error)
DisableServiceCollection(context.Context, *connect_go.Request[v1.DisableServiceCollectionRequest]) (*connect_go.Response[v1.DisableServiceCollectionResponse], error)
EnabledSSH(context.Context, *connect_go.Request[v1.EnableSSHRequest]) (*connect_go.Response[v1.EnableSSHResponse], error)
DisableSSH(context.Context, *connect_go.Request[v1.DisableSSHRequest]) (*connect_go.Response[v1.DisableSSHResponse], error)
GetDNSConfig(context.Context, *connect_go.Request[v1.GetDNSConfigRequest]) (*connect_go.Response[v1.GetDNSConfigResponse], error)
SetDNSConfig(context.Context, *connect_go.Request[v1.SetDNSConfigRequest]) (*connect_go.Response[v1.SetDNSConfigResponse], error)
GetIAMPolicy(context.Context, *connect_go.Request[v1.GetIAMPolicyRequest]) (*connect_go.Response[v1.GetIAMPolicyResponse], error)
@@ -55,6 +65,10 @@ type IonscaleServiceClient interface {
GetMachineRoutes(context.Context, *connect_go.Request[v1.GetMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableMachineRoutes(context.Context, *connect_go.Request[v1.EnableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
DisableMachineRoutes(context.Context, *connect_go.Request[v1.DisableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableExitNode(context.Context, *connect_go.Request[v1.EnableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
DisableExitNode(context.Context, *connect_go.Request[v1.DisableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableHttpsCertificates(context.Context, *connect_go.Request[v1.EnableHttpsCertificatesRequest]) (*connect_go.Response[v1.EnableHttpsCertificatesResponse], error)
DisableHttpsCertificates(context.Context, *connect_go.Request[v1.DisableHttpsCertificatesRequest]) (*connect_go.Response[v1.DisableHttpsCertificatesResponse], error)
}
// NewIonscaleServiceClient constructs a client for the ionscale.v1.IonscaleService service. By
@@ -77,14 +91,19 @@ func NewIonscaleServiceClient(httpClient connect_go.HTTPClient, baseURL string,
baseURL+"/ionscale.v1.IonscaleService/Authenticate",
opts...,
),
getDERPMap: connect_go.NewClient[v1.GetDERPMapRequest, v1.GetDERPMapResponse](
getDefaultDERPMap: connect_go.NewClient[v1.GetDefaultDERPMapRequest, v1.GetDefaultDERPMapResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/GetDERPMap",
baseURL+"/ionscale.v1.IonscaleService/GetDefaultDERPMap",
opts...,
),
setDERPMap: connect_go.NewClient[v1.SetDERPMapRequest, v1.SetDERPMapResponse](
setDefaultDERPMap: connect_go.NewClient[v1.SetDefaultDERPMapRequest, v1.SetDefaultDERPMapResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/SetDERPMap",
baseURL+"/ionscale.v1.IonscaleService/SetDefaultDERPMap",
opts...,
),
resetDefaultDERPMap: connect_go.NewClient[v1.ResetDefaultDERPMapRequest, v1.ResetDefaultDERPMapResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/ResetDefaultDERPMap",
opts...,
),
createTailnet: connect_go.NewClient[v1.CreateTailnetRequest, v1.CreateTailnetResponse](
@@ -107,6 +126,51 @@ func NewIonscaleServiceClient(httpClient connect_go.HTTPClient, baseURL string,
baseURL+"/ionscale.v1.IonscaleService/DeleteTailnet",
opts...,
),
getDERPMap: connect_go.NewClient[v1.GetDERPMapRequest, v1.GetDERPMapResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/GetDERPMap",
opts...,
),
setDERPMap: connect_go.NewClient[v1.SetDERPMapRequest, v1.SetDERPMapResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/SetDERPMap",
opts...,
),
resetDERPMap: connect_go.NewClient[v1.ResetDERPMapRequest, v1.ResetDERPMapResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/ResetDERPMap",
opts...,
),
enabledFileSharing: connect_go.NewClient[v1.EnableFileSharingRequest, v1.EnableFileSharingResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/EnabledFileSharing",
opts...,
),
disableFileSharing: connect_go.NewClient[v1.DisableFileSharingRequest, v1.DisableFileSharingResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/DisableFileSharing",
opts...,
),
enabledServiceCollection: connect_go.NewClient[v1.EnableServiceCollectionRequest, v1.EnableServiceCollectionResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/EnabledServiceCollection",
opts...,
),
disableServiceCollection: connect_go.NewClient[v1.DisableServiceCollectionRequest, v1.DisableServiceCollectionResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/DisableServiceCollection",
opts...,
),
enabledSSH: connect_go.NewClient[v1.EnableSSHRequest, v1.EnableSSHResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/EnabledSSH",
opts...,
),
disableSSH: connect_go.NewClient[v1.DisableSSHRequest, v1.DisableSSHResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/DisableSSH",
opts...,
),
getDNSConfig: connect_go.NewClient[v1.GetDNSConfigRequest, v1.GetDNSConfigResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/GetDNSConfig",
@@ -207,39 +271,73 @@ func NewIonscaleServiceClient(httpClient connect_go.HTTPClient, baseURL string,
baseURL+"/ionscale.v1.IonscaleService/DisableMachineRoutes",
opts...,
),
enableExitNode: connect_go.NewClient[v1.EnableExitNodeRequest, v1.GetMachineRoutesResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/EnableExitNode",
opts...,
),
disableExitNode: connect_go.NewClient[v1.DisableExitNodeRequest, v1.GetMachineRoutesResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/DisableExitNode",
opts...,
),
enableHttpsCertificates: connect_go.NewClient[v1.EnableHttpsCertificatesRequest, v1.EnableHttpsCertificatesResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/EnableHttpsCertificates",
opts...,
),
disableHttpsCertificates: connect_go.NewClient[v1.DisableHttpsCertificatesRequest, v1.DisableHttpsCertificatesResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/DisableHttpsCertificates",
opts...,
),
}
}
// ionscaleServiceClient implements IonscaleServiceClient.
type ionscaleServiceClient struct {
getVersion *connect_go.Client[v1.GetVersionRequest, v1.GetVersionResponse]
authenticate *connect_go.Client[v1.AuthenticationRequest, v1.AuthenticationResponse]
getDERPMap *connect_go.Client[v1.GetDERPMapRequest, v1.GetDERPMapResponse]
setDERPMap *connect_go.Client[v1.SetDERPMapRequest, v1.SetDERPMapResponse]
createTailnet *connect_go.Client[v1.CreateTailnetRequest, v1.CreateTailnetResponse]
getTailnet *connect_go.Client[v1.GetTailnetRequest, v1.GetTailnetResponse]
listTailnets *connect_go.Client[v1.ListTailnetRequest, v1.ListTailnetResponse]
deleteTailnet *connect_go.Client[v1.DeleteTailnetRequest, v1.DeleteTailnetResponse]
getDNSConfig *connect_go.Client[v1.GetDNSConfigRequest, v1.GetDNSConfigResponse]
setDNSConfig *connect_go.Client[v1.SetDNSConfigRequest, v1.SetDNSConfigResponse]
getIAMPolicy *connect_go.Client[v1.GetIAMPolicyRequest, v1.GetIAMPolicyResponse]
setIAMPolicy *connect_go.Client[v1.SetIAMPolicyRequest, v1.SetIAMPolicyResponse]
getACLPolicy *connect_go.Client[v1.GetACLPolicyRequest, v1.GetACLPolicyResponse]
setACLPolicy *connect_go.Client[v1.SetACLPolicyRequest, v1.SetACLPolicyResponse]
getAuthKey *connect_go.Client[v1.GetAuthKeyRequest, v1.GetAuthKeyResponse]
createAuthKey *connect_go.Client[v1.CreateAuthKeyRequest, v1.CreateAuthKeyResponse]
deleteAuthKey *connect_go.Client[v1.DeleteAuthKeyRequest, v1.DeleteAuthKeyResponse]
listAuthKeys *connect_go.Client[v1.ListAuthKeysRequest, v1.ListAuthKeysResponse]
listUsers *connect_go.Client[v1.ListUsersRequest, v1.ListUsersResponse]
deleteUser *connect_go.Client[v1.DeleteUserRequest, v1.DeleteUserResponse]
getMachine *connect_go.Client[v1.GetMachineRequest, v1.GetMachineResponse]
listMachines *connect_go.Client[v1.ListMachinesRequest, v1.ListMachinesResponse]
expireMachine *connect_go.Client[v1.ExpireMachineRequest, v1.ExpireMachineResponse]
deleteMachine *connect_go.Client[v1.DeleteMachineRequest, v1.DeleteMachineResponse]
setMachineKeyExpiry *connect_go.Client[v1.SetMachineKeyExpiryRequest, v1.SetMachineKeyExpiryResponse]
getMachineRoutes *connect_go.Client[v1.GetMachineRoutesRequest, v1.GetMachineRoutesResponse]
enableMachineRoutes *connect_go.Client[v1.EnableMachineRoutesRequest, v1.GetMachineRoutesResponse]
disableMachineRoutes *connect_go.Client[v1.DisableMachineRoutesRequest, v1.GetMachineRoutesResponse]
getVersion *connect_go.Client[v1.GetVersionRequest, v1.GetVersionResponse]
authenticate *connect_go.Client[v1.AuthenticationRequest, v1.AuthenticationResponse]
getDefaultDERPMap *connect_go.Client[v1.GetDefaultDERPMapRequest, v1.GetDefaultDERPMapResponse]
setDefaultDERPMap *connect_go.Client[v1.SetDefaultDERPMapRequest, v1.SetDefaultDERPMapResponse]
resetDefaultDERPMap *connect_go.Client[v1.ResetDefaultDERPMapRequest, v1.ResetDefaultDERPMapResponse]
createTailnet *connect_go.Client[v1.CreateTailnetRequest, v1.CreateTailnetResponse]
getTailnet *connect_go.Client[v1.GetTailnetRequest, v1.GetTailnetResponse]
listTailnets *connect_go.Client[v1.ListTailnetRequest, v1.ListTailnetResponse]
deleteTailnet *connect_go.Client[v1.DeleteTailnetRequest, v1.DeleteTailnetResponse]
getDERPMap *connect_go.Client[v1.GetDERPMapRequest, v1.GetDERPMapResponse]
setDERPMap *connect_go.Client[v1.SetDERPMapRequest, v1.SetDERPMapResponse]
resetDERPMap *connect_go.Client[v1.ResetDERPMapRequest, v1.ResetDERPMapResponse]
enabledFileSharing *connect_go.Client[v1.EnableFileSharingRequest, v1.EnableFileSharingResponse]
disableFileSharing *connect_go.Client[v1.DisableFileSharingRequest, v1.DisableFileSharingResponse]
enabledServiceCollection *connect_go.Client[v1.EnableServiceCollectionRequest, v1.EnableServiceCollectionResponse]
disableServiceCollection *connect_go.Client[v1.DisableServiceCollectionRequest, v1.DisableServiceCollectionResponse]
enabledSSH *connect_go.Client[v1.EnableSSHRequest, v1.EnableSSHResponse]
disableSSH *connect_go.Client[v1.DisableSSHRequest, v1.DisableSSHResponse]
getDNSConfig *connect_go.Client[v1.GetDNSConfigRequest, v1.GetDNSConfigResponse]
setDNSConfig *connect_go.Client[v1.SetDNSConfigRequest, v1.SetDNSConfigResponse]
getIAMPolicy *connect_go.Client[v1.GetIAMPolicyRequest, v1.GetIAMPolicyResponse]
setIAMPolicy *connect_go.Client[v1.SetIAMPolicyRequest, v1.SetIAMPolicyResponse]
getACLPolicy *connect_go.Client[v1.GetACLPolicyRequest, v1.GetACLPolicyResponse]
setACLPolicy *connect_go.Client[v1.SetACLPolicyRequest, v1.SetACLPolicyResponse]
getAuthKey *connect_go.Client[v1.GetAuthKeyRequest, v1.GetAuthKeyResponse]
createAuthKey *connect_go.Client[v1.CreateAuthKeyRequest, v1.CreateAuthKeyResponse]
deleteAuthKey *connect_go.Client[v1.DeleteAuthKeyRequest, v1.DeleteAuthKeyResponse]
listAuthKeys *connect_go.Client[v1.ListAuthKeysRequest, v1.ListAuthKeysResponse]
listUsers *connect_go.Client[v1.ListUsersRequest, v1.ListUsersResponse]
deleteUser *connect_go.Client[v1.DeleteUserRequest, v1.DeleteUserResponse]
getMachine *connect_go.Client[v1.GetMachineRequest, v1.GetMachineResponse]
listMachines *connect_go.Client[v1.ListMachinesRequest, v1.ListMachinesResponse]
expireMachine *connect_go.Client[v1.ExpireMachineRequest, v1.ExpireMachineResponse]
deleteMachine *connect_go.Client[v1.DeleteMachineRequest, v1.DeleteMachineResponse]
setMachineKeyExpiry *connect_go.Client[v1.SetMachineKeyExpiryRequest, v1.SetMachineKeyExpiryResponse]
getMachineRoutes *connect_go.Client[v1.GetMachineRoutesRequest, v1.GetMachineRoutesResponse]
enableMachineRoutes *connect_go.Client[v1.EnableMachineRoutesRequest, v1.GetMachineRoutesResponse]
disableMachineRoutes *connect_go.Client[v1.DisableMachineRoutesRequest, v1.GetMachineRoutesResponse]
enableExitNode *connect_go.Client[v1.EnableExitNodeRequest, v1.GetMachineRoutesResponse]
disableExitNode *connect_go.Client[v1.DisableExitNodeRequest, v1.GetMachineRoutesResponse]
enableHttpsCertificates *connect_go.Client[v1.EnableHttpsCertificatesRequest, v1.EnableHttpsCertificatesResponse]
disableHttpsCertificates *connect_go.Client[v1.DisableHttpsCertificatesRequest, v1.DisableHttpsCertificatesResponse]
}
// GetVersion calls ionscale.v1.IonscaleService.GetVersion.
@@ -252,14 +350,19 @@ func (c *ionscaleServiceClient) Authenticate(ctx context.Context, req *connect_g
return c.authenticate.CallServerStream(ctx, req)
}
// GetDERPMap calls ionscale.v1.IonscaleService.GetDERPMap.
func (c *ionscaleServiceClient) GetDERPMap(ctx context.Context, req *connect_go.Request[v1.GetDERPMapRequest]) (*connect_go.Response[v1.GetDERPMapResponse], error) {
return c.getDERPMap.CallUnary(ctx, req)
// GetDefaultDERPMap calls ionscale.v1.IonscaleService.GetDefaultDERPMap.
func (c *ionscaleServiceClient) GetDefaultDERPMap(ctx context.Context, req *connect_go.Request[v1.GetDefaultDERPMapRequest]) (*connect_go.Response[v1.GetDefaultDERPMapResponse], error) {
return c.getDefaultDERPMap.CallUnary(ctx, req)
}
// SetDERPMap calls ionscale.v1.IonscaleService.SetDERPMap.
func (c *ionscaleServiceClient) SetDERPMap(ctx context.Context, req *connect_go.Request[v1.SetDERPMapRequest]) (*connect_go.Response[v1.SetDERPMapResponse], error) {
return c.setDERPMap.CallUnary(ctx, req)
// SetDefaultDERPMap calls ionscale.v1.IonscaleService.SetDefaultDERPMap.
func (c *ionscaleServiceClient) SetDefaultDERPMap(ctx context.Context, req *connect_go.Request[v1.SetDefaultDERPMapRequest]) (*connect_go.Response[v1.SetDefaultDERPMapResponse], error) {
return c.setDefaultDERPMap.CallUnary(ctx, req)
}
// ResetDefaultDERPMap calls ionscale.v1.IonscaleService.ResetDefaultDERPMap.
func (c *ionscaleServiceClient) ResetDefaultDERPMap(ctx context.Context, req *connect_go.Request[v1.ResetDefaultDERPMapRequest]) (*connect_go.Response[v1.ResetDefaultDERPMapResponse], error) {
return c.resetDefaultDERPMap.CallUnary(ctx, req)
}
// CreateTailnet calls ionscale.v1.IonscaleService.CreateTailnet.
@@ -282,6 +385,51 @@ func (c *ionscaleServiceClient) DeleteTailnet(ctx context.Context, req *connect_
return c.deleteTailnet.CallUnary(ctx, req)
}
// GetDERPMap calls ionscale.v1.IonscaleService.GetDERPMap.
func (c *ionscaleServiceClient) GetDERPMap(ctx context.Context, req *connect_go.Request[v1.GetDERPMapRequest]) (*connect_go.Response[v1.GetDERPMapResponse], error) {
return c.getDERPMap.CallUnary(ctx, req)
}
// SetDERPMap calls ionscale.v1.IonscaleService.SetDERPMap.
func (c *ionscaleServiceClient) SetDERPMap(ctx context.Context, req *connect_go.Request[v1.SetDERPMapRequest]) (*connect_go.Response[v1.SetDERPMapResponse], error) {
return c.setDERPMap.CallUnary(ctx, req)
}
// ResetDERPMap calls ionscale.v1.IonscaleService.ResetDERPMap.
func (c *ionscaleServiceClient) ResetDERPMap(ctx context.Context, req *connect_go.Request[v1.ResetDERPMapRequest]) (*connect_go.Response[v1.ResetDERPMapResponse], error) {
return c.resetDERPMap.CallUnary(ctx, req)
}
// EnabledFileSharing calls ionscale.v1.IonscaleService.EnabledFileSharing.
func (c *ionscaleServiceClient) EnabledFileSharing(ctx context.Context, req *connect_go.Request[v1.EnableFileSharingRequest]) (*connect_go.Response[v1.EnableFileSharingResponse], error) {
return c.enabledFileSharing.CallUnary(ctx, req)
}
// DisableFileSharing calls ionscale.v1.IonscaleService.DisableFileSharing.
func (c *ionscaleServiceClient) DisableFileSharing(ctx context.Context, req *connect_go.Request[v1.DisableFileSharingRequest]) (*connect_go.Response[v1.DisableFileSharingResponse], error) {
return c.disableFileSharing.CallUnary(ctx, req)
}
// EnabledServiceCollection calls ionscale.v1.IonscaleService.EnabledServiceCollection.
func (c *ionscaleServiceClient) EnabledServiceCollection(ctx context.Context, req *connect_go.Request[v1.EnableServiceCollectionRequest]) (*connect_go.Response[v1.EnableServiceCollectionResponse], error) {
return c.enabledServiceCollection.CallUnary(ctx, req)
}
// DisableServiceCollection calls ionscale.v1.IonscaleService.DisableServiceCollection.
func (c *ionscaleServiceClient) DisableServiceCollection(ctx context.Context, req *connect_go.Request[v1.DisableServiceCollectionRequest]) (*connect_go.Response[v1.DisableServiceCollectionResponse], error) {
return c.disableServiceCollection.CallUnary(ctx, req)
}
// EnabledSSH calls ionscale.v1.IonscaleService.EnabledSSH.
func (c *ionscaleServiceClient) EnabledSSH(ctx context.Context, req *connect_go.Request[v1.EnableSSHRequest]) (*connect_go.Response[v1.EnableSSHResponse], error) {
return c.enabledSSH.CallUnary(ctx, req)
}
// DisableSSH calls ionscale.v1.IonscaleService.DisableSSH.
func (c *ionscaleServiceClient) DisableSSH(ctx context.Context, req *connect_go.Request[v1.DisableSSHRequest]) (*connect_go.Response[v1.DisableSSHResponse], error) {
return c.disableSSH.CallUnary(ctx, req)
}
// GetDNSConfig calls ionscale.v1.IonscaleService.GetDNSConfig.
func (c *ionscaleServiceClient) GetDNSConfig(ctx context.Context, req *connect_go.Request[v1.GetDNSConfigRequest]) (*connect_go.Response[v1.GetDNSConfigResponse], error) {
return c.getDNSConfig.CallUnary(ctx, req)
@@ -382,16 +530,46 @@ func (c *ionscaleServiceClient) DisableMachineRoutes(ctx context.Context, req *c
return c.disableMachineRoutes.CallUnary(ctx, req)
}
// EnableExitNode calls ionscale.v1.IonscaleService.EnableExitNode.
func (c *ionscaleServiceClient) EnableExitNode(ctx context.Context, req *connect_go.Request[v1.EnableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return c.enableExitNode.CallUnary(ctx, req)
}
// DisableExitNode calls ionscale.v1.IonscaleService.DisableExitNode.
func (c *ionscaleServiceClient) DisableExitNode(ctx context.Context, req *connect_go.Request[v1.DisableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return c.disableExitNode.CallUnary(ctx, req)
}
// EnableHttpsCertificates calls ionscale.v1.IonscaleService.EnableHttpsCertificates.
func (c *ionscaleServiceClient) EnableHttpsCertificates(ctx context.Context, req *connect_go.Request[v1.EnableHttpsCertificatesRequest]) (*connect_go.Response[v1.EnableHttpsCertificatesResponse], error) {
return c.enableHttpsCertificates.CallUnary(ctx, req)
}
// DisableHttpsCertificates calls ionscale.v1.IonscaleService.DisableHttpsCertificates.
func (c *ionscaleServiceClient) DisableHttpsCertificates(ctx context.Context, req *connect_go.Request[v1.DisableHttpsCertificatesRequest]) (*connect_go.Response[v1.DisableHttpsCertificatesResponse], error) {
return c.disableHttpsCertificates.CallUnary(ctx, req)
}
// IonscaleServiceHandler is an implementation of the ionscale.v1.IonscaleService service.
type IonscaleServiceHandler interface {
GetVersion(context.Context, *connect_go.Request[v1.GetVersionRequest]) (*connect_go.Response[v1.GetVersionResponse], error)
Authenticate(context.Context, *connect_go.Request[v1.AuthenticationRequest], *connect_go.ServerStream[v1.AuthenticationResponse]) error
GetDERPMap(context.Context, *connect_go.Request[v1.GetDERPMapRequest]) (*connect_go.Response[v1.GetDERPMapResponse], error)
SetDERPMap(context.Context, *connect_go.Request[v1.SetDERPMapRequest]) (*connect_go.Response[v1.SetDERPMapResponse], error)
GetDefaultDERPMap(context.Context, *connect_go.Request[v1.GetDefaultDERPMapRequest]) (*connect_go.Response[v1.GetDefaultDERPMapResponse], error)
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)
GetTailnet(context.Context, *connect_go.Request[v1.GetTailnetRequest]) (*connect_go.Response[v1.GetTailnetResponse], error)
ListTailnets(context.Context, *connect_go.Request[v1.ListTailnetRequest]) (*connect_go.Response[v1.ListTailnetResponse], error)
DeleteTailnet(context.Context, *connect_go.Request[v1.DeleteTailnetRequest]) (*connect_go.Response[v1.DeleteTailnetResponse], error)
GetDERPMap(context.Context, *connect_go.Request[v1.GetDERPMapRequest]) (*connect_go.Response[v1.GetDERPMapResponse], error)
SetDERPMap(context.Context, *connect_go.Request[v1.SetDERPMapRequest]) (*connect_go.Response[v1.SetDERPMapResponse], error)
ResetDERPMap(context.Context, *connect_go.Request[v1.ResetDERPMapRequest]) (*connect_go.Response[v1.ResetDERPMapResponse], error)
EnabledFileSharing(context.Context, *connect_go.Request[v1.EnableFileSharingRequest]) (*connect_go.Response[v1.EnableFileSharingResponse], error)
DisableFileSharing(context.Context, *connect_go.Request[v1.DisableFileSharingRequest]) (*connect_go.Response[v1.DisableFileSharingResponse], error)
EnabledServiceCollection(context.Context, *connect_go.Request[v1.EnableServiceCollectionRequest]) (*connect_go.Response[v1.EnableServiceCollectionResponse], error)
DisableServiceCollection(context.Context, *connect_go.Request[v1.DisableServiceCollectionRequest]) (*connect_go.Response[v1.DisableServiceCollectionResponse], error)
EnabledSSH(context.Context, *connect_go.Request[v1.EnableSSHRequest]) (*connect_go.Response[v1.EnableSSHResponse], error)
DisableSSH(context.Context, *connect_go.Request[v1.DisableSSHRequest]) (*connect_go.Response[v1.DisableSSHResponse], error)
GetDNSConfig(context.Context, *connect_go.Request[v1.GetDNSConfigRequest]) (*connect_go.Response[v1.GetDNSConfigResponse], error)
SetDNSConfig(context.Context, *connect_go.Request[v1.SetDNSConfigRequest]) (*connect_go.Response[v1.SetDNSConfigResponse], error)
GetIAMPolicy(context.Context, *connect_go.Request[v1.GetIAMPolicyRequest]) (*connect_go.Response[v1.GetIAMPolicyResponse], error)
@@ -412,6 +590,10 @@ type IonscaleServiceHandler interface {
GetMachineRoutes(context.Context, *connect_go.Request[v1.GetMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableMachineRoutes(context.Context, *connect_go.Request[v1.EnableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
DisableMachineRoutes(context.Context, *connect_go.Request[v1.DisableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableExitNode(context.Context, *connect_go.Request[v1.EnableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
DisableExitNode(context.Context, *connect_go.Request[v1.DisableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableHttpsCertificates(context.Context, *connect_go.Request[v1.EnableHttpsCertificatesRequest]) (*connect_go.Response[v1.EnableHttpsCertificatesResponse], error)
DisableHttpsCertificates(context.Context, *connect_go.Request[v1.DisableHttpsCertificatesRequest]) (*connect_go.Response[v1.DisableHttpsCertificatesResponse], error)
}
// NewIonscaleServiceHandler builds an HTTP handler from the service implementation. It returns the
@@ -431,14 +613,19 @@ func NewIonscaleServiceHandler(svc IonscaleServiceHandler, opts ...connect_go.Ha
svc.Authenticate,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/GetDERPMap", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/GetDERPMap",
svc.GetDERPMap,
mux.Handle("/ionscale.v1.IonscaleService/GetDefaultDERPMap", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/GetDefaultDERPMap",
svc.GetDefaultDERPMap,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/SetDERPMap", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/SetDERPMap",
svc.SetDERPMap,
mux.Handle("/ionscale.v1.IonscaleService/SetDefaultDERPMap", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/SetDefaultDERPMap",
svc.SetDefaultDERPMap,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/ResetDefaultDERPMap", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/ResetDefaultDERPMap",
svc.ResetDefaultDERPMap,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/CreateTailnet", connect_go.NewUnaryHandler(
@@ -461,6 +648,51 @@ func NewIonscaleServiceHandler(svc IonscaleServiceHandler, opts ...connect_go.Ha
svc.DeleteTailnet,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/GetDERPMap", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/GetDERPMap",
svc.GetDERPMap,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/SetDERPMap", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/SetDERPMap",
svc.SetDERPMap,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/ResetDERPMap", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/ResetDERPMap",
svc.ResetDERPMap,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/EnabledFileSharing", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/EnabledFileSharing",
svc.EnabledFileSharing,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/DisableFileSharing", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/DisableFileSharing",
svc.DisableFileSharing,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/EnabledServiceCollection", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/EnabledServiceCollection",
svc.EnabledServiceCollection,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/DisableServiceCollection", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/DisableServiceCollection",
svc.DisableServiceCollection,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/EnabledSSH", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/EnabledSSH",
svc.EnabledSSH,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/DisableSSH", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/DisableSSH",
svc.DisableSSH,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/GetDNSConfig", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/GetDNSConfig",
svc.GetDNSConfig,
@@ -561,6 +793,26 @@ func NewIonscaleServiceHandler(svc IonscaleServiceHandler, opts ...connect_go.Ha
svc.DisableMachineRoutes,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/EnableExitNode", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/EnableExitNode",
svc.EnableExitNode,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/DisableExitNode", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/DisableExitNode",
svc.DisableExitNode,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/EnableHttpsCertificates", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/EnableHttpsCertificates",
svc.EnableHttpsCertificates,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/DisableHttpsCertificates", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/DisableHttpsCertificates",
svc.DisableHttpsCertificates,
opts...,
))
return "/ionscale.v1.IonscaleService/", mux
}
@@ -575,12 +827,16 @@ func (UnimplementedIonscaleServiceHandler) Authenticate(context.Context, *connec
return connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.Authenticate is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) GetDERPMap(context.Context, *connect_go.Request[v1.GetDERPMapRequest]) (*connect_go.Response[v1.GetDERPMapResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.GetDERPMap is not implemented"))
func (UnimplementedIonscaleServiceHandler) GetDefaultDERPMap(context.Context, *connect_go.Request[v1.GetDefaultDERPMapRequest]) (*connect_go.Response[v1.GetDefaultDERPMapResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.GetDefaultDERPMap is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) SetDERPMap(context.Context, *connect_go.Request[v1.SetDERPMapRequest]) (*connect_go.Response[v1.SetDERPMapResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.SetDERPMap is not implemented"))
func (UnimplementedIonscaleServiceHandler) SetDefaultDERPMap(context.Context, *connect_go.Request[v1.SetDefaultDERPMapRequest]) (*connect_go.Response[v1.SetDefaultDERPMapResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.SetDefaultDERPMap is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) ResetDefaultDERPMap(context.Context, *connect_go.Request[v1.ResetDefaultDERPMapRequest]) (*connect_go.Response[v1.ResetDefaultDERPMapResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.ResetDefaultDERPMap is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) CreateTailnet(context.Context, *connect_go.Request[v1.CreateTailnetRequest]) (*connect_go.Response[v1.CreateTailnetResponse], error) {
@@ -599,6 +855,42 @@ func (UnimplementedIonscaleServiceHandler) DeleteTailnet(context.Context, *conne
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DeleteTailnet is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) GetDERPMap(context.Context, *connect_go.Request[v1.GetDERPMapRequest]) (*connect_go.Response[v1.GetDERPMapResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.GetDERPMap is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) SetDERPMap(context.Context, *connect_go.Request[v1.SetDERPMapRequest]) (*connect_go.Response[v1.SetDERPMapResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.SetDERPMap is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) ResetDERPMap(context.Context, *connect_go.Request[v1.ResetDERPMapRequest]) (*connect_go.Response[v1.ResetDERPMapResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.ResetDERPMap is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) EnabledFileSharing(context.Context, *connect_go.Request[v1.EnableFileSharingRequest]) (*connect_go.Response[v1.EnableFileSharingResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.EnabledFileSharing is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) DisableFileSharing(context.Context, *connect_go.Request[v1.DisableFileSharingRequest]) (*connect_go.Response[v1.DisableFileSharingResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableFileSharing is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) EnabledServiceCollection(context.Context, *connect_go.Request[v1.EnableServiceCollectionRequest]) (*connect_go.Response[v1.EnableServiceCollectionResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.EnabledServiceCollection is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) DisableServiceCollection(context.Context, *connect_go.Request[v1.DisableServiceCollectionRequest]) (*connect_go.Response[v1.DisableServiceCollectionResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableServiceCollection is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) EnabledSSH(context.Context, *connect_go.Request[v1.EnableSSHRequest]) (*connect_go.Response[v1.EnableSSHResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.EnabledSSH is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) DisableSSH(context.Context, *connect_go.Request[v1.DisableSSHRequest]) (*connect_go.Response[v1.DisableSSHResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableSSH is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) GetDNSConfig(context.Context, *connect_go.Request[v1.GetDNSConfigRequest]) (*connect_go.Response[v1.GetDNSConfigResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.GetDNSConfig is not implemented"))
}
@@ -678,3 +970,19 @@ func (UnimplementedIonscaleServiceHandler) EnableMachineRoutes(context.Context,
func (UnimplementedIonscaleServiceHandler) DisableMachineRoutes(context.Context, *connect_go.Request[v1.DisableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableMachineRoutes is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) EnableExitNode(context.Context, *connect_go.Request[v1.EnableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.EnableExitNode is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) DisableExitNode(context.Context, *connect_go.Request[v1.DisableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableExitNode is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) EnableHttpsCertificates(context.Context, *connect_go.Request[v1.EnableHttpsCertificatesRequest]) (*connect_go.Response[v1.EnableHttpsCertificatesResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.EnableHttpsCertificates is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) DisableHttpsCertificates(context.Context, *connect_go.Request[v1.DisableHttpsCertificatesRequest]) (*connect_go.Response[v1.DisableHttpsCertificatesResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableHttpsCertificates is not implemented"))
}
+32 -10
View File
@@ -496,6 +496,8 @@ type Machine struct {
KeyExpiryDisabled bool `protobuf:"varint,16,opt,name=key_expiry_disabled,json=keyExpiryDisabled,proto3" json:"key_expiry_disabled,omitempty"`
EnabledRoutes []string `protobuf:"bytes,17,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"`
AdvertisedRoutes []string `protobuf:"bytes,18,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"`
AdvertisedExitNode bool `protobuf:"varint,19,opt,name=advertised_exit_node,json=advertisedExitNode,proto3" json:"advertised_exit_node,omitempty"`
EnabledExitNode bool `protobuf:"varint,20,opt,name=enabled_exit_node,json=enabledExitNode,proto3" json:"enabled_exit_node,omitempty"`
}
func (x *Machine) Reset() {
@@ -656,6 +658,20 @@ func (x *Machine) GetAdvertisedRoutes() []string {
return nil
}
func (x *Machine) GetAdvertisedExitNode() bool {
if x != nil {
return x.AdvertisedExitNode
}
return false
}
func (x *Machine) GetEnabledExitNode() bool {
if x != nil {
return x.EnabledExitNode
}
return false
}
type ClientConnectivity struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -747,7 +763,7 @@ var file_ionscale_v1_machines_proto_rawDesc = []byte{
0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x22, 0xb3, 0x05, 0x0a, 0x07, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12,
0x69, 0x6e, 0x65, 0x22, 0x91, 0x06, 0x0a, 0x07, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28,
@@ -790,15 +806,21 @@ var file_ionscale_v1_machines_proto_rawDesc = []byte{
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11,
0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69,
0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x32, 0x0a, 0x12, 0x43, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12,
0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x09, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 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,
0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x64, 0x76,
0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x6e, 0x6f, 0x64,
0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69,
0x73, 0x65, 0x64, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x65,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65,
0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x45,
0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x22, 0x32, 0x0a, 0x12, 0x43, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09,
0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 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 (
+173 -24
View File
@@ -72,8 +72,10 @@ type GetMachineRoutesResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
AdvertisedRoutes []string `protobuf:"bytes,1,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"`
EnabledRoutes []string `protobuf:"bytes,2,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"`
AdvertisedRoutes []string `protobuf:"bytes,1,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"`
EnabledRoutes []string `protobuf:"bytes,2,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"`
AdvertisedExitNode bool `protobuf:"varint,3,opt,name=advertised_exit_node,json=advertisedExitNode,proto3" json:"advertised_exit_node,omitempty"`
EnabledExitNode bool `protobuf:"varint,4,opt,name=enabled_exit_node,json=enabledExitNode,proto3" json:"enabled_exit_node,omitempty"`
}
func (x *GetMachineRoutesResponse) Reset() {
@@ -122,6 +124,20 @@ func (x *GetMachineRoutesResponse) GetEnabledRoutes() []string {
return nil
}
func (x *GetMachineRoutesResponse) GetAdvertisedExitNode() bool {
if x != nil {
return x.AdvertisedExitNode
}
return false
}
func (x *GetMachineRoutesResponse) GetEnabledExitNode() bool {
if x != nil {
return x.EnabledExitNode
}
return false
}
type EnableMachineRoutesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -240,6 +256,100 @@ func (x *DisableMachineRoutesRequest) GetRoutes() []string {
return nil
}
type EnableExitNodeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
}
func (x *EnableExitNodeRequest) Reset() {
*x = EnableExitNodeRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_routes_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EnableExitNodeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EnableExitNodeRequest) ProtoMessage() {}
func (x *EnableExitNodeRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_routes_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EnableExitNodeRequest.ProtoReflect.Descriptor instead.
func (*EnableExitNodeRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_routes_proto_rawDescGZIP(), []int{4}
}
func (x *EnableExitNodeRequest) GetMachineId() uint64 {
if x != nil {
return x.MachineId
}
return 0
}
type DisableExitNodeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
}
func (x *DisableExitNodeRequest) Reset() {
*x = DisableExitNodeRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_routes_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DisableExitNodeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DisableExitNodeRequest) ProtoMessage() {}
func (x *DisableExitNodeRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_routes_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DisableExitNodeRequest.ProtoReflect.Descriptor instead.
func (*DisableExitNodeRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_routes_proto_rawDescGZIP(), []int{5}
}
func (x *DisableExitNodeRequest) GetMachineId() uint64 {
if x != nil {
return x.MachineId
}
return 0
}
var File_ionscale_v1_routes_proto protoreflect.FileDescriptor
var file_ionscale_v1_routes_proto_rawDesc = []byte{
@@ -249,26 +359,39 @@ var file_ionscale_v1_routes_proto_rawDesc = []byte{
0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49,
0x64, 0x22, 0x6e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a,
0x11, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74,
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74,
0x69, 0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e,
0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65,
0x73, 0x22, 0x6d, 0x0a, 0x1a, 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, 0x12,
0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16,
0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63,
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
0x22, 0x54, 0x0a, 0x1b, 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, 0x12,
0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16,
0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x64, 0x22, 0xcc, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65,
0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b,
0x0a, 0x11, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75,
0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x64, 0x76, 0x65, 0x72,
0x74, 0x69, 0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74,
0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64,
0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x12, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x45, 0x78, 0x69, 0x74,
0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f,
0x65, 0x78, 0x69, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65,
0x22, 0x6d, 0x0a, 0x1a, 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, 0x12, 0x1d,
0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a,
0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x22,
0x54, 0x0a, 0x1b, 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, 0x12, 0x1d,
0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a,
0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x36, 0x0a, 0x15, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45,
0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x37, 0x0a,
0x16, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69,
0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63,
0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 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,
@@ -287,12 +410,14 @@ func file_ionscale_v1_routes_proto_rawDescGZIP() []byte {
return file_ionscale_v1_routes_proto_rawDescData
}
var file_ionscale_v1_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_ionscale_v1_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_ionscale_v1_routes_proto_goTypes = []interface{}{
(*GetMachineRoutesRequest)(nil), // 0: ionscale.v1.GetMachineRoutesRequest
(*GetMachineRoutesResponse)(nil), // 1: ionscale.v1.GetMachineRoutesResponse
(*EnableMachineRoutesRequest)(nil), // 2: ionscale.v1.EnableMachineRoutesRequest
(*DisableMachineRoutesRequest)(nil), // 3: ionscale.v1.DisableMachineRoutesRequest
(*EnableExitNodeRequest)(nil), // 4: ionscale.v1.EnableExitNodeRequest
(*DisableExitNodeRequest)(nil), // 5: ionscale.v1.DisableExitNodeRequest
}
var file_ionscale_v1_routes_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
@@ -356,6 +481,30 @@ func file_ionscale_v1_routes_proto_init() {
return nil
}
}
file_ionscale_v1_routes_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EnableExitNodeRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_routes_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DisableExitNodeRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -363,7 +512,7 @@ func file_ionscale_v1_routes_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ionscale_v1_routes_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},
File diff suppressed because it is too large Load Diff
+15 -1
View File
@@ -27,11 +27,25 @@ message ACLPolicy {
map<string, string> hosts = 1;
map<string, google.protobuf.ListValue> groups = 2;
repeated ACL acls = 3;
map<string, google.protobuf.ListValue> tag_owners = 4;
map<string, google.protobuf.ListValue> tagowners = 4;
AutoApprovers autoapprovers = 5;
repeated SSHRule ssh = 6;
}
message ACL {
string action = 1;
repeated string src = 2;
repeated string dst = 3;
}
message AutoApprovers {
map<string, google.protobuf.ListValue> routes = 1;
repeated string exitnode = 2;
}
message SSHRule {
string action = 1;
repeated string src = 2;
repeated string dst = 3;
repeated string users = 4;
}
+10 -4
View File
@@ -3,16 +3,22 @@ syntax = "proto3";
package ionscale.v1;
option go_package = "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1;ionscalev1";
message GetDERPMapRequest {}
message GetDefaultDERPMapRequest {}
message GetDERPMapResponse {
message GetDefaultDERPMapResponse {
bytes value = 1;
}
message SetDERPMapRequest {
message SetDefaultDERPMapRequest {
bytes value = 1;
}
message SetDERPMapResponse {
message SetDefaultDERPMapResponse {
bytes value = 1;
}
message ResetDefaultDERPMapRequest {
}
message ResetDefaultDERPMapResponse {
}
+15
View File
@@ -23,6 +23,21 @@ message SetDNSConfigResponse {
DNSConfig config = 1;
}
message EnableHttpsCertificatesRequest {
uint64 tailnet_id = 1;
string alias = 2;
}
message EnableHttpsCertificatesResponse {
}
message DisableHttpsCertificatesRequest {
uint64 tailnet_id = 1;
}
message DisableHttpsCertificatesResponse {
}
message DNSConfig {
bool magic_dns = 1;
bool override_local_dns = 2;
+16 -2
View File
@@ -23,13 +23,23 @@ service IonscaleService {
rpc Authenticate (AuthenticationRequest) returns (stream AuthenticationResponse) {}
rpc GetDERPMap (GetDERPMapRequest) returns (GetDERPMapResponse) {}
rpc SetDERPMap (SetDERPMapRequest) returns (SetDERPMapResponse) {}
rpc GetDefaultDERPMap (GetDefaultDERPMapRequest) returns (GetDefaultDERPMapResponse) {}
rpc SetDefaultDERPMap (SetDefaultDERPMapRequest) returns (SetDefaultDERPMapResponse) {}
rpc ResetDefaultDERPMap (ResetDefaultDERPMapRequest) returns (ResetDefaultDERPMapResponse) {}
rpc CreateTailnet (CreateTailnetRequest) returns (CreateTailnetResponse) {}
rpc GetTailnet (GetTailnetRequest) returns (GetTailnetResponse) {}
rpc ListTailnets (ListTailnetRequest) returns (ListTailnetResponse) {}
rpc DeleteTailnet (DeleteTailnetRequest) returns (DeleteTailnetResponse) {}
rpc GetDERPMap (GetDERPMapRequest) returns (GetDERPMapResponse) {}
rpc SetDERPMap (SetDERPMapRequest) returns (SetDERPMapResponse) {}
rpc ResetDERPMap (ResetDERPMapRequest) returns (ResetDERPMapResponse) {}
rpc EnabledFileSharing (EnableFileSharingRequest) returns (EnableFileSharingResponse) {}
rpc DisableFileSharing (DisableFileSharingRequest) returns (DisableFileSharingResponse) {}
rpc EnabledServiceCollection (EnableServiceCollectionRequest) returns (EnableServiceCollectionResponse) {}
rpc DisableServiceCollection (DisableServiceCollectionRequest) returns (DisableServiceCollectionResponse) {}
rpc EnabledSSH (EnableSSHRequest) returns (EnableSSHResponse) {}
rpc DisableSSH (DisableSSHRequest) returns (DisableSSHResponse) {}
rpc GetDNSConfig (GetDNSConfigRequest) returns (GetDNSConfigResponse) {}
rpc SetDNSConfig (SetDNSConfigRequest) returns (SetDNSConfigResponse) {}
@@ -56,4 +66,8 @@ service IonscaleService {
rpc GetMachineRoutes (GetMachineRoutesRequest) returns (GetMachineRoutesResponse) {}
rpc EnableMachineRoutes (EnableMachineRoutesRequest) returns (GetMachineRoutesResponse) {}
rpc DisableMachineRoutes (DisableMachineRoutesRequest) returns (GetMachineRoutesResponse) {}
rpc EnableExitNode (EnableExitNodeRequest) returns (GetMachineRoutesResponse) {}
rpc DisableExitNode (DisableExitNodeRequest) returns (GetMachineRoutesResponse) {}
rpc EnableHttpsCertificates (EnableHttpsCertificatesRequest) returns (EnableHttpsCertificatesResponse) {}
rpc DisableHttpsCertificates (DisableHttpsCertificatesRequest) returns (DisableHttpsCertificatesResponse) {}
}
+2
View File
@@ -62,6 +62,8 @@ message Machine {
bool key_expiry_disabled = 16;
repeated string enabled_routes = 17;
repeated string advertised_routes = 18;
bool advertised_exit_node = 19;
bool enabled_exit_node = 20;
}
message ClientConnectivity {
+10
View File
@@ -10,6 +10,8 @@ message GetMachineRoutesRequest {
message GetMachineRoutesResponse {
repeated string advertised_routes = 1;
repeated string enabled_routes = 2;
bool advertised_exit_node = 3;
bool enabled_exit_node = 4;
}
message EnableMachineRoutesRequest {
@@ -22,3 +24,11 @@ message DisableMachineRoutesRequest {
uint64 machine_id = 1;
repeated string routes = 2;
}
message EnableExitNodeRequest {
uint64 machine_id = 1;
}
message DisableExitNodeRequest {
uint64 machine_id = 1;
}
+71 -1
View File
@@ -3,6 +3,8 @@ syntax = "proto3";
package ionscale.v1;
option go_package = "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1;ionscalev1";
import "ionscale/v1/iam.proto";
message Tailnet {
uint64 id = 1;
string name = 2;
@@ -10,6 +12,7 @@ message Tailnet {
message CreateTailnetRequest {
string name = 1;
IAMPolicy iam_policy = 2;
}
message CreateTailnetResponse {
@@ -36,4 +39,71 @@ message DeleteTailnetRequest {
bool force = 2;
}
message DeleteTailnetResponse {}
message DeleteTailnetResponse {}
message GetDERPMapRequest {
uint64 tailnet_id = 1;
}
message GetDERPMapResponse {
bytes value = 1;
}
message SetDERPMapRequest {
uint64 tailnet_id = 1;
bytes value = 2;
}
message SetDERPMapResponse {
bytes value = 1;
}
message ResetDERPMapRequest {
uint64 tailnet_id = 1;
}
message ResetDERPMapResponse {
}
message EnableFileSharingRequest {
uint64 tailnet_id = 1;
}
message EnableFileSharingResponse {
}
message DisableFileSharingRequest {
uint64 tailnet_id = 1;
}
message DisableFileSharingResponse {
}
message EnableServiceCollectionRequest {
uint64 tailnet_id = 1;
}
message EnableServiceCollectionResponse {
}
message DisableServiceCollectionRequest {
uint64 tailnet_id = 1;
}
message DisableServiceCollectionResponse {
}
message EnableSSHRequest {
uint64 tailnet_id = 1;
}
message EnableSSHResponse {
}
message DisableSSHRequest {
uint64 tailnet_id = 1;
}
message DisableSSHResponse {
}
+18 -25
View File
@@ -22,13 +22,20 @@ setup_env() {
SUDO=
fi
IONSCALE_VERSION=v0.0.1-preview2
if [ -z "${IONSCALE_DOMAIN}" ]; then
fatal "env variable IONSCALE_DOMAIN is undefined"
fi
if [ -z "${IONSCALE_ACME_EMAIL}" ]; then
fatal "env variable IONSCALE_ACME_EMAIL is undefined"
fi
IONSCALE_VERSION=v0.1.0
IONSCALE_DATA_DIR=/var/lib/ionscale
IONSCALE_CONFIG_DIR=/etc/ionscale
IONSCALE_SERVICE_FILE=/etc/systemd/system/ionscale.service
BIN_DIR=/usr/local/bin
IP=$(curl -sfSL https://checkip.amazonaws.com)
}
# --- set arch and suffix, fatal if architecture not supported ---
@@ -87,43 +94,29 @@ create_folders_and_config() {
$SUDO mkdir --parents ${IONSCALE_CONFIG_DIR}
if [ ! -f "/etc/default/ionscale" ]; then
$SUDO echo "IONSCALE_SYSTEM_ADMIN_KEY=$($BIN_DIR/ionscale genkey | xargs)" > /etc/default/ionscale
$SUDO echo "IONSCALE_KEYS_SYSTEM_ADMIN_KEY=$($BIN_DIR/ionscale genkey -n)" >> /etc/default/ionscale
$SUDO echo "IONSCALE_KEYS_CONTROL_KEY=$($BIN_DIR/ionscale genkey -n)" >> /etc/default/ionscale
$SUDO echo "IONSCALE_KEYS_LEGACY_CONTROL_KEY=$($BIN_DIR/ionscale genkey -n)" >> /etc/default/ionscale
fi
if [ ! -z "${IONSCALE_DOMAIN}" ]; then
$SUDO tee ${IONSCALE_CONFIG_DIR}/config.yaml >/dev/null <<EOF
http_listen_addr: ":80"
https_listen_addr: ":443"
metrics_listen_addr: 127.0.0.1:9090
server_url: "https://${IONSCALE_DOMAIN}"
tls:
cert_magic_domain: ${IONSCALE_DOMAIN}
cert_magic_email: "${IONSCALE_EMAIL}"
cert_magic_storage_path: "${IONSCALE_DATA_DIR}/certmagic"
acme: true
acme_email: "${IONSCALE_ACME_EMAIL}"
acme_path: "${IONSCALE_DATA_DIR}/acme"
database:
type: sqlite
url: "${IONSCALE_DATA_DIR}/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"
url: "${IONSCALE_DATA_DIR}/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)"
logging:
level: info
EOF
else
$SUDO tee ${IONSCALE_CONFIG_DIR}/config.yaml >/dev/null <<EOF
listen_addr: ":8080"
server_url: "http://${IP}:8080"
tls:
disable: true
database:
type: sqlite
url: "${IONSCALE_DATA_DIR}/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"
logging:
level: info
EOF
fi
}
@@ -167,7 +160,7 @@ setup_env
setup_verify_arch
verify_system
install_dependencies
create_folders_and_config
download_and_install
create_folders_and_config
create_systemd_service_file
systemd_enable_and_start