You've already forked ionscale
mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 23:17:49 +01:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 280c626704 | |||
| 57e8eb3a25 | |||
| f8b0eceae7 | |||
| 924ddf1b36 | |||
| 65e446e126 | |||
| 8fe4342571 | |||
| d5a5a924ca | |||
| 442d794189 | |||
| 9483662395 | |||
| 5b9da83c30 | |||
| 776e3de7d8 | |||
| a0e1fcb4aa | |||
| 814335d703 | |||
| 644b99b70f | |||
| 1ab135aa9a | |||
| 4c31c71593 | |||
| d5dd7b1c9d | |||
| 2116b38ae5 | |||
| 0127b027f6 | |||
| a4ae50f20c | |||
| e1f3ad61fb | |||
| a2fd56be89 | |||
| 828e0c920b | |||
| 978b0ecf4f | |||
| c1c708269c | |||
| ed3e1eb54a | |||
| 4a3b5399e6 | |||
| 28c5ff2570 | |||
| 48bd29beba | |||
| eb46fa12ec | |||
| 99aececab2 | |||
| 8e0cc33fd4 | |||
| 4394d44cbd |
@@ -13,14 +13,14 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ts_version:
|
||||
- "v1.64"
|
||||
- "v1.62"
|
||||
- "v1.60"
|
||||
- "v1.58"
|
||||
- "v1.56"
|
||||
- "v1.54"
|
||||
- "v1.52"
|
||||
- "v1.50"
|
||||
- "v1.80"
|
||||
- "v1.78"
|
||||
- "v1.76"
|
||||
- "v1.74"
|
||||
- "v1.72"
|
||||
- "v1.70"
|
||||
- "v1.68"
|
||||
- "v1.66"
|
||||
env:
|
||||
IONSCALE_TESTS_TS_TARGET_VERSION: ${{ matrix.ts_version }}
|
||||
steps:
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
name: Close inactive issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
days-before-issue-stale: 90
|
||||
days-before-issue-close: 7
|
||||
stale-issue-label: "stale"
|
||||
stale-issue-message: "This issue is stale because it has been open for 90 days with no activity."
|
||||
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
|
||||
days-before-pr-stale: -1
|
||||
days-before-pr-close: -1
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} alpine:3.20.0
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} alpine:3.21.3
|
||||
|
||||
COPY ionscale /usr/local/bin/ionscale
|
||||
|
||||
|
||||
@@ -1,71 +1,76 @@
|
||||
module github.com/jsiebens/ionscale
|
||||
|
||||
go 1.22.0
|
||||
go 1.24.2
|
||||
|
||||
require (
|
||||
github.com/99designs/keyring v1.2.2
|
||||
github.com/a-h/templ v0.2.663
|
||||
github.com/a-h/templ v0.3.857
|
||||
github.com/apparentlymart/go-cidr v1.1.0
|
||||
github.com/bufbuild/connect-go v1.10.0
|
||||
github.com/caarlos0/env/v6 v6.10.1
|
||||
github.com/caddyserver/certmagic v0.20.0
|
||||
github.com/coreos/go-oidc/v3 v3.10.0
|
||||
github.com/dustinkirkland/golang-petname v0.0.0-20240422154211-76c06c4bde6b
|
||||
github.com/coreos/go-oidc/v3 v3.14.1
|
||||
github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0
|
||||
github.com/glebarez/sqlite v1.11.0
|
||||
github.com/go-gormigrate/gormigrate/v2 v2.1.2
|
||||
github.com/go-jose/go-jose/v3 v3.0.3
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/go-gormigrate/gormigrate/v2 v2.1.4
|
||||
github.com/go-jose/go-jose/v3 v3.0.4
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2
|
||||
github.com/hashicorp/go-bexpr v0.1.14
|
||||
github.com/hashicorp/go-getter v1.7.4
|
||||
github.com/hashicorp/go-getter v1.7.8
|
||||
github.com/hashicorp/go-hclog v1.6.3
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/imdario/mergo v0.3.16
|
||||
github.com/hashicorp/go-plugin v1.6.3
|
||||
github.com/jsiebens/go-edit v0.1.0
|
||||
github.com/jsiebens/libdns-plugin v0.1.0
|
||||
github.com/jsiebens/mockoidc v0.1.0-rc2
|
||||
github.com/klauspost/compress v1.17.8
|
||||
github.com/labstack/echo-contrib v0.17.1
|
||||
github.com/labstack/echo/v4 v4.12.0
|
||||
github.com/klauspost/compress v1.18.0
|
||||
github.com/labstack/echo-contrib v0.17.3
|
||||
github.com/labstack/echo/v4 v4.13.3
|
||||
github.com/libdns/azure v0.4.0
|
||||
github.com/libdns/cloudflare v0.1.1
|
||||
github.com/libdns/digitalocean v0.0.0-20230728223659-4f9064657aea
|
||||
github.com/libdns/googleclouddns v1.1.0
|
||||
github.com/libdns/libdns v0.2.2
|
||||
github.com/libdns/libdns v0.2.3
|
||||
github.com/libdns/route53 v1.3.3
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/pointerstructure v1.2.1
|
||||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/nleeper/goment v1.4.4
|
||||
github.com/ory/dockertest/v3 v3.10.0
|
||||
github.com/prometheus/client_golang v1.19.0
|
||||
github.com/rodaine/table v1.2.0
|
||||
github.com/ory/dockertest/v3 v3.12.0
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1
|
||||
github.com/rodaine/table v1.3.0
|
||||
github.com/sony/sonyflake v1.2.0
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a
|
||||
github.com/travisjeffery/certmagic-sqlstorage v1.1.1
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.22.0
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/oauth2 v0.19.0
|
||||
golang.org/x/sync v0.7.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
golang.org/x/crypto v0.38.0
|
||||
golang.org/x/net v0.40.0
|
||||
golang.org/x/oauth2 v0.29.0
|
||||
golang.org/x/sync v0.14.0
|
||||
google.golang.org/protobuf v1.36.6
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/postgres v1.5.7
|
||||
gorm.io/gorm v1.25.9
|
||||
gorm.io/driver/postgres v1.5.11
|
||||
gorm.io/gorm v1.26.0
|
||||
gorm.io/plugin/prometheus v0.1.0
|
||||
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a
|
||||
tailscale.com v1.64.2
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
tailscale.com v1.80.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.112.2 // indirect
|
||||
cloud.google.com/go/auth v0.3.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.7 // indirect
|
||||
cloud.google.com/go/storage v1.40.0 // indirect
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
cel.dev/expr v0.23.1 // indirect
|
||||
cloud.google.com/go v0.120.1 // indirect
|
||||
cloud.google.com/go/auth v0.16.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
cloud.google.com/go/iam v1.5.2 // indirect
|
||||
cloud.google.com/go/monitoring v1.24.2 // indirect
|
||||
cloud.google.com/go/storage v1.52.0 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect
|
||||
@@ -74,11 +79,14 @@ require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/akutz/memconn v0.1.0 // indirect
|
||||
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect
|
||||
github.com/aws/aws-sdk-go v1.51.29 // indirect
|
||||
github.com/aws/aws-sdk-go v1.55.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.11 // indirect
|
||||
@@ -99,54 +107,61 @@ require (
|
||||
github.com/bits-and-blooms/bitset v1.13.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/continuity v0.4.3 // indirect
|
||||
github.com/coreos/go-iptables v0.7.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect
|
||||
github.com/coder/websocket v1.8.12 // indirect
|
||||
github.com/containerd/continuity v0.4.5 // indirect
|
||||
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect
|
||||
github.com/danieljoos/wincred v1.2.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dblohm7/wingoes v0.0.0-20240123200102-b75a8a7d7eb0 // indirect
|
||||
github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect
|
||||
github.com/digitalocean/godo v1.113.0 // indirect
|
||||
github.com/docker/cli v26.1.0+incompatible // indirect
|
||||
github.com/docker/docker v26.1.0+incompatible // indirect
|
||||
github.com/docker/cli v27.4.1+incompatible // indirect
|
||||
github.com/docker/docker v27.4.1+incompatible // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/dvsekhvalnov/jose2go v1.7.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
|
||||
github.com/gaissmai/bart v0.4.1 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/gaissmai/bart v0.11.1 // indirect
|
||||
github.com/glebarez/go-sqlite v1.22.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
|
||||
github.com/go-json-experiment/json v0.0.0-20250103232110-6a9a0fde9288 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.1.0 // indirect
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/nftables v0.2.0 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
|
||||
github.com/gorilla/csrf v1.7.2 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
||||
github.com/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||
github.com/hashicorp/go-safetemp v1.0.0 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
|
||||
github.com/illarion/gonotify v1.0.1 // indirect
|
||||
github.com/illarion/gonotify/v2 v2.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
@@ -156,17 +171,15 @@ require (
|
||||
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.1.1-0.20230202152459-5c7d0dd6ab86 // indirect
|
||||
github.com/jsimonetti/rtnetlink v1.4.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/lib/pq v1.10.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mdlayher/genetlink v1.3.2 // indirect
|
||||
github.com/mdlayher/netlink v1.7.2 // indirect
|
||||
github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 // indirect
|
||||
github.com/mdlayher/sdnotify v1.0.0 // indirect
|
||||
github.com/mdlayher/socket v0.5.1 // indirect
|
||||
github.com/mholt/acmez v1.2.0 // indirect
|
||||
@@ -175,73 +188,80 @@ require (
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/sys/user v0.3.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/mtibben/percent v0.2.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/opencontainers/runc v1.1.12 // indirect
|
||||
github.com/opencontainers/runc v1.2.3 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus-community/pro-bing v0.4.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
github.com/prometheus/procfs v0.14.0 // indirect
|
||||
github.com/prometheus/common v0.63.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/safchain/ethtool v0.3.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
|
||||
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect
|
||||
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect
|
||||
github.com/tailscale/golang-x-crypto v0.0.0-20240108194725-7ce1f622c780 // indirect
|
||||
github.com/tailscale/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4 // indirect
|
||||
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect
|
||||
github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85 // indirect
|
||||
github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4 // indirect
|
||||
github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 // indirect
|
||||
github.com/tailscale/wireguard-go v0.0.0-20231121184858-cc193a0b3272 // indirect
|
||||
github.com/tcnksm/go-httpstat v0.2.0 // indirect
|
||||
github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 // indirect
|
||||
github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect
|
||||
github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 // indirect
|
||||
github.com/tailscale/wireguard-go v0.0.0-20250107165329-0b8b35511f19 // indirect
|
||||
github.com/tkuchiki/go-timezone v0.2.3 // indirect
|
||||
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e // indirect
|
||||
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
|
||||
github.com/ulikunitz/xz v0.5.12 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
|
||||
go.opentelemetry.io/otel v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.26.0 // indirect
|
||||
github.com/zeebo/errs v1.4.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect
|
||||
go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect
|
||||
go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 // indirect
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/term v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.20.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/term v0.32.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
|
||||
google.golang.org/api v0.176.1 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240415180920-8c6c420018be // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
|
||||
google.golang.org/grpc v1.63.2 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20240306221502-ee1e1f6070e3 // indirect
|
||||
google.golang.org/api v0.230.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250425173222-7b384671a197 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250425173222-7b384671a197 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9 // indirect
|
||||
google.golang.org/grpc v1.72.1 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20240722211153-64c016c92987 // indirect
|
||||
modernc.org/libc v1.50.3 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.29.8 // indirect
|
||||
nhooyr.io/websocket v1.8.11 // indirect
|
||||
)
|
||||
|
||||
@@ -33,6 +33,7 @@ func machineCommands() *cobra.Command {
|
||||
command.AddCommand(disableExitNodeCommand())
|
||||
command.AddCommand(disableMachineKeyExpiryCommand())
|
||||
command.AddCommand(authorizeMachineCommand())
|
||||
command.AddCommand(setMachineNameCommand())
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -168,6 +169,40 @@ func deleteMachineCommand() *cobra.Command {
|
||||
return command
|
||||
}
|
||||
|
||||
func setMachineNameCommand() *cobra.Command {
|
||||
command, tc := prepareCommand(false, &cobra.Command{
|
||||
Use: "set-name",
|
||||
Short: "Set the name of a given machine",
|
||||
SilenceUsage: true,
|
||||
})
|
||||
|
||||
var machineID uint64
|
||||
var useOSHostname bool
|
||||
var name string
|
||||
command.Flags().Uint64Var(&machineID, "machine-id", 0, "Machine ID")
|
||||
command.Flags().StringVar(&name, "name", "", "New name for the machine")
|
||||
command.Flags().BoolVar(&useOSHostname, "use-os-hostname", false, "Auto-generate from the machine OS hostname")
|
||||
|
||||
_ = command.MarkFlagRequired("machine-id")
|
||||
|
||||
command.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
if !useOSHostname && name == "" {
|
||||
return fmt.Errorf("name is required when not using os hostname")
|
||||
}
|
||||
|
||||
req := api.SetMachineNameRequest{MachineId: machineID, Name: name, UseOsHostname: useOSHostname}
|
||||
if _, err := tc.Client().SetMachineName(cmd.Context(), connect.NewRequest(&req)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Machine name set.")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
func expireMachineCommand() *cobra.Command {
|
||||
command, tc := prepareCommand(false, &cobra.Command{
|
||||
Use: "expire",
|
||||
|
||||
+144
-70
@@ -2,18 +2,19 @@ package config
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"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"
|
||||
"gopkg.in/yaml.v3"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sigs.k8s.io/yaml"
|
||||
"strings"
|
||||
"tailscale.com/tailcfg"
|
||||
tkey "tailscale.com/types/key"
|
||||
"time"
|
||||
@@ -61,6 +62,11 @@ func LoadConfig(path string) (*Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err = expandEnvVars(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(b, cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -73,23 +79,17 @@ func LoadConfig(path string) (*Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// merge env configuration on top of the default/file configuration
|
||||
b, err = expandEnvVars(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(b, cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
envCfg := &Config{}
|
||||
if err := env.Parse(envCfg, env.Options{Prefix: "IONSCALE_"}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 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
|
||||
keepAliveInterval = time.Duration(cfg.PollNet.KeepAliveInterval)
|
||||
magicDNSSuffix = cfg.DNS.MagicDNSSuffix
|
||||
|
||||
if cfg.DNS.Provider.Zone != "" {
|
||||
@@ -117,7 +117,7 @@ func defaultConfig() *Config {
|
||||
AcmeCA: certmagic.LetsEncryptProductionCA,
|
||||
},
|
||||
PollNet: PollNet{
|
||||
KeepAliveInterval: defaultKeepAliveInterval,
|
||||
KeepAliveInterval: Duration(defaultKeepAliveInterval),
|
||||
},
|
||||
DNS: DNS{
|
||||
MagicDNSSuffix: defaultMagicDNSSuffix,
|
||||
@@ -143,21 +143,21 @@ type ServerKeys struct {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
ListenAddr string `yaml:"listen_addr,omitempty" env:"LISTEN_ADDR"`
|
||||
StunListenAddr string `yaml:"stun_listen_addr,omitempty" env:"STUN_LISTEN_ADDR"`
|
||||
MetricsListenAddr string `yaml:"metrics_listen_addr,omitempty" env:"METRICS_LISTEN_ADDR"`
|
||||
PublicAddr string `yaml:"public_addr,omitempty" env:"PUBLIC_ADDR"`
|
||||
StunPublicAddr string `yaml:"stun_public_addr,omitempty" env:"STUN_PUBLIC_ADDR"`
|
||||
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"`
|
||||
DERP DERP `yaml:"derp,omitempty" envPrefix:"DERP_"`
|
||||
Logging Logging `yaml:"logging,omitempty" envPrefix:"LOGGING_"`
|
||||
ListenAddr string `json:"listen_addr,omitempty"`
|
||||
StunListenAddr string `json:"stun_listen_addr,omitempty"`
|
||||
MetricsListenAddr string `json:"metrics_listen_addr,omitempty"`
|
||||
PublicAddr string `json:"public_addr,omitempty"`
|
||||
StunPublicAddr string `json:"stun_public_addr,omitempty"`
|
||||
Tls Tls `json:"tls,omitempty"`
|
||||
PollNet PollNet `json:"poll_net,omitempty"`
|
||||
Keys Keys `json:"keys,omitempty"`
|
||||
Database Database `json:"database,omitempty"`
|
||||
Auth Auth `json:"auth,omitempty"`
|
||||
DNS DNS `json:"dns,omitempty"`
|
||||
DERP DERP `json:"derp,omitempty"`
|
||||
Logging Logging `json:"logging,omitempty"`
|
||||
|
||||
PublicUrl *url.URL `yaml:"-"`
|
||||
PublicUrl *url.URL `json:"-"`
|
||||
|
||||
stunHost string
|
||||
stunPort int
|
||||
@@ -166,79 +166,80 @@ type Config struct {
|
||||
}
|
||||
|
||||
type Tls struct {
|
||||
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"`
|
||||
Disable bool `json:"disable"`
|
||||
ForceHttps bool `json:"force_https"`
|
||||
CertFile string `json:"cert_file,omitempty"`
|
||||
KeyFile string `json:"key_file,omitempty"`
|
||||
AcmeEnabled bool `json:"acme,omitempty"`
|
||||
AcmeEmail string `json:"acme_email,omitempty"`
|
||||
AcmeCA string `json:"acme_ca,omitempty"`
|
||||
}
|
||||
|
||||
type PollNet struct {
|
||||
KeepAliveInterval time.Duration `yaml:"keep_alive_interval" env:"KEEP_ALIVE_INTERVAL"`
|
||||
KeepAliveInterval Duration `json:"keep_alive_interval"`
|
||||
}
|
||||
|
||||
type Logging struct {
|
||||
Level string `yaml:"level,omitempty" env:"LEVEL"`
|
||||
Format string `yaml:"format,omitempty" env:"FORMAT"`
|
||||
File string `yaml:"file,omitempty" env:"FILE"`
|
||||
Level string `json:"level,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
File string `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
type Database struct {
|
||||
Type string `yaml:"type,omitempty" env:"TYPE"`
|
||||
Url string `yaml:"url,omitempty" env:"URL"`
|
||||
MaxOpenConns int `yaml:"max_open_conns,omitempty" env:"MAX_OPEN_CONNS"`
|
||||
MaxIdleConns int `yaml:"max_idle_conns,omitempty" env:"MAX_IDLE_CONNS"`
|
||||
ConnMaxLifetime time.Duration `yaml:"conn_max_life_time,omitempty" env:"CONN_MAX_LIFE_TIME"`
|
||||
ConnMaxIdleTime time.Duration `yaml:"conn_max_idle_time,omitempty" env:"CONN_MAX_IDLE_TIME"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
MaxOpenConns int `json:"max_open_conns,omitempty"`
|
||||
MaxIdleConns int `json:"max_idle_conns,omitempty"`
|
||||
ConnMaxLifetime Duration `json:"conn_max_life_time,omitempty"`
|
||||
ConnMaxIdleTime Duration `json:"conn_max_idle_time,omitempty"`
|
||||
}
|
||||
|
||||
type Keys struct {
|
||||
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"`
|
||||
ControlKey string `json:"control_key,omitempty"`
|
||||
LegacyControlKey string `json:"legacy_control_key,omitempty"`
|
||||
SystemAdminKey string `json:"system_admin_key,omitempty"`
|
||||
}
|
||||
|
||||
type Auth struct {
|
||||
Provider AuthProvider `yaml:"provider,omitempty" envPrefix:"PROVIDER_"`
|
||||
SystemAdminPolicy SystemAdminPolicy `yaml:"system_admins"`
|
||||
Provider AuthProvider `json:"provider,omitempty"`
|
||||
SystemAdminPolicy SystemAdminPolicy `json:"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"`
|
||||
Issuer string `json:"issuer"`
|
||||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
Scopes []string `json:"additional_scopes" `
|
||||
}
|
||||
|
||||
type DNS struct {
|
||||
MagicDNSSuffix string `yaml:"magic_dns_suffix"`
|
||||
Provider DNSProvider `yaml:"provider,omitempty"`
|
||||
MagicDNSSuffix string `json:"magic_dns_suffix"`
|
||||
Provider DNSProvider `json:"provider,omitempty"`
|
||||
}
|
||||
|
||||
type DNSProvider struct {
|
||||
Name string `yaml:"name"`
|
||||
Zone string `yaml:"zone"`
|
||||
Configuration map[string]string `yaml:"config"`
|
||||
Name string `json:"name"`
|
||||
PluginPath string `json:"plugin_path"`
|
||||
Zone string `json:"zone"`
|
||||
Configuration json.RawMessage `json:"config"`
|
||||
}
|
||||
|
||||
type SystemAdminPolicy struct {
|
||||
Subs []string `yaml:"subs,omitempty"`
|
||||
Emails []string `yaml:"emails,omitempty"`
|
||||
Filters []string `yaml:"filters,omitempty"`
|
||||
Subs []string `json:"subs,omitempty"`
|
||||
Emails []string `json:"emails,omitempty"`
|
||||
Filters []string `json:"filters,omitempty"`
|
||||
}
|
||||
|
||||
type DERP struct {
|
||||
Server DERPServer `yaml:"server,omitempty"`
|
||||
Sources []string `yaml:"sources,omitempty"`
|
||||
Server DERPServer `json:"server,omitempty"`
|
||||
Sources []string `json:"sources,omitempty"`
|
||||
}
|
||||
|
||||
type DERPServer struct {
|
||||
Disabled bool `yaml:"disabled,omitempty"`
|
||||
RegionID int `yaml:"region_id,omitempty"`
|
||||
RegionCode string `yaml:"region_code,omitempty"`
|
||||
RegionName string `yaml:"region_name,omitempty"`
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
RegionID int `json:"region_id,omitempty"`
|
||||
RegionCode string `json:"region_code,omitempty"`
|
||||
RegionName string `json:"region_name,omitempty"`
|
||||
}
|
||||
|
||||
func (c *Config) Validate() (*Config, error) {
|
||||
@@ -356,3 +357,76 @@ func (c *Config) DefaultDERPMap() *tailcfg.DERPMap {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Duration time.Duration
|
||||
|
||||
func (d Duration) Std() time.Duration {
|
||||
return time.Duration(d)
|
||||
}
|
||||
|
||||
func (d Duration) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(time.Duration(d).String())
|
||||
}
|
||||
|
||||
func (d *Duration) UnmarshalJSON(b []byte) error {
|
||||
var v interface{}
|
||||
if err := json.Unmarshal(b, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
switch value := v.(type) {
|
||||
case float64:
|
||||
*d = Duration(value)
|
||||
return nil
|
||||
case string:
|
||||
tmp, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*d = Duration(tmp)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("invalid duration")
|
||||
}
|
||||
}
|
||||
|
||||
// Match ${VAR:default} syntax for variables with default values
|
||||
var optionalEnvRegex = regexp.MustCompile(`\${([a-zA-Z0-9_]+):([^}]*)}`)
|
||||
|
||||
// Match ${VAR} syntax (without default) - these are required
|
||||
var requiredEnvRegex = regexp.MustCompile(`\${([a-zA-Z0-9_]+)}`)
|
||||
|
||||
func expandEnvVars(config []byte) ([]byte, error) {
|
||||
var result = config
|
||||
var missingVars []string
|
||||
|
||||
result = optionalEnvRegex.ReplaceAllFunc(result, func(match []byte) []byte {
|
||||
parts := optionalEnvRegex.FindSubmatch(match)
|
||||
envVar := string(parts[1])
|
||||
defaultValue := parts[2]
|
||||
|
||||
envValue := os.Getenv(envVar)
|
||||
if envValue != "" {
|
||||
return []byte(envValue)
|
||||
}
|
||||
return defaultValue
|
||||
})
|
||||
|
||||
result = requiredEnvRegex.ReplaceAllFunc(result, func(match []byte) []byte {
|
||||
parts := requiredEnvRegex.FindSubmatch(match)
|
||||
envVar := string(parts[1])
|
||||
envValue := os.Getenv(envVar)
|
||||
|
||||
if envValue == "" {
|
||||
missingVars = append(missingVars, envVar)
|
||||
return match
|
||||
}
|
||||
|
||||
return []byte(envValue)
|
||||
})
|
||||
|
||||
if len(missingVars) > 0 {
|
||||
return nil, fmt.Errorf("missing required environment variables: %s", strings.Join(missingVars, ", "))
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadConfig(t *testing.T) {
|
||||
// Create a temporary config file
|
||||
tempFile, err := os.CreateTemp("", "config-*.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp file: %v", err)
|
||||
}
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
// Write test configuration
|
||||
yamlContent := `
|
||||
public_addr: "ionscale.localtest.me:443"
|
||||
stun_public_addr: "ionscale.localtest.me:3478"
|
||||
|
||||
database:
|
||||
type: ${DB_TYPE:sqlite}
|
||||
url: ${DB_URL}
|
||||
max_open_conns: ${DB_MAX_OPEN_CONNS:5}
|
||||
conn_max_life_time: ${DB_CONN_MAX_LIFE_TIME:5s}
|
||||
`
|
||||
if _, err := tempFile.Write([]byte(yamlContent)); err != nil {
|
||||
t.Fatalf("Failed to write to temp file: %v", err)
|
||||
}
|
||||
tempFile.Close()
|
||||
|
||||
t.Run("With DB_URL set", func(t *testing.T) {
|
||||
require.NoError(t, os.Setenv("DB_URL", "./ionscale.db"))
|
||||
|
||||
config, err := LoadConfig(tempFile.Name())
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "sqlite", config.Database.Type)
|
||||
require.Equal(t, "./ionscale.db", config.Database.Url)
|
||||
require.Equal(t, 5, config.Database.MaxOpenConns)
|
||||
})
|
||||
|
||||
t.Run("Without required DB_URL", func(t *testing.T) {
|
||||
require.NoError(t, os.Unsetenv("DB_URL"))
|
||||
|
||||
_, err := LoadConfig(tempFile.Name())
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestExpandEnvVars(t *testing.T) {
|
||||
// Setup test environment variables
|
||||
require.NoError(t, os.Setenv("TEST_VAR", "test_value"))
|
||||
require.NoError(t, os.Setenv("PORT", "9090"))
|
||||
|
||||
// Ensure TEST_DEFAULT is not set
|
||||
require.NoError(t, os.Unsetenv("TEST_DEFAULT"))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input []byte
|
||||
expected []byte
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "Braced variable",
|
||||
input: []byte("Port: ${PORT}"),
|
||||
expected: []byte("Port: 9090"),
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Default value used",
|
||||
input: []byte("Default: ${TEST_DEFAULT:fallback}"),
|
||||
expected: []byte("Default: fallback"),
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Default value not used when env var exists",
|
||||
input: []byte("Not default: ${PORT:8080}"),
|
||||
expected: []byte("Not default: 9090"),
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Multiple replacements",
|
||||
input: []byte("Config: ${TEST_VAR} ${PORT} ${TEST_DEFAULT:default}"),
|
||||
expected: []byte("Config: test_value 9090 default"),
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Missing required variable",
|
||||
input: []byte("Required: ${MISSING_VAR}"),
|
||||
expected: nil,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
name: "Mixed variables with one missing",
|
||||
input: []byte("Mixed: ${TEST_VAR} ${MISSING_VAR} ${TEST_DEFAULT:default}"),
|
||||
expected: nil,
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := expandEnvVars(tt.input)
|
||||
|
||||
// Check error expectation
|
||||
if tt.expectError && err == nil {
|
||||
t.Errorf("expandEnvVars() expected error but got none")
|
||||
return
|
||||
}
|
||||
if !tt.expectError && err != nil {
|
||||
t.Errorf("expandEnvVars() got unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// If we expected an error, don't check the result further
|
||||
if tt.expectError {
|
||||
return
|
||||
}
|
||||
|
||||
// Check result
|
||||
if !bytes.Equal(result, tt.expected) {
|
||||
t.Errorf("expandEnvVars() got = %s, want %s", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -25,18 +25,6 @@ func GetString(key, defaultValue string) string {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func GetUint64(key string, defaultValue uint64) uint64 {
|
||||
v := os.Getenv(key)
|
||||
if v != "" {
|
||||
vi, err := strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
return vi
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func validatePublicAddr(addr string) (*url.URL, string, int, error) {
|
||||
scheme := "https"
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/puzpuzpuz/xsync/v3"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -9,35 +10,81 @@ import (
|
||||
type Ping struct{}
|
||||
|
||||
type PollMapSessionManager interface {
|
||||
Register(tailnetID uint64, machineID uint64, ch chan *Ping)
|
||||
Deregister(tailnetID uint64, machineID uint64)
|
||||
Register(tailnetID uint64, machineID uint64, ch chan<- *Ping)
|
||||
Deregister(tailnetID uint64, machineID uint64, ch chan<- *Ping)
|
||||
HasSession(tailnetID uint64, machineID uint64) bool
|
||||
NotifyAll(tailnetID uint64, ignoreMachineIDs ...uint64)
|
||||
}
|
||||
|
||||
func NewPollMapSessionManager() PollMapSessionManager {
|
||||
return &pollMapSessionManager{
|
||||
data: map[uint64]map[uint64]chan *Ping{},
|
||||
timers: map[uint64]*time.Timer{},
|
||||
tailnets: xsync.NewMapOf[uint64, *tailnetSessionManager](),
|
||||
}
|
||||
}
|
||||
|
||||
type pollMapSessionManager struct {
|
||||
sync.RWMutex
|
||||
data map[uint64]map[uint64]chan *Ping
|
||||
timers map[uint64]*time.Timer
|
||||
tailnets *xsync.MapOf[uint64, *tailnetSessionManager]
|
||||
}
|
||||
|
||||
func (n *pollMapSessionManager) Register(tailnetID uint64, machineID uint64, ch chan *Ping) {
|
||||
func (n *pollMapSessionManager) load(tailnetID uint64) *tailnetSessionManager {
|
||||
m, _ := n.tailnets.LoadOrCompute(tailnetID, func() *tailnetSessionManager {
|
||||
return &tailnetSessionManager{
|
||||
targets: make(map[uint64]chan<- *Ping),
|
||||
timers: make(map[uint64]*time.Timer),
|
||||
sessions: xsync.NewMapOf[uint64, bool](),
|
||||
}
|
||||
})
|
||||
return m
|
||||
}
|
||||
|
||||
func (n *pollMapSessionManager) Register(tailnetID uint64, machineID uint64, ch chan<- *Ping) {
|
||||
n.load(tailnetID).Register(machineID, ch)
|
||||
}
|
||||
|
||||
func (n *pollMapSessionManager) Deregister(tailnetID uint64, machineID uint64, ch chan<- *Ping) {
|
||||
n.load(tailnetID).Deregister(machineID, ch)
|
||||
}
|
||||
|
||||
func (n *pollMapSessionManager) HasSession(tailnetID uint64, machineID uint64) bool {
|
||||
return n.load(tailnetID).HasSession(machineID)
|
||||
}
|
||||
|
||||
func (n *pollMapSessionManager) NotifyAll(tailnetID uint64, ignoreMachineIDs ...uint64) {
|
||||
n.load(tailnetID).NotifyAll(ignoreMachineIDs...)
|
||||
}
|
||||
|
||||
type tailnetSessionManager struct {
|
||||
sync.RWMutex
|
||||
targets map[uint64]chan<- *Ping
|
||||
timers map[uint64]*time.Timer
|
||||
sessions *xsync.MapOf[uint64, bool]
|
||||
}
|
||||
|
||||
func (n *tailnetSessionManager) NotifyAll(ignoreMachineIDs ...uint64) {
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
|
||||
for i, p := range n.targets {
|
||||
if !slices.Contains(ignoreMachineIDs, i) {
|
||||
select {
|
||||
case p <- &Ping{}:
|
||||
default: // ignore, channel has a small buffer, failing to insert means there is already a ping pending
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *tailnetSessionManager) Register(machineID uint64, ch chan<- *Ping) {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
|
||||
if ss := n.data[tailnetID]; ss == nil {
|
||||
n.data[tailnetID] = map[uint64]chan *Ping{machineID: ch}
|
||||
} else {
|
||||
ss[machineID] = ch
|
||||
if curr, ok := n.targets[machineID]; ok {
|
||||
close(curr)
|
||||
}
|
||||
|
||||
n.targets[machineID] = ch
|
||||
n.sessions.Store(machineID, true)
|
||||
|
||||
t, ok := n.timers[machineID]
|
||||
if ok {
|
||||
t.Stop()
|
||||
@@ -47,22 +94,25 @@ func (n *pollMapSessionManager) Register(tailnetID uint64, machineID uint64, ch
|
||||
timer := time.NewTimer(5 * time.Second)
|
||||
go func() {
|
||||
<-timer.C
|
||||
if n.HasSession(tailnetID, machineID) {
|
||||
n.NotifyAll(tailnetID, machineID)
|
||||
if n.HasSession(machineID) {
|
||||
n.NotifyAll(machineID)
|
||||
}
|
||||
}()
|
||||
|
||||
n.timers[machineID] = timer
|
||||
}
|
||||
|
||||
func (n *pollMapSessionManager) Deregister(tailnetID uint64, machineID uint64) {
|
||||
func (n *tailnetSessionManager) Deregister(machineID uint64, ch chan<- *Ping) {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
|
||||
if ss := n.data[tailnetID]; ss != nil {
|
||||
delete(ss, machineID)
|
||||
if curr, ok := n.targets[machineID]; ok && curr != ch {
|
||||
return
|
||||
}
|
||||
|
||||
delete(n.targets, machineID)
|
||||
n.sessions.Store(machineID, false)
|
||||
|
||||
t, ok := n.timers[machineID]
|
||||
if ok {
|
||||
t.Stop()
|
||||
@@ -72,36 +122,15 @@ func (n *pollMapSessionManager) Deregister(tailnetID uint64, machineID uint64) {
|
||||
timer := time.NewTimer(10 * time.Second)
|
||||
go func() {
|
||||
<-timer.C
|
||||
if !n.HasSession(tailnetID, machineID) {
|
||||
n.NotifyAll(tailnetID)
|
||||
if !n.HasSession(machineID) {
|
||||
n.NotifyAll()
|
||||
}
|
||||
}()
|
||||
|
||||
n.timers[machineID] = timer
|
||||
}
|
||||
|
||||
func (n *pollMapSessionManager) HasSession(tailnetID uint64, machineID uint64) bool {
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
|
||||
if ss := n.data[tailnetID]; ss != nil {
|
||||
if _, ok := ss[machineID]; ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *pollMapSessionManager) NotifyAll(tailnetID uint64, ignoreMachineIDs ...uint64) {
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
|
||||
if ss := n.data[tailnetID]; ss != nil {
|
||||
for i, p := range ss {
|
||||
if !slices.Contains(ignoreMachineIDs, i) {
|
||||
p <- &Ping{}
|
||||
}
|
||||
}
|
||||
}
|
||||
func (n *tailnetSessionManager) HasSession(machineID uint64) bool {
|
||||
v, ok := n.sessions.Load(machineID)
|
||||
return ok && v
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ func OpenDB(config *config.Database, logger *zap.Logger) (*sql.DB, domain.Reposi
|
||||
|
||||
sqlDB.SetMaxOpenConns(config.MaxOpenConns)
|
||||
sqlDB.SetMaxIdleConns(config.MaxIdleConns)
|
||||
sqlDB.SetConnMaxLifetime(config.ConnMaxLifetime)
|
||||
sqlDB.SetConnMaxIdleTime(config.ConnMaxIdleTime)
|
||||
sqlDB.SetConnMaxLifetime(config.ConnMaxLifetime.Std())
|
||||
sqlDB.SetConnMaxIdleTime(config.ConnMaxIdleTime.Std())
|
||||
|
||||
repository := domain.NewRepository(db)
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package migration
|
||||
|
||||
import (
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func m202502150830_use_hostname() *gormigrate.Migration {
|
||||
return &gormigrate.Migration{
|
||||
ID: "202502150830",
|
||||
Migrate: func(db *gorm.DB) error {
|
||||
type Machine struct {
|
||||
UseOSHostname bool `gorm:"default:true"`
|
||||
}
|
||||
|
||||
if err := db.Migrator().AddColumn(&Machine{}, "UseOSHostname"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Rollback: nil,
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ func Migrations() []*gormigrate.Migration {
|
||||
m202401061400_machine_indeces(),
|
||||
m202402120800_user_last_authenticated(),
|
||||
m202403130830_json_to_text(),
|
||||
m202502150830_use_hostname(),
|
||||
}
|
||||
return migrations
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/hashicorp/go-plugin"
|
||||
"github.com/jsiebens/ionscale/internal/util"
|
||||
dnsplugin "github.com/jsiebens/libdns-plugin"
|
||||
"github.com/libdns/libdns"
|
||||
"go.uber.org/zap"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// pluginManager handles plugin lifecycle and resilience
|
||||
type pluginManager struct {
|
||||
pluginPath string
|
||||
client *plugin.Client
|
||||
instance dnsplugin.Provider
|
||||
lock sync.RWMutex
|
||||
logger *zap.Logger
|
||||
|
||||
zone string
|
||||
config json.RawMessage
|
||||
}
|
||||
|
||||
// NewPluginManager creates a new plugin manager
|
||||
func newPluginManager(pluginPath string, zone string, config json.RawMessage) (*pluginManager, error) {
|
||||
logger := zap.L().Named("dns").With(zap.String("plugin_path", pluginPath))
|
||||
|
||||
p := &pluginManager{
|
||||
pluginPath: pluginPath,
|
||||
logger: logger,
|
||||
zone: zone,
|
||||
config: config,
|
||||
}
|
||||
|
||||
if err := p.ensureRunning(true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ensureRunning makes sure the plugin is running
|
||||
func (pm *pluginManager) ensureRunning(start bool) error {
|
||||
pm.lock.RLock()
|
||||
running := pm.client != nil && !pm.client.Exited()
|
||||
instance := pm.instance
|
||||
pm.lock.RUnlock()
|
||||
|
||||
if running && instance != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Need to restart
|
||||
pm.lock.Lock()
|
||||
defer pm.lock.Unlock()
|
||||
|
||||
if !start {
|
||||
pm.logger.Info("Restarting DNS plugin")
|
||||
}
|
||||
|
||||
if pm.client != nil {
|
||||
pm.client.Kill()
|
||||
}
|
||||
|
||||
// Create a new client
|
||||
cmd := exec.Command(pm.pluginPath)
|
||||
pm.client = plugin.NewClient(&plugin.ClientConfig{
|
||||
HandshakeConfig: dnsplugin.Handshake,
|
||||
Plugins: dnsplugin.PluginMap,
|
||||
Cmd: cmd,
|
||||
AllowedProtocols: []plugin.Protocol{
|
||||
plugin.ProtocolNetRPC,
|
||||
plugin.ProtocolGRPC,
|
||||
},
|
||||
Managed: true,
|
||||
Logger: util.NewZapAdapter(pm.logger, "dns"),
|
||||
})
|
||||
|
||||
// Connect via RPC
|
||||
rpcClient, err := pm.client.Client()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating plugin client: %w", err)
|
||||
}
|
||||
|
||||
// Request the plugin
|
||||
raw, err := rpcClient.Dispense(dnsplugin.ProviderPluginName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error dispensing plugin: %w", err)
|
||||
}
|
||||
|
||||
// Convert to the interface
|
||||
pm.instance = raw.(dnsplugin.Provider)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := pm.instance.Configure(ctx, pm.config); err != nil {
|
||||
return fmt.Errorf("error configuring plugin: %w", err)
|
||||
}
|
||||
|
||||
pm.logger.Info("DNS plugin started")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pm *pluginManager) SetRecord(ctx context.Context, recordType, recordName, value string) error {
|
||||
if err := pm.ensureRunning(false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := pm.instance.SetRecords(ctx, pm.zone, []libdns.Record{{
|
||||
Type: recordType,
|
||||
Name: libdns.RelativeName(recordName, pm.zone),
|
||||
Value: value,
|
||||
TTL: 1 * time.Minute,
|
||||
}})
|
||||
|
||||
return err
|
||||
}
|
||||
+42
-103
@@ -2,20 +2,28 @@ package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/imdario/mergo"
|
||||
"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"
|
||||
"go.uber.org/zap"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var factories = map[string]func() libdns.RecordSetter{
|
||||
"azure": azureProvider,
|
||||
"cloudflare": cloudflareProvider,
|
||||
"digitalocean": digitalOceanProvider,
|
||||
"googleclouddns": googleCloudDNSProvider,
|
||||
"route53": route53Provider,
|
||||
}
|
||||
|
||||
type Provider interface {
|
||||
SetRecord(ctx context.Context, recordType, recordName, value string) error
|
||||
}
|
||||
@@ -26,126 +34,57 @@ func NewProvider(config config.DNS) (Provider, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if p.Name == "" && p.PluginPath == "" {
|
||||
return nil, fmt.Errorf("invalid dns provider configuration, either name or plugin_path should be set")
|
||||
}
|
||||
|
||||
if p.Name != "" && p.PluginPath != "" {
|
||||
return nil, fmt.Errorf("invalid dns provider configuration, only one of name or plugin_path should be set")
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(config.MagicDNSSuffix, p.Zone) {
|
||||
return nil, fmt.Errorf("invalid MagicDNS suffix [%s], not part of zone [%s]", config.MagicDNSSuffix, p.Zone)
|
||||
}
|
||||
|
||||
switch p.Name {
|
||||
case "azure":
|
||||
return configureAzureProvider(p.Zone, p.Configuration)
|
||||
case "cloudflare":
|
||||
return configureCloudflareProvider(p.Zone, p.Configuration)
|
||||
case "digitalocean":
|
||||
return configureDigitalOceanProvider(p.Zone, p.Configuration)
|
||||
case "googleclouddns":
|
||||
return configureGoogleCloudDNSProvider(p.Zone, p.Configuration)
|
||||
case "route53":
|
||||
return configureRoute53Provider(p.Zone, p.Configuration)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown dns provider: %s", p.Name)
|
||||
factory, ok := factories[p.Name]
|
||||
if ok {
|
||||
return newProvider(p.Zone, p.Configuration, factory)
|
||||
}
|
||||
|
||||
return newPluginManager(p.PluginPath, fqdn(p.Zone), p.Configuration)
|
||||
}
|
||||
|
||||
func configureAzureProvider(zone string, values map[string]string) (Provider, error) {
|
||||
p := &azure.Provider{}
|
||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
||||
func newProvider(zone string, values json.RawMessage, factory func() libdns.RecordSetter) (Provider, error) {
|
||||
p := factory()
|
||||
if err := json.Unmarshal(values, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e := &azure.Provider{
|
||||
TenantId: config.GetString("IONSCALE_DNS_AZURE_TENANT_ID", ""),
|
||||
ClientId: config.GetString("IONSCALE_DNS_AZURE_CLIENT_ID", ""),
|
||||
ClientSecret: config.GetString("IONSCALE_DNS_AZURE_CLIENT_SECRET", ""),
|
||||
SubscriptionId: config.GetString("IONSCALE_DNS_AZURE_SUBSCRIPTION_ID", ""),
|
||||
ResourceGroupName: config.GetString("IONSCALE_DNS_AZURE_RESOURCE_GROUP_NAME", ""),
|
||||
}
|
||||
|
||||
// merge env configuration on top of the default/file configuration
|
||||
if err := mergo.Merge(p, e, mergo.WithOverride); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
||||
}
|
||||
|
||||
func configureCloudflareProvider(zone string, values map[string]string) (Provider, error) {
|
||||
p := &cloudflare.Provider{}
|
||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e := &cloudflare.Provider{
|
||||
APIToken: config.GetString("IONSCALE_DNS_CLOUDFLARE_API_TOKEN", ""),
|
||||
}
|
||||
|
||||
// merge env configuration on top of the default/file configuration
|
||||
if err := mergo.Merge(p, e, mergo.WithOverride); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
||||
func azureProvider() libdns.RecordSetter {
|
||||
zap.L().Warn("Builtin azure DNS plugin is deprecated and will be removed in a future release.")
|
||||
return &azure.Provider{}
|
||||
}
|
||||
|
||||
func configureDigitalOceanProvider(zone string, values map[string]string) (Provider, error) {
|
||||
p := &digitalocean.Provider{}
|
||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e := &digitalocean.Provider{
|
||||
APIToken: config.GetString("IONSCALE_DNS_DIGITALOCEAN_API_TOKEN", ""),
|
||||
}
|
||||
|
||||
// merge env configuration on top of the default/file configuration
|
||||
if err := mergo.Merge(p, e, mergo.WithOverride); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
||||
func cloudflareProvider() libdns.RecordSetter {
|
||||
zap.L().Warn("Builtin cloudflare DNS plugin is deprecated and will be removed in a future release.")
|
||||
return &cloudflare.Provider{}
|
||||
}
|
||||
|
||||
func configureGoogleCloudDNSProvider(zone string, values map[string]string) (Provider, error) {
|
||||
p := &googleclouddns.Provider{}
|
||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e := &googleclouddns.Provider{
|
||||
Project: config.GetString("IONSCALE_DNS_GOOGLECLOUDDNS_PROJECT", ""),
|
||||
ServiceAccountJSON: config.GetString("IONSCALE_DNS_GOOGLECLOUDDNS_SERVICE_ACCOUNT_JSON", ""),
|
||||
}
|
||||
|
||||
// merge env configuration on top of the default/file configuration
|
||||
if err := mergo.Merge(p, e, mergo.WithOverride); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
||||
func digitalOceanProvider() libdns.RecordSetter {
|
||||
zap.L().Warn("Builtin digitalocean DNS plugin is deprecated and will be removed in a future release.")
|
||||
return &digitalocean.Provider{}
|
||||
}
|
||||
|
||||
func configureRoute53Provider(zone string, values map[string]string) (Provider, error) {
|
||||
p := &route53.Provider{}
|
||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func googleCloudDNSProvider() libdns.RecordSetter {
|
||||
zap.L().Warn("Builtin googleclouddns DNS plugin is deprecated and will be removed in a future release.")
|
||||
return &googleclouddns.Provider{}
|
||||
}
|
||||
|
||||
e := &route53.Provider{
|
||||
MaxRetries: 0,
|
||||
MaxWaitDur: 0,
|
||||
WaitForPropagation: false,
|
||||
Region: config.GetString("IONSCALE_DNS_ROUTE53_REGION", ""),
|
||||
AWSProfile: config.GetString("IONSCALE_DNS_ROUTE53_AWS_PROFILE", ""),
|
||||
AccessKeyId: config.GetString("IONSCALE_DNS_ROUTE53_ACCESS_KEY_ID", ""),
|
||||
SecretAccessKey: config.GetString("IONSCALE_DNS_ROUTE53_SECRET_ACCESS_KEY", ""),
|
||||
Token: config.GetString("IONSCALE_DNS_ROUTE53_TOKEN", ""),
|
||||
}
|
||||
|
||||
// merge env configuration on top of the default/file configuration
|
||||
if err := mergo.Merge(p, e, mergo.WithOverride); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
||||
func route53Provider() libdns.RecordSetter {
|
||||
zap.L().Warn("Builtin route53 DNS plugin is deprecated and will be removed in a future release.")
|
||||
return &route53.Provider{}
|
||||
}
|
||||
|
||||
type externalProvider struct {
|
||||
|
||||
@@ -164,6 +164,10 @@ func (a ACLPolicy) NodeCapabilities(m *Machine) []tailcfg.NodeCapability {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (alias == AutoGroupMember || alias == AutoGroupMembers) && !m.HasTags() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
@@ -113,6 +113,38 @@ func TestACLPolicy_NodeAttributesWithUserAndTags(t *testing.T) {
|
||||
assert.Equal(t, expectedAttrs, actualAttrs)
|
||||
}
|
||||
|
||||
func TestACLPolicy_NodeAttributesWithAutoGroupMember(t *testing.T) {
|
||||
p1 := createMachine("john@example.com")
|
||||
|
||||
policy := ACLPolicy{
|
||||
ionscale.ACLPolicy{
|
||||
NodeAttrs: []ionscale.ACLNodeAttrGrant{
|
||||
{
|
||||
Target: []string{"autogroup:member"},
|
||||
Attr: []string{
|
||||
"attr1",
|
||||
"attr2",
|
||||
},
|
||||
},
|
||||
{
|
||||
Target: []string{"tag:web"},
|
||||
Attr: []string{
|
||||
"attr3",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
actualAttrs := policy.NodeCapabilities(p1)
|
||||
expectedAttrs := []tailcfg.NodeCapability{
|
||||
tailcfg.NodeCapability("attr1"),
|
||||
tailcfg.NodeCapability("attr2"),
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedAttrs, actualAttrs)
|
||||
}
|
||||
|
||||
func TestACLPolicy_BuildFilterRulesEmptyACL(t *testing.T) {
|
||||
p1 := createMachine("john@example.com")
|
||||
p2 := createMachine("jane@example.com")
|
||||
|
||||
@@ -42,6 +42,7 @@ type Machine struct {
|
||||
Tags Tags
|
||||
KeyExpiryDisabled bool
|
||||
Authorized bool
|
||||
UseOSHostname bool `gorm:"default:true"`
|
||||
|
||||
HostInfo HostInfo
|
||||
Endpoints Endpoints
|
||||
@@ -124,7 +125,7 @@ func (m *Machine) IsAllowedExitNode() bool {
|
||||
}
|
||||
|
||||
func (m *Machine) AdvertisedPrefixes() []string {
|
||||
result := []string{}
|
||||
var result []string
|
||||
for _, r := range m.HostInfo.RoutableIPs {
|
||||
if r.Bits() != 0 {
|
||||
result = append(result, r.String())
|
||||
|
||||
@@ -30,9 +30,9 @@ type TailnetRepository interface {
|
||||
DeleteTailnet(ctx context.Context, id uint64) error
|
||||
}
|
||||
|
||||
func (t Tailnet) GetDERPMap(ctx context.Context, fallack DefaultDERPMap) (*DERPMap, error) {
|
||||
func (t Tailnet) GetDERPMap(ctx context.Context, fallback DefaultDERPMap) (*DERPMap, error) {
|
||||
if t.DERPMap.Checksum == "" {
|
||||
return fallack.GetDERPMap(ctx)
|
||||
return fallback.GetDERPMap(ctx)
|
||||
} else {
|
||||
return &t.DERPMap, nil
|
||||
}
|
||||
|
||||
@@ -482,6 +482,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, form
|
||||
ID: util.NextID(),
|
||||
Name: sanitizeHostname,
|
||||
NameIdx: nameIdx,
|
||||
UseOSHostname: true,
|
||||
MachineKey: machineKey,
|
||||
NodeKey: nodeKey,
|
||||
Ephemeral: ephemeral || req.Ephemeral,
|
||||
@@ -511,7 +512,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, form
|
||||
tags := append(registeredTags, advertisedTags...)
|
||||
|
||||
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
|
||||
if m.Name != sanitizeHostname {
|
||||
if m.UseOSHostname && m.Name != sanitizeHostname {
|
||||
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
|
||||
if err != nil {
|
||||
return logError(err)
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"golang.org/x/net/http2/h2c"
|
||||
"io"
|
||||
"net/http"
|
||||
"tailscale.com/control/controlhttp"
|
||||
"tailscale.com/control/controlhttp/controlhttpserver"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
@@ -27,7 +27,7 @@ func NewNoiseHandlers(controlKey key.MachinePrivate, createPeerHandler CreatePee
|
||||
}
|
||||
|
||||
func (h *NoiseHandlers) Upgrade(c echo.Context) error {
|
||||
conn, err := controlhttp.AcceptHTTP(c.Request().Context(), c.Response(), c.Request(), h.controlKey, nil)
|
||||
conn, err := controlhttpserver.AcceptHTTP(c.Request().Context(), c.Response(), c.Request(), h.controlKey, nil)
|
||||
if err != nil {
|
||||
return logError(err)
|
||||
}
|
||||
|
||||
@@ -11,10 +11,12 @@ import (
|
||||
"github.com/klauspost/compress/zstd"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
"slices"
|
||||
"sync"
|
||||
"tailscale.com/smallzstd"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/util/dnsname"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -81,11 +83,25 @@ func (h *PollNetMapHandler) handlePollNetMap(c echo.Context, m *domain.Machine,
|
||||
}
|
||||
|
||||
if !mapRequest.Stream {
|
||||
if !slices.Equal(m.HostInfo.RoutableIPs, mapRequest.Hostinfo.RoutableIPs) {
|
||||
m.AutoAllowIPs = m.Tailnet.ACLPolicy.Get().FindAutoApprovedIPs(mapRequest.Hostinfo.RoutableIPs, m.Tags, &m.User)
|
||||
}
|
||||
|
||||
m.HostInfo = domain.HostInfo(*mapRequest.Hostinfo)
|
||||
m.DiscoKey = mapRequest.DiscoKey.String()
|
||||
m.Endpoints = mapRequest.Endpoints
|
||||
m.LastSeen = &now
|
||||
|
||||
sanitizeHostname := dnsname.SanitizeHostname(m.HostInfo.Hostname)
|
||||
if m.UseOSHostname && m.Name != sanitizeHostname {
|
||||
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, m.TailnetID, sanitizeHostname)
|
||||
if err != nil {
|
||||
return logError(err)
|
||||
}
|
||||
m.Name = sanitizeHostname
|
||||
m.NameIdx = nameIdx
|
||||
}
|
||||
|
||||
if err := h.repository.SaveMachine(ctx, m); err != nil {
|
||||
return logError(err)
|
||||
}
|
||||
@@ -120,19 +136,21 @@ func (h *PollNetMapHandler) handlePollNetMap(c echo.Context, m *domain.Machine,
|
||||
|
||||
defer func() {
|
||||
connectedDevices.WithLabelValues(m.Tailnet.Name).Dec()
|
||||
h.sessionManager.Deregister(m.TailnetID, m.ID)
|
||||
h.sessionManager.Deregister(m.TailnetID, m.ID, updateChan)
|
||||
keepAliveTicker.Stop()
|
||||
syncTicker.Stop()
|
||||
_ = h.repository.SetMachineLastSeen(ctx, machineID)
|
||||
}()
|
||||
|
||||
var latestSync = time.Now()
|
||||
var latestUpdate = latestSync
|
||||
var shouldUpdate bool = false
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-updateChan:
|
||||
latestUpdate = time.Now()
|
||||
case _, ok := <-updateChan:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
shouldUpdate = true
|
||||
case <-keepAliveTicker.C:
|
||||
if mapRequest.KeepAlive {
|
||||
if _, err := c.Response().Write(keepAliveResponse); err != nil {
|
||||
@@ -142,7 +160,7 @@ func (h *PollNetMapHandler) handlePollNetMap(c echo.Context, m *domain.Machine,
|
||||
c.Response().Flush()
|
||||
}
|
||||
case <-syncTicker.C:
|
||||
if latestSync.Before(latestUpdate) {
|
||||
if shouldUpdate {
|
||||
machine, err := h.repository.GetMachine(ctx, machineID)
|
||||
if err != nil {
|
||||
return logError(err)
|
||||
@@ -165,7 +183,7 @@ func (h *PollNetMapHandler) handlePollNetMap(c echo.Context, m *domain.Machine,
|
||||
}
|
||||
c.Response().Flush()
|
||||
|
||||
latestSync = latestUpdate
|
||||
shouldUpdate = false
|
||||
}
|
||||
case <-notify:
|
||||
return nil
|
||||
|
||||
@@ -86,14 +86,13 @@ func (h *RegistrationHandlers) Register(c echo.Context) error {
|
||||
}
|
||||
|
||||
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
|
||||
if m.Name != sanitizeHostname {
|
||||
if m.UseOSHostname && m.Name != sanitizeHostname {
|
||||
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, m.TailnetID, sanitizeHostname)
|
||||
if err != nil {
|
||||
return logError(err)
|
||||
}
|
||||
m.Name = sanitizeHostname
|
||||
m.NameIdx = nameIdx
|
||||
|
||||
}
|
||||
|
||||
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
|
||||
@@ -124,7 +123,7 @@ func (h *RegistrationHandlers) authenticateMachine(c echo.Context, machineKey st
|
||||
return h.followup(c, req)
|
||||
}
|
||||
|
||||
if req.Auth.AuthKey == "" {
|
||||
if req.Auth == nil || req.Auth.AuthKey == "" {
|
||||
key := util.RandStringBytes(8)
|
||||
authUrl := h.config.CreateUrl("/a/r/%s", key)
|
||||
|
||||
@@ -196,6 +195,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, ma
|
||||
ID: util.NextID(),
|
||||
Name: sanitizeHostname,
|
||||
NameIdx: nameIdx,
|
||||
UseOSHostname: true,
|
||||
MachineKey: machineKey,
|
||||
NodeKey: nodeKey,
|
||||
Ephemeral: authKey.Ephemeral || req.Ephemeral,
|
||||
@@ -225,7 +225,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, ma
|
||||
m.IPv6 = domain.IP{Addr: ipv6}
|
||||
} else {
|
||||
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
|
||||
if m.Name != sanitizeHostname {
|
||||
if m.UseOSHostname && m.Name != sanitizeHostname {
|
||||
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
|
||||
if err != nil {
|
||||
return logError(err)
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/jsiebens/ionscale/internal/domain"
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
func NewUpdateHealthHandlers(machineKey key.MachinePublic, repository domain.Repository) *UpdateFeatureHandlers {
|
||||
return &UpdateFeatureHandlers{machineKey: machineKey, repository: repository}
|
||||
}
|
||||
|
||||
type UpdateFeatureHandlers struct {
|
||||
machineKey key.MachinePublic
|
||||
repository domain.Repository
|
||||
}
|
||||
|
||||
func (h *UpdateFeatureHandlers) UpdateHealth(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
|
||||
req := new(tailcfg.HealthChangeRequest)
|
||||
if err := c.Bind(req); err != nil {
|
||||
return logError(err)
|
||||
}
|
||||
|
||||
machineKey := h.machineKey.String()
|
||||
nodeKey := req.NodeKey.String()
|
||||
|
||||
machine, err := h.repository.GetMachineByKeys(ctx, machineKey, nodeKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if machine == nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest)
|
||||
}
|
||||
|
||||
zap.L().Debug("Health checks updated",
|
||||
zap.Uint64("tailnet", machine.TailnetID),
|
||||
zap.Uint64("machine", machine.ID),
|
||||
zap.String("subsystem", req.Subsys),
|
||||
zap.String("err", req.Error),
|
||||
)
|
||||
|
||||
return c.String(http.StatusOK, "OK")
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package mapping
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/jsiebens/ionscale/internal/config"
|
||||
"github.com/jsiebens/ionscale/internal/domain"
|
||||
@@ -15,19 +14,6 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func CopyViaJson[F any, T any](f F, t T) error {
|
||||
raw, err := json.Marshal(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(raw, t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ToDNSConfig(m *domain.Machine, tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfig {
|
||||
certsEnabled := c.HttpsCertsEnabled && config.DNSProviderConfigured()
|
||||
|
||||
@@ -138,11 +124,14 @@ func ToNode(capVer tailcfg.CapabilityVersion, m *domain.Machine, tailnet *domain
|
||||
allowedIPs = append(allowedIPs, netip.MustParsePrefix("0.0.0.0/0"), netip.MustParsePrefix("::/0"))
|
||||
}
|
||||
|
||||
var derp string
|
||||
var derp int
|
||||
var legacyDerp string
|
||||
if hostinfo.NetInfo != nil {
|
||||
derp = fmt.Sprintf("127.3.3.40:%d", hostinfo.NetInfo.PreferredDERP)
|
||||
derp = hostinfo.NetInfo.PreferredDERP
|
||||
legacyDerp = fmt.Sprintf("127.3.3.40:%d", hostinfo.NetInfo.PreferredDERP)
|
||||
} else {
|
||||
derp = "127.3.3.40:0"
|
||||
derp = 0
|
||||
legacyDerp = "127.3.3.40:0"
|
||||
}
|
||||
|
||||
var name = m.CompleteName()
|
||||
@@ -166,7 +155,8 @@ func ToNode(capVer tailcfg.CapabilityVersion, m *domain.Machine, tailnet *domain
|
||||
Addresses: addrs,
|
||||
AllowedIPs: allowedIPs,
|
||||
Endpoints: endpoints,
|
||||
DERP: derp,
|
||||
HomeDERP: derp,
|
||||
LegacyDERPString: legacyDerp,
|
||||
|
||||
Hostinfo: hostInfo.View(),
|
||||
Created: m.CreatedAt.UTC(),
|
||||
@@ -235,6 +225,7 @@ func ToNode(capVer tailcfg.CapabilityVersion, m *domain.Machine, tailnet *domain
|
||||
|
||||
if m.HasTags() {
|
||||
n.User = tailcfg.UserID(taggedDevicesUser.ID)
|
||||
n.Tags = m.Tags
|
||||
user = tailcfg.UserProfile{
|
||||
ID: tailcfg.UserID(taggedDevicesUser.ID),
|
||||
LoginName: "tagged-devices",
|
||||
@@ -257,9 +248,7 @@ func ToUserProfile(u domain.User) tailcfg.UserProfile {
|
||||
func ToUser(u domain.User) (tailcfg.User, tailcfg.Login) {
|
||||
user := tailcfg.User{
|
||||
ID: tailcfg.UserID(u.ID),
|
||||
LoginName: u.Name,
|
||||
DisplayName: u.Name,
|
||||
Logins: []tailcfg.LoginID{tailcfg.LoginID(u.ID)},
|
||||
}
|
||||
login := tailcfg.Login{
|
||||
ID: tailcfg.LoginID(u.ID),
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/hashicorp/go-plugin"
|
||||
"github.com/jsiebens/ionscale/internal/auth"
|
||||
"github.com/jsiebens/ionscale/internal/config"
|
||||
"github.com/jsiebens/ionscale/internal/core"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"github.com/jsiebens/ionscale/internal/service"
|
||||
"github.com/jsiebens/ionscale/internal/stunserver"
|
||||
"github.com/jsiebens/ionscale/internal/templates"
|
||||
"github.com/jsiebens/ionscale/internal/util"
|
||||
"github.com/labstack/echo-contrib/echoprometheus"
|
||||
"github.com/labstack/echo-contrib/pprof"
|
||||
"github.com/labstack/echo/v4"
|
||||
@@ -53,6 +55,8 @@ func Start(ctx context.Context, c *config.Config) error {
|
||||
return err
|
||||
}
|
||||
|
||||
util.EnsureIDProvider()
|
||||
|
||||
derpMap, err := derp.LoadDERPSources(c)
|
||||
if err != nil {
|
||||
logger.Warn("not all derp sources are read successfully", zap.Error(err))
|
||||
@@ -122,6 +126,7 @@ func Start(ctx context.Context, c *config.Config) error {
|
||||
idTokenHandlers := handlers.NewIDTokenHandlers(machinePublicKey, c, repository)
|
||||
sshActionHandlers := handlers.NewSSHActionHandlers(machinePublicKey, c, repository)
|
||||
queryFeatureHandlers := handlers.NewQueryFeatureHandlers(machinePublicKey, dnsProvider, repository)
|
||||
updateHealthHandlers := handlers.NewUpdateHealthHandlers(machinePublicKey, repository)
|
||||
|
||||
e := echo.New()
|
||||
e.Binder = handlers.JsonBinder{}
|
||||
@@ -134,6 +139,7 @@ func Start(ctx context.Context, c *config.Config) error {
|
||||
e.GET("/machine/ssh/action/:src_machine_id/to/:dst_machine_id/:check_period", sshActionHandlers.StartAuth)
|
||||
e.GET("/machine/ssh/action/check/:key", sshActionHandlers.CheckAuth)
|
||||
e.POST("/machine/feature/query", queryFeatureHandlers.QueryFeature)
|
||||
e.POST("/machine/update-health", updateHealthHandlers.UpdateHealth)
|
||||
|
||||
return e
|
||||
}
|
||||
@@ -216,6 +222,7 @@ func Start(ctx context.Context, c *config.Config) error {
|
||||
go func() {
|
||||
<-gCtx.Done()
|
||||
logger.Sugar().Infow("Shutting down ionscale server")
|
||||
plugin.CleanupClients()
|
||||
shutdownHttpServer(metricsServer)
|
||||
shutdownHttpServer(webServer)
|
||||
_ = stunServer.Shutdown()
|
||||
|
||||
@@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/bufbuild/connect-go"
|
||||
"github.com/jsiebens/ionscale/internal/domain"
|
||||
@@ -59,7 +60,7 @@ func (s *Service) Authenticate(ctx context.Context, req *connect.Request[api.Aut
|
||||
}
|
||||
|
||||
if len(m.Error) != 0 {
|
||||
return connect.NewError(connect.CodePermissionDenied, fmt.Errorf(m.Error))
|
||||
return connect.NewError(connect.CodePermissionDenied, errors.New(m.Error))
|
||||
}
|
||||
|
||||
if err := stream.Send(&api.AuthenticateResponse{AuthUrl: authUrl}); err != nil {
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"tailscale.com/util/dnsname"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -162,6 +164,72 @@ func (s *Service) ExpireMachine(ctx context.Context, req *connect.Request[api.Ex
|
||||
return connect.NewResponse(&api.ExpireMachineResponse{}), nil
|
||||
}
|
||||
|
||||
func (s *Service) SetMachineName(ctx context.Context, req *connect.Request[api.SetMachineNameRequest]) (*connect.Response[api.SetMachineNameResponse], error) {
|
||||
principal := CurrentPrincipal(ctx)
|
||||
|
||||
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
|
||||
if err != nil {
|
||||
return nil, logError(err)
|
||||
}
|
||||
|
||||
if m == nil {
|
||||
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("machine not found"))
|
||||
}
|
||||
|
||||
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(m.TailnetID) {
|
||||
return nil, connect.NewError(connect.CodePermissionDenied, fmt.Errorf("permission denied"))
|
||||
}
|
||||
|
||||
if req.Msg.UseOsHostname {
|
||||
sanitizeHostname := dnsname.SanitizeHostname(m.HostInfo.Hostname)
|
||||
nameIdx, err := s.repository.GetNextMachineNameIndex(ctx, m.TailnetID, sanitizeHostname)
|
||||
if err != nil {
|
||||
return nil, logError(err)
|
||||
}
|
||||
|
||||
m.Name = sanitizeHostname
|
||||
m.NameIdx = nameIdx
|
||||
m.UseOSHostname = true
|
||||
if err := s.repository.SaveMachine(ctx, m); err != nil {
|
||||
return nil, logError(err)
|
||||
}
|
||||
|
||||
s.sessionManager.NotifyAll(m.TailnetID)
|
||||
|
||||
return connect.NewResponse(&api.SetMachineNameResponse{}), nil
|
||||
}
|
||||
|
||||
if strings.TrimSpace(req.Msg.Name) == "" {
|
||||
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("machine name is required when not using os hostname"))
|
||||
}
|
||||
|
||||
sanitizeHostname := dnsname.SanitizeHostname(req.Msg.Name)
|
||||
|
||||
if sanitizeHostname == m.Name {
|
||||
return connect.NewResponse(&api.SetMachineNameResponse{}), nil
|
||||
}
|
||||
|
||||
nameIdx, err := s.repository.GetNextMachineNameIndex(ctx, m.TailnetID, sanitizeHostname)
|
||||
if err != nil {
|
||||
return nil, logError(err)
|
||||
}
|
||||
|
||||
if nameIdx > 0 {
|
||||
return nil, connect.NewError(connect.CodeAlreadyExists, fmt.Errorf("machine name already in use"))
|
||||
}
|
||||
|
||||
m.Name = sanitizeHostname
|
||||
m.NameIdx = 0
|
||||
m.UseOSHostname = false
|
||||
if err := s.repository.SaveMachine(ctx, m); err != nil {
|
||||
return nil, logError(err)
|
||||
}
|
||||
|
||||
s.sessionManager.NotifyAll(m.TailnetID)
|
||||
|
||||
return connect.NewResponse(&api.SetMachineNameResponse{}), nil
|
||||
}
|
||||
|
||||
func (s *Service) AuthorizeMachine(ctx context.Context, req *connect.Request[api.AuthorizeMachineRequest]) (*connect.Response[api.AuthorizeMachineResponse], error) {
|
||||
principal := CurrentPrincipal(ctx)
|
||||
|
||||
|
||||
+46
-8
@@ -1,8 +1,10 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/sony/sonyflake"
|
||||
"go.uber.org/zap"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -11,28 +13,64 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
sf *sonyflake.Sonyflake
|
||||
sf provider
|
||||
sfOnce sync.Once
|
||||
)
|
||||
|
||||
func NextID() uint64 {
|
||||
ensureProvider()
|
||||
id, _ := sf.NextID()
|
||||
EnsureIDProvider()
|
||||
id, err := sf.NextID()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func ensureProvider() {
|
||||
type provider interface {
|
||||
NextID() (uint64, error)
|
||||
}
|
||||
|
||||
type errorProvider struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (e errorProvider) NextID() (uint64, error) {
|
||||
return 0, fmt.Errorf("unable to generate ID, sonyflake not configured properly: %w", e.err)
|
||||
}
|
||||
|
||||
func EnsureIDProvider() {
|
||||
sfOnce.Do(func() {
|
||||
sf = createIDProvider()
|
||||
})
|
||||
}
|
||||
|
||||
func createIDProvider() provider {
|
||||
startTime := time.Date(2022, 05, 01, 00, 0, 0, 0, time.UTC)
|
||||
|
||||
sfInstance, err := sonyflake.New(sonyflake.Settings{
|
||||
MachineID: machineID(),
|
||||
StartTime: time.Date(2022, 05, 01, 00, 0, 0, 0, time.UTC),
|
||||
StartTime: startTime,
|
||||
})
|
||||
|
||||
if err != nil && errors.Is(err, sonyflake.ErrNoPrivateAddress) {
|
||||
id := RandUint16()
|
||||
zap.L().Warn("failed to generate sonyflake machine id from private ip address, using a random machine id", zap.Uint16("id", id))
|
||||
|
||||
sfInstance, err = sonyflake.New(sonyflake.Settings{
|
||||
MachineID: func() (uint16, error) { return id, nil },
|
||||
StartTime: startTime,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
panic("unable to initialize sonyflake: " + err.Error())
|
||||
return errorProvider{err}
|
||||
}
|
||||
}
|
||||
|
||||
sf = sfInstance
|
||||
})
|
||||
if err != nil {
|
||||
return errorProvider{err}
|
||||
}
|
||||
|
||||
return sfInstance
|
||||
}
|
||||
|
||||
func machineID() func() (uint16, error) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
@@ -31,6 +32,15 @@ func RandUint64(n uint64) uint64 {
|
||||
return val.Uint64()
|
||||
}
|
||||
|
||||
func RandUint16() uint16 {
|
||||
var randomBytes [2]byte
|
||||
_, err := rand.Read(randomBytes[:])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return binary.BigEndian.Uint16(randomBytes[:])
|
||||
}
|
||||
|
||||
func RandomBytes(size int) ([]byte, error) {
|
||||
buf := make([]byte, size)
|
||||
if _, err := rand.Read(buf); err != nil {
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
type ZapHCLogAdapter struct {
|
||||
zapLogger *zap.Logger
|
||||
name string
|
||||
}
|
||||
|
||||
func NewZapAdapter(zapLogger *zap.Logger, name string) *ZapHCLogAdapter {
|
||||
return &ZapHCLogAdapter{
|
||||
zapLogger: zapLogger.WithOptions(zap.AddCallerSkip(2)),
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Log(level hclog.Level, msg string, args ...interface{}) {
|
||||
fields := make([]zap.Field, 0, len(args)/2)
|
||||
for i := 0; i < len(args); i += 2 {
|
||||
if i+1 < len(args) {
|
||||
key, ok := args[i].(string)
|
||||
if !ok {
|
||||
key = fmt.Sprintf("%v", args[i])
|
||||
}
|
||||
fields = append(fields, zap.Any(key, args[i+1]))
|
||||
}
|
||||
}
|
||||
|
||||
switch level {
|
||||
case hclog.Trace:
|
||||
z.zapLogger.Debug(msg, fields...)
|
||||
case hclog.Debug:
|
||||
z.zapLogger.Debug(msg, fields...)
|
||||
case hclog.Info:
|
||||
z.zapLogger.Info(msg, fields...)
|
||||
case hclog.Warn:
|
||||
z.zapLogger.Warn(msg, fields...)
|
||||
case hclog.Error:
|
||||
z.zapLogger.Error(msg, fields...)
|
||||
}
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Trace(msg string, args ...interface{}) {
|
||||
z.Log(hclog.Trace, msg, args...)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Debug(msg string, args ...interface{}) {
|
||||
z.Log(hclog.Debug, msg, args...)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Info(msg string, args ...interface{}) {
|
||||
z.Log(hclog.Info, msg, args...)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Warn(msg string, args ...interface{}) {
|
||||
z.Log(hclog.Warn, msg, args...)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Error(msg string, args ...interface{}) {
|
||||
z.Log(hclog.Error, msg, args...)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) IsTrace() bool {
|
||||
return z.zapLogger.Core().Enabled(zapcore.DebugLevel)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) IsDebug() bool {
|
||||
return z.zapLogger.Core().Enabled(zapcore.DebugLevel)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) IsInfo() bool {
|
||||
return z.zapLogger.Core().Enabled(zapcore.InfoLevel)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) IsWarn() bool {
|
||||
return z.zapLogger.Core().Enabled(zapcore.WarnLevel)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) IsError() bool {
|
||||
return z.zapLogger.Core().Enabled(zapcore.ErrorLevel)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) ImpliedArgs() []interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) With(args ...interface{}) hclog.Logger {
|
||||
if len(args) == 0 {
|
||||
return z
|
||||
}
|
||||
|
||||
fields := make([]zap.Field, 0, len(args)/2)
|
||||
for i := 0; i < len(args); i += 2 {
|
||||
if i+1 < len(args) {
|
||||
key, ok := args[i].(string)
|
||||
if !ok {
|
||||
key = fmt.Sprintf("%v", args[i])
|
||||
}
|
||||
fields = append(fields, zap.Any(key, args[i+1]))
|
||||
}
|
||||
}
|
||||
|
||||
newLogger := z.zapLogger.With(fields...)
|
||||
return &ZapHCLogAdapter{
|
||||
zapLogger: newLogger,
|
||||
}
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Name() string {
|
||||
return z.name
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Named(name string) hclog.Logger {
|
||||
return &ZapHCLogAdapter{zapLogger: z.zapLogger.Named(name), name: name}
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) ResetNamed(name string) hclog.Logger {
|
||||
return &ZapHCLogAdapter{
|
||||
zapLogger: z.zapLogger,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) SetLevel(level hclog.Level) {
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) GetLevel() hclog.Level {
|
||||
return hclog.LevelFromString(z.zapLogger.Level().String())
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) StandardLogger(opts *hclog.StandardLoggerOptions) *log.Logger {
|
||||
return log.New(z, "", log.LstdFlags)
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) StandardWriter(opts *hclog.StandardLoggerOptions) io.Writer {
|
||||
return z
|
||||
}
|
||||
|
||||
func (z *ZapHCLogAdapter) Write(p []byte) (n int, err error) {
|
||||
s := strings.TrimSpace(string(p))
|
||||
z.Info(s)
|
||||
return len(p), nil
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
# Configuring authentication with OIDC
|
||||
|
||||
While ionscale can operate without an OIDC (OpenID Connect) provider using only static keys, configuring an OIDC provider is highly recommended for enhanced security, user management, and a smoother administrative experience.
|
||||
|
||||
## Why configure an OIDC provider?
|
||||
|
||||
Without an OIDC provider, ionscale operates in a key-only mode:
|
||||
|
||||
- System administrators can only use the system admin key for administrative tasks
|
||||
- Tailscale devices can only connect using [tags](https://tailscale.com/kb/1068/tags) and [pre-authentication keys](https://tailscale.com/kb/1085/auth-keys)
|
||||
- No user accounts or user-specific permissions are available
|
||||
|
||||
With an OIDC provider configured:
|
||||
|
||||
- Users can authenticate using their existing identity provider credentials
|
||||
- Administrators can assign specific permissions to users
|
||||
- System administration can be delegated to specific users
|
||||
- Fine-grained access control based on user identity becomes possible
|
||||
- More seamless user experience with browser-based authentication
|
||||
|
||||
## Supported OIDC providers
|
||||
|
||||
ionscale supports any standard OIDC provider, including:
|
||||
|
||||
- Google Workspace
|
||||
- Auth0
|
||||
- Okta
|
||||
- Azure AD / Microsoft Entra ID
|
||||
- Keycloak
|
||||
- GitLab
|
||||
- GitHub (OAuth 2.0 with OIDC extensions)
|
||||
- And many others
|
||||
|
||||
## Basic OIDC configuration
|
||||
|
||||
To configure an OIDC provider, update your ionscale configuration file (`config.yaml`) with the following settings:
|
||||
|
||||
```yaml
|
||||
auth:
|
||||
provider:
|
||||
# OIDC issuer URL where ionscale can find the OpenID Provider Configuration Document
|
||||
issuer: "https://your-oidc-provider.com"
|
||||
# OIDC client ID and secret
|
||||
client_id: "your-client-id"
|
||||
client_secret: "your-client-secret"
|
||||
# Optional: additional OIDC scopes used in the OIDC flow
|
||||
additional_scopes: "groups"
|
||||
```
|
||||
|
||||
### Required configuration fields
|
||||
|
||||
- `issuer`: The URL to your OIDC provider's issuer. This URL is used to discover your provider's endpoints.
|
||||
- `client_id`: The client ID from your OIDC provider application registration.
|
||||
- `client_secret`: The client secret from your OIDC provider application registration.
|
||||
|
||||
### Optional configuration
|
||||
|
||||
- `additional_scopes`: A space-separated list of additional OAuth scopes to request during authentication.
|
||||
By default, ionscale requests the `openid`, `email`, and `profile` scopes.
|
||||
|
||||
## Configuring your OIDC provider
|
||||
|
||||
When registering ionscale with your OIDC provider, you'll need to configure the following:
|
||||
|
||||
**Redirect URI**: Set to `https://your-ionscale-domain.com/auth/callback`
|
||||
|
||||
## System administrator access
|
||||
|
||||
With OIDC configured, you'll want to specify which users have system administrator privileges.
|
||||
This is done in the `auth.system_admins` section of your configuration:
|
||||
|
||||
```yaml
|
||||
auth:
|
||||
# Configuration from previous section...
|
||||
|
||||
system_admins:
|
||||
# By email address
|
||||
emails:
|
||||
- "admin@example.com"
|
||||
- "secadmin@example.com"
|
||||
|
||||
# By subject identifier (sub claim from OIDC)
|
||||
subs:
|
||||
- "user|123456"
|
||||
|
||||
# By attribute expression (using BEXPR syntax)
|
||||
filters:
|
||||
- "token.groups contains \"admin\""
|
||||
- "domain == \"admin.example.com\""
|
||||
```
|
||||
|
||||
You can use one or more of these methods to designate system administrators:
|
||||
|
||||
1. **By Email**: List specific email addresses that should have admin privileges.
|
||||
2. **By Subject ID**: List specific user IDs (the `sub` claim from your OIDC provider).
|
||||
3. **By Expression**: Use BEXPR filters to determine admin status based on token claims.
|
||||
|
||||
## OIDC authentication flow
|
||||
|
||||
When a user attempts to authenticate with ionscale:
|
||||
|
||||
1. The user is redirected to the OIDC provider's login page.
|
||||
2. After successful authentication, the user is redirected back to ionscale.
|
||||
3. ionscale verifies the authentication and checks if:
|
||||
- The user is a system administrator (based on the `system_admins` configuration).
|
||||
- The user has access to any tailnets (based on IAM policies configured for individual tailnets).
|
||||
|
||||
## Provider-specific setup instructions
|
||||
|
||||
### Google
|
||||
|
||||
1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
|
||||
2. Create a new project or select an existing one.
|
||||
3. Navigate to "APIs & Services" > "Credentials".
|
||||
4. Click "Create Credentials" > "OAuth client ID".
|
||||
5. Select "Web application" as the application type.
|
||||
6. Add `https://your-ionscale-domain.com/auth/callback` as an authorized redirect URI.
|
||||
7. Copy the client ID and client secret.
|
||||
|
||||
Configure ionscale:
|
||||
```yaml
|
||||
auth:
|
||||
provider:
|
||||
issuer: "https://accounts.google.com"
|
||||
client_id: "your-client-id.apps.googleusercontent.com"
|
||||
client_secret: "your-client-secret"
|
||||
```
|
||||
|
||||
### Auth0
|
||||
|
||||
1. Go to the [Auth0 Dashboard](https://manage.auth0.com/).
|
||||
2. Create a new application or select an existing one of type "Regular Web Application".
|
||||
3. Under "Settings", configure:
|
||||
- Allowed Callback URLs: `https://your-ionscale-domain.com/auth/callback`
|
||||
4. Copy the Domain, Client ID, and Client Secret.
|
||||
|
||||
Configure ionscale:
|
||||
```yaml
|
||||
auth:
|
||||
provider:
|
||||
issuer: "https://your-tenant.auth0.com/"
|
||||
client_id: "your-client-id"
|
||||
client_secret: "your-client-secret"
|
||||
```
|
||||
|
||||
### Microsoft Azure AD / Entra ID
|
||||
|
||||
1. Go to the [Azure Portal](https://portal.azure.com/).
|
||||
2. Navigate to "Azure Active Directory" > "App registrations".
|
||||
3. Create a new registration.
|
||||
4. Add `https://your-ionscale-domain.com/auth/callback` as a redirect URI of type "Web".
|
||||
5. Under "Certificates & secrets", create a new client secret.
|
||||
6. Copy the Application (client) ID and the new secret.
|
||||
|
||||
Configure ionscale:
|
||||
```yaml
|
||||
auth:
|
||||
provider:
|
||||
issuer: "https://login.microsoftonline.com/your-tenant-id/v2.0"
|
||||
client_id: "your-client-id"
|
||||
client_secret: "your-client-secret"
|
||||
additional_scopes: "offline_access"
|
||||
```
|
||||
|
||||
## Complete configuration example
|
||||
|
||||
```yaml
|
||||
auth:
|
||||
provider:
|
||||
issuer: "https://accounts.google.com"
|
||||
client_id: "your-client-id.apps.googleusercontent.com"
|
||||
client_secret: "your-client-secret"
|
||||
additional_scopes: "groups"
|
||||
|
||||
system_admins:
|
||||
emails:
|
||||
- "admin@example.com"
|
||||
filters:
|
||||
- "domain == \"example.com\" && token.groups contains \"admin\""
|
||||
```
|
||||
|
||||
## OIDC without system admin
|
||||
|
||||
If you've configured OIDC but no system administrators, you can still use the system admin key from your initial setup for administrative tasks:
|
||||
|
||||
```bash
|
||||
export IONSCALE_ADDR="https://your-ionscale-domain.com"
|
||||
export IONSCALE_SYSTEM_ADMIN_KEY="your-system-admin-key"
|
||||
ionscale tailnet list
|
||||
```
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
# DERP Configuration
|
||||
|
||||
DERP (Designated Encrypted Relay for Packets) servers are relay servers that help Tailscale clients establish connections when direct connections aren't possible due to NAT, firewalls, or other network impediments. ionscale provides flexible DERP configuration options to support various deployment scenarios.
|
||||
|
||||
## Embedded DERP Server
|
||||
|
||||
ionscale includes a built-in DERP server that is enabled by default. This provides an out-of-the-box relay solution without requiring additional infrastructure.
|
||||
|
||||
### Configuration
|
||||
|
||||
The embedded DERP server can be configured in your ionscale configuration file:
|
||||
|
||||
```yaml
|
||||
derp:
|
||||
server:
|
||||
disabled: false # Set to true to disable the embedded DERP server
|
||||
region_id: 1000 # The region ID for the embedded DERP server
|
||||
region_code: "ionscale" # The region code (short name)
|
||||
region_name: "ionscale Embedded DERP" # Human-readable region name
|
||||
```
|
||||
|
||||
Additional networking parameters that affect the DERP server:
|
||||
|
||||
```yaml
|
||||
# The HTTP(S) listen address for the control plane (also used for DERP)
|
||||
listen_addr: ":8080"
|
||||
|
||||
# The STUN listen address when using the embedded DERP
|
||||
stun_listen_addr: ":3478"
|
||||
|
||||
# The DNS name of the server HTTP(S) endpoint as accessible by clients
|
||||
public_addr: "ionscale.example.com:443"
|
||||
|
||||
# The DNS name of the STUN endpoint as accessible by clients
|
||||
stun_public_addr: "ionscale.example.com:3478"
|
||||
```
|
||||
|
||||
!!! important
|
||||
For the embedded DERP server to function properly, clients must be able to reach your ionscale server at the configured `public_addr` and `stun_public_addr`. Ensure these addresses are publicly accessible and have the appropriate ports open in your firewall.
|
||||
|
||||
## External DERP Sources
|
||||
|
||||
In addition to or instead of the embedded DERP server, ionscale can use external DERP servers. This is useful for:
|
||||
|
||||
- Using Tailscale's global DERP infrastructure
|
||||
- Setting up your own geographically distributed DERP servers
|
||||
- Optimizing connection paths for globally distributed teams
|
||||
|
||||
To configure external DERP sources:
|
||||
|
||||
```yaml
|
||||
derp:
|
||||
sources:
|
||||
- https://controlplane.tailscale.com/derpmap/default # Tailscale's default DERP map
|
||||
- https://example.com/my-custom-derpmap.json # Custom DERP map
|
||||
- git::https://github.com/example/derpmap//config.json # From a git repository
|
||||
- file:///etc/ionscale/derpmaps/custom.json # From a local file
|
||||
```
|
||||
|
||||
The `derp.sources` field accepts a list of URLs that point to JSON files containing DERP map configurations. These sources are loaded at server startup and merged with the embedded DERP configuration (if enabled).
|
||||
|
||||
!!! info "Source locations"
|
||||
ionscale uses HashiCorp's [go-getter](https://github.com/hashicorp/go-getter) library to fetch external sources, which supports multiple protocols and source types:
|
||||
|
||||
- **HTTP/HTTPS**: `https://example.com/derpmap.json`
|
||||
- **Local files**: `file:///path/to/derpmap.json`
|
||||
- **Git repositories**: `git::https://github.com/user/repo//path/to/file.json`
|
||||
- **S3 buckets**: `s3::https://s3.amazonaws.com/bucket/derpmap.json`
|
||||
- **GCS buckets**: `gcs::https://www.googleapis.com/storage/v1/bucket/derpmap.json`
|
||||
|
||||
This flexibility allows you to store and manage your DERP maps in various locations based on your organization's needs.
|
||||
|
||||
!!! note
|
||||
At the time of writing, ionscale only loads external DERP sources at startup and does not automatically poll them for changes. To apply changes to external DERP sources, you will need to restart the ionscale server.
|
||||
|
||||
## Instance and Tailnet DERP Configuration
|
||||
|
||||
ionscale provides a flexible DERP configuration model:
|
||||
|
||||
### Default Instance Configuration
|
||||
|
||||
By default, all tailnets use the DERP map defined at the instance level, which includes:
|
||||
|
||||
- The embedded DERP server (if enabled)
|
||||
- Any external DERP sources configured in your ionscale configuration file
|
||||
|
||||
You can view the instance-level DERP map with:
|
||||
|
||||
```bash
|
||||
ionscale system get-derp-map [--json]
|
||||
```
|
||||
|
||||
### Tailnet-Specific Configuration
|
||||
|
||||
Each tailnet can be configured with its own custom DERP map. This gives you the flexibility to:
|
||||
|
||||
- Provide optimized DERP configurations for teams in different regions
|
||||
- Test new DERP setups on specific tailnets before broader deployment
|
||||
- Create specialized network paths for particular use cases
|
||||
|
||||
When a tailnet doesn't have a custom DERP map configured, it automatically uses the instance's default DERP map.
|
||||
|
||||
Managing tailnet-specific DERP maps:
|
||||
|
||||
```bash
|
||||
# View a tailnet's current DERP map
|
||||
ionscale tailnets get-derp-map --tailnet <tailnet-id> [--json]
|
||||
|
||||
# Set a custom DERP map for a specific tailnet
|
||||
ionscale tailnets set-derp-map --tailnet <tailnet-id> --file <derpmap.json>
|
||||
|
||||
# Remove the custom configuration and revert to the instance default
|
||||
ionscale tailnets reset-derp-map --tailnet <tailnet-id>
|
||||
```
|
||||
|
||||
## Creating Custom DERP Maps
|
||||
|
||||
A DERP map is a JSON structure containing regions and nodes. Here's an example:
|
||||
|
||||
```json
|
||||
{
|
||||
"Regions": {
|
||||
"1": {
|
||||
"RegionID": 1,
|
||||
"RegionCode": "nyc",
|
||||
"RegionName": "New York City",
|
||||
"Nodes": [
|
||||
{
|
||||
"Name": "1a",
|
||||
"RegionID": 1,
|
||||
"HostName": "derp1.example.com",
|
||||
"DERPPort": 443,
|
||||
"STUNPort": 3478
|
||||
}
|
||||
]
|
||||
},
|
||||
"2": {
|
||||
"RegionID": 2,
|
||||
"RegionCode": "sfo",
|
||||
"RegionName": "San Francisco",
|
||||
"Nodes": [
|
||||
{
|
||||
"Name": "2a",
|
||||
"RegionID": 2,
|
||||
"HostName": "derp2.example.com",
|
||||
"DERPPort": 443,
|
||||
"STUNPort": 3478
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Important fields:
|
||||
|
||||
- `RegionID`: A unique identifier for the region (1-999 for custom regions, 1000+ reserved for ionscale)
|
||||
- `RegionCode`: A short code for the region (e.g., "nyc", "sfo")
|
||||
- `RegionName`: A human-readable name for the region
|
||||
- `Nodes`: A list of DERP servers in the region
|
||||
- `Name`: A unique name for the node within the region
|
||||
- `HostName`: The DNS name of the DERP server
|
||||
- `DERPPort`: The port for DERP traffic (typically 443)
|
||||
- `STUNPort`: The port for STUN traffic (typically 3478)
|
||||
|
||||
To apply a custom DERP map to a tailnet:
|
||||
|
||||
```bash
|
||||
# Create the DERP map file
|
||||
cat > my-derpmap.json <<EOF
|
||||
{
|
||||
"Regions": {
|
||||
"1": {
|
||||
"RegionID": 1,
|
||||
"RegionCode": "custom",
|
||||
"RegionName": "My Custom DERP",
|
||||
"Nodes": [
|
||||
{
|
||||
"Name": "derp1",
|
||||
"RegionID": 1,
|
||||
"HostName": "derp.example.com",
|
||||
"DERPPort": 443,
|
||||
"STUNPort": 3478
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Apply it to a tailnet
|
||||
ionscale tailnets set-derp-map --tailnet <tailnet-id> --file my-derpmap.json
|
||||
```
|
||||
|
||||
!!! tip
|
||||
DERP servers primarily help with establishing connections when direct peer-to-peer connections aren't possible. Having DERP servers geographically close to your users can improve connection establishment times and provide better fallback performance.
|
||||
|
||||
!!! note
|
||||
Changes to DERP maps are automatically distributed to clients during their regular polling. There's no need to manually update clients when changing DERP configurations.
|
||||
@@ -0,0 +1,244 @@
|
||||
# Configuring DNS providers
|
||||
|
||||
ionscale supports integration with various DNS providers to enable Tailscale's HTTPS certificate functionality. When a DNS provider is properly configured, ionscale can automatically manage TXT records required for the DNS-01 challenge when requesting certificates.
|
||||
|
||||
## Why configure a DNS provider
|
||||
|
||||
While not strictly required for basic ionscale operation, configuring a DNS provider enables important Tailscale features:
|
||||
|
||||
1. **Tailscale HTTPS Certificates**: Allows nodes to receive valid HTTPS certificates for their Tailscale hostnames, enabling secure web services within your tailnet.
|
||||
2. **Tailscale Serve**: Supports the `tailscale serve` feature, which allows users to easily share web services with proper HTTPS.
|
||||
|
||||
Without a configured DNS provider, these features will not be available to your users.
|
||||
|
||||
## Supported DNS providers
|
||||
|
||||
ionscale supports DNS providers through two methods:
|
||||
|
||||
### Built-in providers (deprecated)
|
||||
|
||||
ionscale includes built-in support for the following DNS providers using [libdns](https://github.com/libdns) libraries:
|
||||
|
||||
- [Azure DNS](https://github.com/libdns/azure)
|
||||
- [Cloudflare](https://github.com/libdns/cloudflare)
|
||||
- [DigitalOcean](https://github.com/libdns/digitalocean)
|
||||
- [Google Cloud DNS](https://github.com/libdns/googleclouddns)
|
||||
- [Amazon Route 53](https://github.com/libdns/route53)
|
||||
|
||||
!!! warning "Built-in providers are deprecated"
|
||||
The built-in DNS providers are deprecated and will be removed in a future release. Please migrate to external DNS plugins for continued support.
|
||||
|
||||
### External DNS plugins (recommended)
|
||||
|
||||
ionscale now supports external DNS plugins through a plugin system. This allows for:
|
||||
|
||||
- **Extensibility**: Add support for any DNS provider without modifying ionscale
|
||||
- **Maintainability**: Plugins are maintained independently
|
||||
- **Flexibility**: Plugin configuration specific to each provider's needs
|
||||
|
||||
!!! info "Plugin availability"
|
||||
External DNS plugins implement the [libdns-plugin](https://github.com/libdns/libdns-plugin) interface. Official plugin implementations can be found in the [ionscale GitHub organization](https://github.com/ionscale) with repositories named `ionscale-<provider>-dns`. You can also create your own following the plugin specification.
|
||||
|
||||
## DNS provider configuration
|
||||
|
||||
To configure a DNS provider, add the appropriate settings to your ionscale configuration file (`config.yaml`):
|
||||
|
||||
### Built-in provider configuration
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
# The base domain for MagicDNS FQDN hostnames
|
||||
magic_dns_suffix: "ionscale.net"
|
||||
|
||||
# DNS provider configuration for HTTPS certificates
|
||||
provider:
|
||||
# Name of your DNS provider
|
||||
name: "cloudflare"
|
||||
# The DNS zone to use (typically your domain name)
|
||||
zone: "example.com"
|
||||
# Provider-specific configuration (varies by provider)
|
||||
config:
|
||||
# Provider-specific credentials and settings go here
|
||||
# See provider-specific examples below
|
||||
```
|
||||
|
||||
### External plugin configuration
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
# The base domain for MagicDNS FQDN hostnames
|
||||
magic_dns_suffix: "ionscale.net"
|
||||
|
||||
# DNS provider configuration for HTTPS certificates
|
||||
provider:
|
||||
# Path to your DNS plugin executable
|
||||
plugin_path: "/path/to/your/dns-plugin"
|
||||
# The DNS zone to use (typically your domain name)
|
||||
zone: "example.com"
|
||||
# Plugin-specific configuration (varies by plugin)
|
||||
config:
|
||||
# Plugin-specific credentials and settings go here
|
||||
# See plugin documentation for configuration options
|
||||
```
|
||||
|
||||
### Important requirements
|
||||
|
||||
1. The `magic_dns_suffix` must be a subdomain of the provider's zone (or the zone itself).
|
||||
2. MagicDNS must be enabled for the tailnet to use HTTPS certificates.
|
||||
3. You must have administrative access to the DNS zone to configure the provider.
|
||||
4. For external plugins, the plugin executable must be accessible and executable by the ionscale process.
|
||||
|
||||
## Provider-specific examples
|
||||
|
||||
### Cloudflare
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
magic_dns_suffix: "ts.example.com"
|
||||
provider:
|
||||
name: "cloudflare"
|
||||
zone: "example.com"
|
||||
config:
|
||||
api_token: "your-cloudflare-api-token"
|
||||
```
|
||||
|
||||
For Cloudflare, create an API token with the "Edit" permission for "Zone:DNS".
|
||||
|
||||
### Azure DNS
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
magic_dns_suffix: "ts.example.com"
|
||||
provider:
|
||||
name: "azure"
|
||||
zone: "example.com"
|
||||
config:
|
||||
tenant_id: "your-tenant-id"
|
||||
client_id: "your-client-id"
|
||||
client_secret: "your-client-secret"
|
||||
subscription_id: "your-subscription-id"
|
||||
resource_group_name: "your-resource-group"
|
||||
```
|
||||
|
||||
For Azure, create a service principal with "DNS Zone Contributor" role for your DNS zone's resource group.
|
||||
|
||||
### Amazon Route 53
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
magic_dns_suffix: "ts.example.com"
|
||||
provider:
|
||||
name: "route53"
|
||||
zone: "example.com"
|
||||
config:
|
||||
access_key_id: "your-access-key-id"
|
||||
secret_access_key: "your-secret-access-key"
|
||||
# Optional region, defaults to us-east-1
|
||||
region: "us-east-1"
|
||||
...
|
||||
```
|
||||
|
||||
For AWS Route 53, create an IAM user with permissions to modify records in your hosted zone.
|
||||
|
||||
### Google Cloud DNS
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
magic_dns_suffix: "ts.example.com"
|
||||
provider:
|
||||
name: "googleclouddns"
|
||||
zone: "example-com" # Note: GCP uses zone names without dots
|
||||
config:
|
||||
gcp_project: "your-project-id"
|
||||
# Optional path to a service account key file
|
||||
# gcp_application_default: "/path/to/service-account-key.json"
|
||||
```
|
||||
|
||||
For Google Cloud DNS, create a service account with the "DNS Administrator" role.
|
||||
|
||||
### DigitalOcean
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
magic_dns_suffix: "ts.example.com"
|
||||
provider:
|
||||
name: "digitalocean"
|
||||
zone: "example.com"
|
||||
config:
|
||||
auth_token: "your-digitalocean-api-token"
|
||||
```
|
||||
|
||||
For DigitalOcean, create an API token with read and write access.
|
||||
|
||||
## External DNS plugin examples
|
||||
|
||||
### Using a hypothetical Cloudflare plugin
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
magic_dns_suffix: "ts.example.com"
|
||||
provider:
|
||||
plugin_path: "/usr/local/bin/libdns-cloudflare-plugin"
|
||||
zone: "example.com"
|
||||
config:
|
||||
api_token: "your-cloudflare-api-token"
|
||||
```
|
||||
|
||||
### Using a custom DNS plugin
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
magic_dns_suffix: "ts.example.com"
|
||||
provider:
|
||||
plugin_path: "/opt/dns-plugins/my-custom-provider"
|
||||
zone: "example.com"
|
||||
config:
|
||||
# Configuration specific to your custom plugin
|
||||
endpoint: "https://api.mydnsprovider.com"
|
||||
api_key: "your-api-key"
|
||||
custom_setting: "value"
|
||||
```
|
||||
|
||||
!!! tip "Plugin development"
|
||||
To create your own DNS plugin, implement the [libdns-plugin](https://github.com/libdns/libdns-plugin) interface. The plugin system uses HashiCorp's go-plugin framework for communication between ionscale and your plugin.
|
||||
|
||||
## Enabling HTTPS certificates for a tailnet
|
||||
|
||||
After configuring a DNS provider in your ionscale server, you can enable HTTPS certificates for a tailnet:
|
||||
|
||||
```bash
|
||||
# Enable MagicDNS and HTTPS certificates for a tailnet
|
||||
ionscale dns update --tailnet "my-tailnet" --magic-dns --https-certs
|
||||
```
|
||||
|
||||
## Verifying DNS provider configuration
|
||||
|
||||
To verify that your DNS provider is correctly configured:
|
||||
|
||||
1. Configure a tailnet with MagicDNS and HTTPS certificates enabled.
|
||||
2. Connect a device to the tailnet.
|
||||
3. On the device, run:
|
||||
```bash
|
||||
tailscale cert <hostname>
|
||||
```
|
||||
4. If successful, the command will obtain a certificate for the hostname.
|
||||
5. You should see TXT records created in your DNS zone for the ACME challenge.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you encounter issues with DNS provider integration:
|
||||
|
||||
### General troubleshooting
|
||||
|
||||
1. **Check DNS Provider Credentials**: Ensure the credentials in your configuration have sufficient permissions.
|
||||
2. **Verify Zone Configuration**: Make sure the zone in your configuration matches your actual DNS zone.
|
||||
3. **Check MagicDNS Settings**: Confirm that `magic_dns_suffix` is properly configured as a subdomain of your zone.
|
||||
4. **Review Server Logs**: The ionscale server logs may contain error messages related to DNS provider integration.
|
||||
5. **Test DNS Record Creation**: Some providers offer tools to test API access for creating and updating DNS records.
|
||||
|
||||
### External plugin troubleshooting
|
||||
|
||||
1. **Plugin Executable**: Ensure the plugin path is correct and the executable has proper permissions.
|
||||
2. **Plugin Logs**: Check both ionscale logs and any plugin-specific logs for error messages.
|
||||
3. **Plugin Health**: ionscale automatically restarts failed plugins, but persistent failures may indicate configuration issues.
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
# Configuration Guide
|
||||
|
||||
ionscale uses a flexible YAML-based configuration system that supports environment variable substitution and sensible defaults. This guide explains how to configure your ionscale instance.
|
||||
|
||||
## Configuration File Format
|
||||
|
||||
ionscale uses YAML for its configuration files. Here's a basic example:
|
||||
|
||||
```yaml
|
||||
# Server network configuration
|
||||
listen_addr: ":8080"
|
||||
public_addr: "ionscale.example.com:443"
|
||||
stun_listen_addr: ":3478"
|
||||
stun_public_addr: "ionscale.example.com:3478"
|
||||
|
||||
# TLS configuration
|
||||
tls:
|
||||
disable: false
|
||||
force_https: true
|
||||
cert_file: /etc/ionscale/cert.pem
|
||||
key_file: /etc/ionscale/key.pem
|
||||
|
||||
# Database configuration
|
||||
database:
|
||||
type: postgres
|
||||
url: postgres://user:password@localhost:5432/ionscale
|
||||
```
|
||||
|
||||
## Loading Configuration
|
||||
|
||||
When starting ionscale, you can specify a configuration file using the `--config` or `-c` flag:
|
||||
|
||||
```bash
|
||||
ionscale server --config /etc/ionscale/config.yaml
|
||||
```
|
||||
|
||||
If no configuration file is provided, ionscale will use its default values.
|
||||
|
||||
## Environment Variable Support
|
||||
|
||||
ionscale supports two ways to use environment variables in configuration:
|
||||
|
||||
### 1. Direct Configuration via Environment Variables
|
||||
|
||||
You can provide the entire configuration as a base64-encoded string using the `IONSCALE_CONFIG_BASE64` environment variable. This is useful for containerized deployments where you want to inject configuration without mounting files.
|
||||
|
||||
```bash
|
||||
# Create base64-encoded config
|
||||
CONFIG_B64=$(cat config.yaml | base64 -w0)
|
||||
|
||||
# Run ionscale with environment config
|
||||
IONSCALE_CONFIG_BASE64=$CONFIG_B64 ionscale server
|
||||
```
|
||||
|
||||
### 2. Variable Substitution in YAML Files
|
||||
|
||||
You can reference environment variables directly in your YAML configuration files using:
|
||||
|
||||
- `${VAR}` syntax for required variables
|
||||
- `${VAR:default}` syntax for variables with default values
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
database:
|
||||
type: ${DB_TYPE:sqlite}
|
||||
url: ${DB_URL}
|
||||
max_open_conns: ${DB_MAX_OPEN_CONNS:10}
|
||||
```
|
||||
|
||||
In this example:
|
||||
- `DB_TYPE` has a default value of "sqlite" if the environment variable is not set
|
||||
- `DB_URL` is required and must be set in the environment
|
||||
- `DB_MAX_OPEN_CONNS` defaults to 10 if not set
|
||||
|
||||
If a required variable is missing, the configuration loading will fail with an error.
|
||||
|
||||
## Default Configuration
|
||||
|
||||
If no configuration file is provided, ionscale uses these default values:
|
||||
|
||||
```yaml
|
||||
listen_addr: ":8080"
|
||||
metrics_listen_addr: ":9091"
|
||||
stun_listen_addr: ":3478"
|
||||
|
||||
database:
|
||||
type: sqlite
|
||||
url: ./ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)
|
||||
max_idle_conns: 2
|
||||
|
||||
poll_net:
|
||||
keep_alive_interval: 1m
|
||||
|
||||
dns:
|
||||
magic_dns_suffix: ionscale.net
|
||||
|
||||
derp:
|
||||
server:
|
||||
disabled: false
|
||||
region_id: 1000
|
||||
region_code: ionscale
|
||||
region_name: ionscale Embedded DERP
|
||||
|
||||
logging:
|
||||
level: info
|
||||
```
|
||||
|
||||
## Configuration Sections
|
||||
|
||||
### Server Network Configuration
|
||||
|
||||
Controls the network interfaces and addresses:
|
||||
|
||||
```yaml
|
||||
# The HTTP(S) listen address for the control plane
|
||||
listen_addr: ":8080"
|
||||
|
||||
# The metrics listen address (for Prometheus)
|
||||
metrics_listen_addr: ":9091"
|
||||
|
||||
# The STUN listen address when using the embedded DERP
|
||||
stun_listen_addr: ":3478"
|
||||
|
||||
# The DNS name of the server HTTP(S) endpoint as accessible by clients
|
||||
public_addr: "ionscale.example.com:443"
|
||||
|
||||
# The DNS name of the STUN endpoint as accessible by clients
|
||||
stun_public_addr: "ionscale.example.com:3478"
|
||||
```
|
||||
|
||||
### TLS Configuration
|
||||
|
||||
Controls HTTPS and certificate usage:
|
||||
|
||||
```yaml
|
||||
tls:
|
||||
# Disable TLS (not recommended for production)
|
||||
disable: false
|
||||
|
||||
# Force HTTPS redirect
|
||||
force_https: true
|
||||
|
||||
# Path to certificate files (when not using ACME)
|
||||
cert_file: /etc/ionscale/cert.pem
|
||||
key_file: /etc/ionscale/key.pem
|
||||
|
||||
# Let's Encrypt ACME configuration
|
||||
acme: true
|
||||
acme_email: admin@example.com
|
||||
acme_ca: https://acme-v02.api.letsencrypt.org/directory
|
||||
```
|
||||
|
||||
### Database Configuration
|
||||
|
||||
Controls the database storage:
|
||||
|
||||
```yaml
|
||||
database:
|
||||
# Database type: sqlite or postgres
|
||||
type: postgres
|
||||
|
||||
# Database connection URL
|
||||
url: postgres://user:password@localhost:5432/ionscale
|
||||
|
||||
# Connection pool settings
|
||||
max_open_conns: 10
|
||||
max_idle_conns: 5
|
||||
conn_max_life_time: 5m
|
||||
conn_max_idle_time: 5m
|
||||
```
|
||||
|
||||
### OIDC Configuration
|
||||
|
||||
Controls OpenID Connect authentication providers and admin access:
|
||||
|
||||
```yaml
|
||||
auth:
|
||||
# OIDC provider configuration
|
||||
provider:
|
||||
issuer: https://auth.example.com
|
||||
client_id: client_id
|
||||
client_secret: client_secret
|
||||
additional_scopes: ["profile", "email"]
|
||||
|
||||
# System administrators configuration
|
||||
system_admins:
|
||||
emails: ["admin@example.com"]
|
||||
subs: ["subject123"]
|
||||
filters: ["domain == example.com"]
|
||||
```
|
||||
|
||||
For more details about configuring OIDC authentication, see [OIDC Configuration](./auth-oidc.md).
|
||||
|
||||
### DNS Configuration
|
||||
|
||||
Controls DNS settings:
|
||||
|
||||
```yaml
|
||||
dns:
|
||||
# Suffix for MagicDNS
|
||||
magic_dns_suffix: ionscale.net
|
||||
|
||||
# DNS provider for dynamic updates
|
||||
provider:
|
||||
name: cloudflare
|
||||
zone: example.com
|
||||
config:
|
||||
auth_token: ${CLOUDFLARE_TOKEN}
|
||||
```
|
||||
|
||||
For more details about configuring DNS providers, see [DNS Providers](./dns-providers.md).
|
||||
|
||||
### DERP Configuration
|
||||
|
||||
Controls relay server configuration:
|
||||
|
||||
```yaml
|
||||
derp:
|
||||
# Embedded DERP server configuration
|
||||
server:
|
||||
disabled: false
|
||||
region_id: 1000
|
||||
region_code: ionscale
|
||||
region_name: ionscale Embedded DERP
|
||||
|
||||
# External DERP maps to load
|
||||
sources:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
- file:///etc/ionscale/custom-derp.json
|
||||
```
|
||||
|
||||
For more details about configuring DERP servers, see [DERP Configuration](./derp.md).
|
||||
|
||||
### Logging Configuration
|
||||
|
||||
Controls log output:
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
# Log level: debug, info, warn, error
|
||||
level: info
|
||||
|
||||
# Log format: text, json
|
||||
format: text
|
||||
|
||||
# Optional file output (in addition to stdout)
|
||||
file: /var/log/ionscale.log
|
||||
```
|
||||
|
||||
### Keys and Security
|
||||
|
||||
You can configure private keys for the system:
|
||||
|
||||
```yaml
|
||||
keys:
|
||||
# System administrator key for CLI authentication
|
||||
system_admin_key: your-private-key
|
||||
|
||||
# Control plane keys (optional, auto-generated when not provided)
|
||||
control_key: your-control-key
|
||||
legacy_control_key: your-legacy-control-key
|
||||
```
|
||||
|
||||
The `control_key` and `legacy_control_key` are optional and will be automatically generated if not provided. Once generated, they are stored in the database and reused across restarts.
|
||||
|
||||
!!! warning
|
||||
Never commit sensitive keys in your configuration files to version control. Use environment variables for sensitive values.
|
||||
|
||||
## Configuration File Locations
|
||||
|
||||
Common locations for ionscale configuration files:
|
||||
|
||||
- `/etc/ionscale/config.yaml` - System-wide configuration
|
||||
- `$HOME/.config/ionscale/config.yaml` - User-specific configuration
|
||||
- `./config.yaml` - Local directory configuration
|
||||
|
||||
## Complete Configuration Example
|
||||
|
||||
Below is a complete configuration file example with comments:
|
||||
|
||||
```yaml
|
||||
# Network configuration
|
||||
listen_addr: ":8080" # HTTP/HTTPS control plane address
|
||||
stun_listen_addr: ":3478" # STUN server listen address
|
||||
metrics_listen_addr: ":9091" # Prometheus metrics address
|
||||
public_addr: "ionscale.example.com:443" # Public HTTPS endpoint for clients
|
||||
stun_public_addr: "ionscale.example.com:3478" # Public STUN endpoint for clients
|
||||
|
||||
# TLS configuration
|
||||
tls:
|
||||
disable: false # Set to true if behind a TLS-terminating proxy
|
||||
force_https: true # Redirect HTTP to HTTPS
|
||||
# Provide your own certificates
|
||||
cert_file: "/etc/ionscale/cert.pem"
|
||||
key_file: "/etc/ionscale/key.pem"
|
||||
# Or use Let's Encrypt
|
||||
acme: false # Enable ACME/Let's Encrypt
|
||||
acme_email: "admin@example.com" # Contact email for Let's Encrypt
|
||||
acme_ca: "https://acme-v02.api.letsencrypt.org/directory"
|
||||
acme_path: "./data" # Storage path for ACME certificates
|
||||
|
||||
# Database configuration
|
||||
database:
|
||||
# SQLite configuration
|
||||
type: "sqlite"
|
||||
url: "/var/lib/ionscale/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)"
|
||||
|
||||
# Or PostgreSQL configuration
|
||||
# type: "postgres"
|
||||
# url: "postgres://user:password@localhost:5432/ionscale?sslmode=disable"
|
||||
|
||||
# Connection pool settings
|
||||
max_open_conns: 10
|
||||
max_idle_conns: 5
|
||||
conn_max_life_time: "5m"
|
||||
conn_max_idle_time: "5m"
|
||||
|
||||
# DERP (relay) configuration
|
||||
derp:
|
||||
# Embedded DERP server
|
||||
server:
|
||||
disabled: false # Set to true to disable embedded DERP
|
||||
region_id: 1000 # Region ID (1000+ reserved for ionscale)
|
||||
region_code: "ionscale" # Short code for the region
|
||||
region_name: "ionscale Embedded DERP" # Human-readable name
|
||||
|
||||
# External DERP sources (optional)
|
||||
sources:
|
||||
- https://controlplane.tailscale.com/derpmap/default # Tailscale's DERP map
|
||||
# - file:///etc/ionscale/custom-derp.json # Custom DERP map
|
||||
# - git::https://github.com/example/derp//map.json # DERP map from git
|
||||
|
||||
# Security keys
|
||||
keys:
|
||||
# System admin key for CLI authentication (required for admin CLI usage)
|
||||
system_admin_key: "${IONSCALE_SYSTEM_ADMIN_KEY}" # Use environment variable
|
||||
|
||||
# Control keys (optional, auto-generated if not provided)
|
||||
# control_key: "privkey:xxxxxx"
|
||||
# legacy_control_key: "privkey:xxxxxx"
|
||||
|
||||
# Network polling configuration
|
||||
poll_net:
|
||||
# How often to send keep-alive messages
|
||||
keep_alive_interval: "60s"
|
||||
|
||||
# OIDC authentication configuration
|
||||
auth:
|
||||
# OIDC provider settings
|
||||
provider:
|
||||
issuer: "https://auth.example.com" # OIDC issuer URL
|
||||
client_id: "your-client-id" # OAuth client ID
|
||||
client_secret: "${OIDC_CLIENT_SECRET}" # OAuth client secret from env var
|
||||
additional_scopes: ["profile", "email"] # Extra scopes to request
|
||||
|
||||
# System administrator policy
|
||||
system_admins:
|
||||
# Users identified by email
|
||||
emails: ["admin@example.com"]
|
||||
# Users identified by subject ID
|
||||
subs: ["subject-id-12345"]
|
||||
# Users matching expression filters
|
||||
filters: ["domain == example.com"]
|
||||
|
||||
# DNS configuration
|
||||
dns:
|
||||
# Suffix for MagicDNS hostnames
|
||||
magic_dns_suffix: "ionscale.net"
|
||||
|
||||
# DNS provider for automatic DNS management (optional)
|
||||
provider:
|
||||
name: "cloudflare" # Provider name (cloudflare, route53, etc.)
|
||||
zone: "example.com" # DNS zone to manage
|
||||
config: # Provider-specific configuration
|
||||
auth_token: "${DNS_API_TOKEN}"
|
||||
|
||||
# Logging configuration
|
||||
logging:
|
||||
level: "info" # debug, info, warn, error
|
||||
format: "text" # text or json
|
||||
file: "/var/log/ionscale.log" # Optional log file path
|
||||
```
|
||||
|
||||
!!! note "Environment variables"
|
||||
In this example, we use environment variables for sensitive values:
|
||||
```
|
||||
${IONSCALE_SYSTEM_ADMIN_KEY} - System admin key for CLI authentication
|
||||
${OIDC_CLIENT_SECRET} - OIDC client secret
|
||||
${DNS_API_TOKEN} - DNS provider API token
|
||||
```
|
||||
|
||||
These must be set in your environment before starting ionscale.
|
||||
@@ -1,117 +0,0 @@
|
||||
# Configuration Reference
|
||||
|
||||
__ionscale__ uses the YAML file format for configuration.
|
||||
A full configuration reference file is shown below, this provides comments and all available options.
|
||||
|
||||
```yaml
|
||||
# The HTTP(S) listen address to serve the control plane.
|
||||
listen_addr: ":8080"
|
||||
|
||||
# The STUN listen address when using the embedded DERP.
|
||||
stun_listen_addr: ":3478"
|
||||
|
||||
# The address to bind to for the metrics.
|
||||
metrics_listen_addr: ":9091"
|
||||
|
||||
# The DNS name of the server HTTP(S) endpoint as accessible by clients and the CLI.
|
||||
public_addr: "ionscale.example.com:443"
|
||||
|
||||
# The DNS name of the STUN endpoint as accessible by clients.
|
||||
stun_public_addr: "ionscale.example.com:3478"
|
||||
|
||||
tls:
|
||||
# Disable TLS (not recommended)
|
||||
# Use this flag to disable TLS e.g. when running behind a reverse proxy
|
||||
disable: false
|
||||
# Redirect HTTP requests to HTTPS requests
|
||||
force_https: true
|
||||
# The path to the certificate for TLS.
|
||||
# Required when TLS is enabled and ACME disabled
|
||||
cert_file: ""
|
||||
# The path to the private key for the certificate.
|
||||
# Required when TLS is enabled and ACME disabled
|
||||
key_file: ""
|
||||
# Enable automatic TLS certificates provisioning with Let's Encrypt
|
||||
acme: false
|
||||
# An email address, used when creating an ACME account and keeping you up-to-date regarding your certificates
|
||||
acme_email: ""
|
||||
# The URL to the ACME CA's directory.
|
||||
acme_ca: "https://acme-v02.api.letsencrypt.org/directory"
|
||||
# Path to store certificates and metadata needed by ACME
|
||||
acme_path: "./data"
|
||||
|
||||
database:
|
||||
# Type of databas to use, supported values are sqlite or postgres
|
||||
type: "sqlite"
|
||||
# The URL for connecting to the database
|
||||
# e.g
|
||||
# url: "/data/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"
|
||||
# url: "postgres://ionscale:ionscale@localhost/ionscale?sslmode=disable"
|
||||
url: "./ionscale.db"
|
||||
|
||||
derp:
|
||||
server:
|
||||
disabled: false
|
||||
region_id: 1000
|
||||
region_code: "ionscale"
|
||||
region_name: "ionscale Embedded DERP"
|
||||
sources:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
|
||||
keys:
|
||||
# A private, 32 bytes in hex, system admin key
|
||||
# Use this key with the CLI when configuring system-wide resources like tailnets
|
||||
# A key can be generated by:
|
||||
# - ionscale genkey
|
||||
# - openssl rand -hex 32
|
||||
system_admin_key: ""
|
||||
|
||||
poll_net:
|
||||
# Period to send keep alive messages to the connected devices
|
||||
keep_alive_interval: "60s"
|
||||
|
||||
# Optional authentication configuration
|
||||
auth:
|
||||
# OIDC provider configuration
|
||||
provider:
|
||||
# OIDC issuer URL where ionscale can find the OpenID Provider Configuration Document
|
||||
issuer: ""
|
||||
# OIDC client id and secrets
|
||||
client_id: ""
|
||||
client_secret: ""
|
||||
# additional OIDC scopes used in the OIDC flow
|
||||
additional_scopes: ""
|
||||
# IAM policy to mark some authenticated users as System Admin
|
||||
system_admins:
|
||||
# A list of emails of users that are System Admin
|
||||
emails: []
|
||||
# A list of ID (sub OIDC claim) of users that are System Admin
|
||||
subs: []
|
||||
# A list of BEXPR filters to mark authenticated users as System Admin
|
||||
filters: []
|
||||
|
||||
dns:
|
||||
# The base domain of the MagicDNS FQDN hostnames
|
||||
magic_dns_suffix: "ionscale.net"
|
||||
# A DNS provider for setting public TXT records
|
||||
# This is a requirement to enable Tailscale HTTPS certs.
|
||||
provider:
|
||||
# name of your provider, currently supported implementations:
|
||||
# - azure (https://github.com/libdns/azure)
|
||||
# - cloudflare (https://github.com/libdns/cloudflare)
|
||||
# - digitialocean (https://github.com/libdns/digitalocean)
|
||||
# - googleclouddns (https://github.com/libdns/googleclouddns)
|
||||
# - route53 (https://github.com/libdns/route53)
|
||||
name: ""
|
||||
# DNS zone
|
||||
zone: ""
|
||||
# Provider specific configuration
|
||||
config: {}
|
||||
|
||||
logging:
|
||||
# Output formatting for logs: text or json
|
||||
format: "text"
|
||||
level: "info"
|
||||
# Path of a target log file, if omitted logs are written to stdout
|
||||
file: ""
|
||||
```
|
||||
@@ -0,0 +1,123 @@
|
||||
# ACL Policies
|
||||
|
||||
Access Control Lists (ACLs) define what network access is allowed within a tailnet. By default, tailnets are created with an open policy that allows all connections between devices.
|
||||
|
||||
## Understanding ACL policies
|
||||
|
||||
ACL policies in ionscale follow the same format and rules as Tailscale's ACL system. They allow you to control:
|
||||
|
||||
- Which devices can communicate with each other
|
||||
- What ports and protocols are allowed
|
||||
- Who can use exit nodes and other special features
|
||||
- SSH access between machines
|
||||
- Tag ownership and management
|
||||
|
||||
## Basic ACL structure
|
||||
|
||||
A basic ACL policy contains rules that specify which sources can access which destinations:
|
||||
|
||||
```json
|
||||
{
|
||||
"acls": [
|
||||
{"action": "accept", "src": ["tag:web"], "dst": ["tag:db:5432"]},
|
||||
{"action": "accept", "src": ["group:admins"], "dst": ["*:*"]}
|
||||
],
|
||||
"groups": {
|
||||
"admins": ["admin@example.com"]
|
||||
},
|
||||
"tagOwners": {
|
||||
"tag:web": ["admin@example.com"],
|
||||
"tag:db": ["admin@example.com"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this example:
|
||||
- Web servers (tagged `tag:web`) can only access database servers on port 5432
|
||||
- Admins have full access to all resources
|
||||
- Only admin@example.com can assign the web and database tags to machines
|
||||
|
||||
## Managing ACL policies
|
||||
|
||||
You can view and update the ACL policy for a tailnet using the ionscale CLI:
|
||||
|
||||
```bash
|
||||
# View current ACL policy
|
||||
ionscale acl get --tailnet "my-tailnet"
|
||||
|
||||
# Update ACL policy from a file
|
||||
ionscale acl update --tailnet "my-tailnet" --file acl.json
|
||||
```
|
||||
|
||||
!!! tip
|
||||
ACL changes take effect immediately for all devices in the tailnet.
|
||||
|
||||
## Common ACL patterns
|
||||
|
||||
### Allow specific tags to communicate
|
||||
|
||||
```json
|
||||
{
|
||||
"acls": [
|
||||
{"action": "accept", "src": ["tag:web"], "dst": ["tag:api:8080"]},
|
||||
{"action": "accept", "src": ["tag:api"], "dst": ["tag:db:5432"]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Group-based access
|
||||
|
||||
```json
|
||||
{
|
||||
"acls": [
|
||||
{"action": "accept", "src": ["group:developers"], "dst": ["tag:dev-env:*"]},
|
||||
{"action": "accept", "src": ["group:ops"], "dst": ["*:*"]}
|
||||
],
|
||||
"groups": {
|
||||
"developers": ["alice@example.com", "bob@example.com"],
|
||||
"ops": ["charlie@example.com", "diana@example.com"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### SSH access control
|
||||
|
||||
```json
|
||||
{
|
||||
"ssh": [
|
||||
{
|
||||
"action": "accept",
|
||||
"src": ["group:admins"],
|
||||
"dst": ["tag:server"],
|
||||
"users": ["root"]
|
||||
},
|
||||
{
|
||||
"action": "accept",
|
||||
"src": ["group:developers"],
|
||||
"dst": ["tag:dev"],
|
||||
"users": ["autogroup:nonroot"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Auto-approving advertised routes
|
||||
|
||||
```json
|
||||
{
|
||||
"autoApprovers": {
|
||||
"routes": {
|
||||
"10.0.0.0/24": ["group:network-admins"],
|
||||
"192.168.1.0/24": ["user@example.com"]
|
||||
},
|
||||
"exitNode": ["group:network-admins"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Additional resources
|
||||
|
||||
For more detailed information on ACL syntax and capabilities, see the [Tailscale ACL documentation](https://tailscale.com/kb/1018/acls/).
|
||||
|
||||
!!! note "Feature support"
|
||||
Not all ACL features from the official Tailscale control plane are supported in ionscale. Some advanced features or newer functionality may not be available.
|
||||
@@ -1,72 +0,0 @@
|
||||
# Getting started with Docker
|
||||
|
||||
You can install and run __ionscale__ using the Docker images published on [GitHub Container Registry](https://github.com/jsiebens/ionscale/pkgs/container/ionscale).
|
||||
|
||||
## Requirements
|
||||
|
||||
- A Linux machine with port 443 and 3478 open to ingress traffic.
|
||||
- Docker installed. See the [official installation documentation](https://docs.docker.com/install/)
|
||||
- A registered domain name.
|
||||
|
||||
## Step 1. Configure DNS
|
||||
|
||||
Set up a `A` DNS records: `ionscale.example.com` (We are assuming that your domain name is example.com.)
|
||||
|
||||
!!! tip
|
||||
|
||||
You can use `dig` to make sure that DNS records are propagated:
|
||||
|
||||
``` bash
|
||||
$ dig ionscale.example.com
|
||||
```
|
||||
|
||||
## Step 2. Run ionscale with Docker
|
||||
|
||||
### Configure ionscale
|
||||
|
||||
``` bash
|
||||
mkdir -p ionscale/data
|
||||
cd ./ionscale
|
||||
```
|
||||
|
||||
Generate a configuration file for __ionscale__ with the following commands:
|
||||
|
||||
``` bash
|
||||
export IONSCALE_ACME_EMAIL=<your email>
|
||||
export IONSCALE_DOMAIN=ionscale.example.com
|
||||
export IONSCALE_SYSTEM_ADMIN_KEY=$(docker run ghcr.io/jsiebens/ionscale:0.15.0 genkey -n)
|
||||
```
|
||||
|
||||
``` bash
|
||||
tee ./config.yaml >/dev/null <<EOF
|
||||
listen_addr: ":443"
|
||||
public_addr: "${IONSCALE_DOMAIN}:443"
|
||||
stun_public_addr: "${IONSCALE_DOMAIN}:3478"
|
||||
|
||||
tls:
|
||||
acme: true
|
||||
acme_email: "${IONSCALE_ACME_EMAIL}"
|
||||
|
||||
keys:
|
||||
system_admin_key: "${IONSCALE_SYSTEM_ADMIN_KEY}"
|
||||
|
||||
database:
|
||||
url: "/data/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"
|
||||
|
||||
logging:
|
||||
level: info
|
||||
EOF
|
||||
```
|
||||
|
||||
### Start ionscale
|
||||
|
||||
Run an __ionscale__ instance with the following command:
|
||||
|
||||
``` bash
|
||||
docker run \
|
||||
-v $(pwd)/config.yaml:/etc/ionscale/config.yaml \
|
||||
-v $(pwd)/data:/data \
|
||||
-p 443:443 \
|
||||
-p 3478:3478/udp \
|
||||
ghcr.io/jsiebens/ionscale:0.15.0 server --config /etc/ionscale/config.yaml
|
||||
```
|
||||
@@ -0,0 +1,160 @@
|
||||
# IAM Policies
|
||||
|
||||
Identity and Access Management (IAM) policies in ionscale control who can access a tailnet and what administrative permissions they have.
|
||||
|
||||
!!! important "OIDC required"
|
||||
IAM policies are only relevant when an OIDC provider is configured. If your ionscale instance isn't using OIDC, access to tailnets is managed solely through auth keys.
|
||||
|
||||
## Understanding IAM policies
|
||||
|
||||
IAM policies determine:
|
||||
|
||||
- Which users can join a tailnet
|
||||
- What roles and permissions users have within the tailnet
|
||||
- How access decisions are made based on user attributes
|
||||
|
||||
An IAM policy consists of:
|
||||
|
||||
```json
|
||||
{
|
||||
"subs": ["auth0|123456789"],
|
||||
"filters": ["domain == example.com"],
|
||||
"emails": ["specific-user@otherdomain.com"],
|
||||
"roles": {
|
||||
"admin@example.com": "admin"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## IAM policy components
|
||||
|
||||
### Subs
|
||||
|
||||
The `subs` list provides direct access based on user IDs (subjects):
|
||||
|
||||
```json
|
||||
"subs": ["auth0|123456789", "google-oauth2|12345"]
|
||||
```
|
||||
|
||||
Any user whose ID matches an entry in this list will be granted access to the tailnet. User IDs are typically provided by the OIDC provider and are unique identifiers for each user.
|
||||
|
||||
### Emails
|
||||
|
||||
The `emails` list provides direct access to specific email addresses:
|
||||
|
||||
```json
|
||||
"emails": ["alice@example.com", "bob@otherdomain.com"]
|
||||
```
|
||||
|
||||
Any user with an email in this list will be granted access to the tailnet, regardless of filters.
|
||||
|
||||
### Filters
|
||||
|
||||
Filters are expressions that evaluate user attributes:
|
||||
|
||||
```json
|
||||
"filters": ["domain == example.com", "email.endsWith('@engineering.example.com')"]
|
||||
```
|
||||
|
||||
These expressions determine if a user can access the tailnet based on their identity attributes. Users matching any filter expression will be granted access.
|
||||
|
||||
### Roles
|
||||
|
||||
The `roles` map assigns specific roles to users:
|
||||
|
||||
```json
|
||||
"roles": {
|
||||
"admin@example.com": "admin",
|
||||
"devops@example.com": "admin",
|
||||
"developer@example.com": "member"
|
||||
}
|
||||
```
|
||||
|
||||
Available roles:
|
||||
- `admin`: Can manage tailnet settings, ACLs, and auth keys
|
||||
- `member`: Standard access to use the tailnet (default)
|
||||
|
||||
## Managing IAM policies
|
||||
|
||||
View and update IAM policies using the ionscale CLI:
|
||||
|
||||
```bash
|
||||
# View current IAM policy
|
||||
ionscale iam get-policy --tailnet "my-tailnet"
|
||||
|
||||
# Update IAM policy using a JSON file
|
||||
ionscale iam update-policy --tailnet "my-tailnet" --file policy.json
|
||||
```
|
||||
|
||||
## Common IAM patterns
|
||||
|
||||
### Domain-based tailnet
|
||||
|
||||
Grant access to everyone with the same email domain:
|
||||
|
||||
```json
|
||||
{
|
||||
"filters": ["domain == example.com"],
|
||||
"roles": {
|
||||
"admin1@example.com": "admin",
|
||||
"admin2@example.com": "admin"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Personal tailnet
|
||||
|
||||
Create a tailnet for individual use:
|
||||
|
||||
```json
|
||||
{
|
||||
"emails": ["personal@example.com"],
|
||||
"roles": {
|
||||
"personal@example.com": "admin"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Setting IAM during tailnet creation
|
||||
|
||||
You can set basic IAM policies during tailnet creation with CLI flags:
|
||||
|
||||
```bash
|
||||
# Allow all users with an @example.com email address
|
||||
ionscale tailnet create --name "shared-tailnet" --domain "example.com"
|
||||
|
||||
# Allow only a specific user
|
||||
ionscale tailnet create --name "personal-tailnet" --email "user@example.com"
|
||||
```
|
||||
|
||||
These shortcuts create appropriate filter rules or email entries in the IAM policy.
|
||||
|
||||
## IAM policy evaluation
|
||||
|
||||
When a user attempts to access a tailnet, the following checks occur:
|
||||
|
||||
1. Is the user's ID in the `subs` list? If yes, grant access.
|
||||
2. Is the user's email in the `emails` list? If yes, grant access.
|
||||
3. Does the user match any expression in the `filters` list? If yes, grant access.
|
||||
4. If none of these conditions are met, access is denied.
|
||||
|
||||
For role determination:
|
||||
|
||||
1. Check if the user has an entry in the `roles` map
|
||||
2. If yes, assign that role
|
||||
3. If no, assign the default `member` role
|
||||
|
||||
## Security considerations
|
||||
|
||||
- **Principle of least privilege**: Start with minimal access and add users or filters as needed
|
||||
- **Regular audits**: Periodically review IAM policies to ensure only appropriate users have access
|
||||
- **Admin roles**: Limit admin roles to trusted users who need to manage tailnet settings
|
||||
|
||||
## Troubleshooting access issues
|
||||
|
||||
If a user is having trouble accessing a tailnet:
|
||||
|
||||
1. Verify the user's email is correct and matches their OIDC identity
|
||||
2. Check filter expressions to ensure they match the user's attributes
|
||||
3. Verify the user is authenticating against the correct ionscale instance
|
||||
4. Check OIDC provider configuration and token issuance
|
||||
@@ -0,0 +1,78 @@
|
||||
# Getting started with ionscale
|
||||
|
||||
After installing ionscale, you'll need to configure the CLI to interact with your server. This guide will walk you through the initial setup and explain the authentication options available.
|
||||
|
||||
## Installing the ionscale CLI
|
||||
|
||||
The ionscale CLI is the primary tool for managing your ionscale instance. It allows you to create and manage tailnets, users, and access controls.
|
||||
|
||||
```bash
|
||||
# Download the CLI (adjust the URL for your system architecture)
|
||||
curl -L -o ionscale https://github.com/jsiebens/ionscale/releases/download/v0.17.0/ionscale_linux_amd64
|
||||
|
||||
# Make it executable
|
||||
chmod +x ionscale
|
||||
|
||||
# Move to system path
|
||||
sudo mv ionscale /usr/local/bin/
|
||||
```
|
||||
|
||||
## Authentication requirements
|
||||
|
||||
To use the ionscale CLI, you must authenticate with the server using one of two methods:
|
||||
|
||||
!!! important "Administrator access required"
|
||||
All management operations require either:
|
||||
|
||||
1. **System admin key** authentication, or
|
||||
2. **OIDC user** authentication with system administrator privileges
|
||||
|
||||
### Option 1: Using the system admin key
|
||||
|
||||
If you configured ionscale with a system admin key during installation, you can authenticate using that key:
|
||||
|
||||
```bash
|
||||
# Configure environment variables
|
||||
export IONSCALE_ADDR="https://ionscale.example.com"
|
||||
export IONSCALE_SYSTEM_ADMIN_KEY="your-system-admin-key"
|
||||
|
||||
# Verify connection
|
||||
ionscale version
|
||||
```
|
||||
|
||||
The system admin key provides full administrative access to your ionscale instance. This is the default authentication method when OIDC is not configured.
|
||||
|
||||
### Option 2: Using OIDC authentication
|
||||
|
||||
If you configured ionscale with an OIDC provider, users designated as system administrators in the OIDC configuration can authenticate:
|
||||
|
||||
```bash
|
||||
# Configure URL only
|
||||
export IONSCALE_ADDR="https://ionscale.example.com"
|
||||
|
||||
# Authenticate through OIDC
|
||||
ionscale auth login
|
||||
```
|
||||
|
||||
This will open a browser window where you can authenticate with your OIDC provider. After successful authentication, if your account has system administrator privileges, you'll be able to use the CLI.
|
||||
|
||||
!!! tip "OIDC system administrators"
|
||||
System administrators are defined in the ionscale configuration under the `auth.system_admins` section. See the [Authentication with OIDC](../configuration/auth-oidc.md) documentation for details.
|
||||
|
||||
## Basic CLI commands
|
||||
|
||||
Once authenticated, you can use the ionscale CLI to manage your instance:
|
||||
|
||||
```bash
|
||||
# View general information
|
||||
ionscale version # Show version information
|
||||
ionscale help # Display help information
|
||||
|
||||
# Tailnet management
|
||||
ionscale tailnet list # List all tailnets
|
||||
ionscale tailnet create -n NAME # Create a new tailnet
|
||||
|
||||
# Auth key management
|
||||
ionscale auth-key list --tailnet NAME # List auth keys for a tailnet
|
||||
ionscale auth-key create --tailnet NAME # Create a new auth key
|
||||
```
|
||||
@@ -1,115 +0,0 @@
|
||||
# Getting started on a Linux Server
|
||||
|
||||
This tutorial will guide you through the steps needed to install and run __ionscale__ on a Linux machine.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A Linux machine with port 443 and 3478 open to ingress traffic.
|
||||
- A registered domain name.
|
||||
|
||||
## Step 1. Configure DNS
|
||||
|
||||
Set up a `A` DNS records: `ionscale.example.com` (We are assuming that your domain name is example.com.)
|
||||
|
||||
!!! tip
|
||||
|
||||
You can use `dig` to make sure that DNS records are propagated:
|
||||
|
||||
``` bash
|
||||
$ dig ionscale.example.com
|
||||
```
|
||||
|
||||
## Step 2. Set up ionscale on your Linux host
|
||||
|
||||
### Prepare installation
|
||||
|
||||
Run the following commands to prepare the installation:
|
||||
|
||||
``` bash
|
||||
sudo mkdir -p /etc/ionscale
|
||||
sudo mkdir -p /var/lib/ionscale
|
||||
|
||||
sudo useradd --system --no-create-home --shell /bin/false ionscale
|
||||
sudo chown ionscale:ionscale /etc/ionscale
|
||||
sudo chown ionscale:ionscale /var/lib/ionscale
|
||||
```
|
||||
|
||||
### Install ionscale
|
||||
|
||||
Run the following commands to install the __ionscale__ binary on your Linux host:
|
||||
|
||||
``` bash
|
||||
sudo curl \
|
||||
-o "/usr/local/bin/ionscale" \
|
||||
-sfL "https://github.com/jsiebens/ionscale/releases/download/v0.15.0/ionscale_linux_amd64"
|
||||
|
||||
sudo chmod +x "/usr/local/bin/ionscale"
|
||||
```
|
||||
|
||||
### Configure ionscale
|
||||
|
||||
Generate a system admin key for __ionscale__ using the `ionscale genkey` command and write it the an environment file:
|
||||
|
||||
``` bash
|
||||
sudo tee /etc/default/ionscale >/dev/null <<EOF
|
||||
IONSCALE_KEYS_SYSTEM_ADMIN_KEY=$(ionscale genkey -n)
|
||||
EOF
|
||||
```
|
||||
|
||||
Generate a configuration file for __ionscale__ with the following commands:
|
||||
|
||||
``` bash
|
||||
export IONSCALE_ACME_EMAIL=<your email>
|
||||
export IONSCALE_DOMAIN=ionscale.example.com
|
||||
```
|
||||
|
||||
``` bash
|
||||
sudo tee /etc/ionscale/config.yaml >/dev/null <<EOF
|
||||
listen_addr: ":443"
|
||||
public_addr: "${IONSCALE_DOMAIN}:443"
|
||||
stun_public_addr: "${IONSCALE_DOMAIN}:3478"
|
||||
|
||||
tls:
|
||||
acme: true
|
||||
acme_email: "${IONSCALE_ACME_EMAIL}"
|
||||
|
||||
database:
|
||||
url: "/var/lib/ionscale/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"
|
||||
|
||||
logging:
|
||||
level: info
|
||||
EOF
|
||||
```
|
||||
|
||||
Create a systemd service file for __ionscale__ with the following commands:
|
||||
|
||||
``` bash
|
||||
sudo tee /etc/systemd/system/ionscale.service >/dev/null <<EOF
|
||||
[Unit]
|
||||
Description=ionscale - a Tailscale Controller server
|
||||
Requires=network-online.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/etc/default/ionscale
|
||||
User=ionscale
|
||||
Group=ionscale
|
||||
ExecStart=/usr/local/bin/ionscale server --config /etc/ionscale/config.yaml
|
||||
Restart=on-failure
|
||||
RestartSec=10s
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
```
|
||||
|
||||
### Start ionscale
|
||||
|
||||
On your Linux machine, run the following commands to enable and start the __ionscale__ daemon:
|
||||
|
||||
``` bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable ionscale
|
||||
sudo systemctl start ionscale
|
||||
```
|
||||
@@ -0,0 +1,154 @@
|
||||
# Creating your first tailnet
|
||||
|
||||
A tailnet is a private network that connects your devices securely using Tailscale. This guide will walk you through creating your first tailnet with ionscale.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before creating a tailnet, make sure you have:
|
||||
|
||||
- ionscale server installed and running
|
||||
- The ionscale CLI installed and configured
|
||||
- Authentication with system administrator privileges
|
||||
|
||||
## Creating a tailnet
|
||||
|
||||
The simplest way to create a tailnet is with the `tailnet create` command:
|
||||
|
||||
```bash
|
||||
ionscale tailnet create --name "my-first-tailnet"
|
||||
```
|
||||
|
||||
This creates a basic tailnet named "my-first-tailnet" with:
|
||||
|
||||
- A default ACL policy that allows all connections
|
||||
```
|
||||
{"acls": [{"action": "accept", "src": ["*"], "dst": ["*:*"]}]}
|
||||
```
|
||||
- A default IAM policy that determines who can access the tailnet
|
||||
|
||||
!!! note
|
||||
The tailnet name must be unique within your ionscale instance and should only contain alphanumeric characters, hyphens, and underscores.
|
||||
|
||||
## Setting IAM policies for access control
|
||||
|
||||
!!! important "OIDC required"
|
||||
IAM policies are only relevant when an OIDC provider is configured. If your ionscale instance isn't using OIDC, access to tailnets is managed solely through auth keys, and the configuration in this section won't apply.
|
||||
|
||||
When using OIDC authentication, you'll need to configure who can access your tailnet through IAM policies.
|
||||
|
||||
### Configuring IAM during tailnet creation
|
||||
|
||||
You can set a basic IAM policy when creating a tailnet using flags:
|
||||
|
||||
```bash
|
||||
# Allow all users with an @example.com email address
|
||||
ionscale tailnet create --name "company-tailnet" --domain "example.com"
|
||||
|
||||
# Allow only a specific user
|
||||
ionscale tailnet create --name "personal-tailnet" --email "user@example.com"
|
||||
```
|
||||
|
||||
These flags provide quick ways to set up common IAM policies:
|
||||
|
||||
- `--domain example.com`: Creates a **shared tailnet** that allows all users with an email address from the specified domain. This is ideal for company or team networks where multiple users need access. The IAM policy will contain a filter rule like `domain == "example.com"`.
|
||||
|
||||
- `--email user@example.com`: Creates a **personal tailnet** that grants access only to the specific email address. This is suitable for individual use or when you want to tightly control access to a specific user. The IAM policy will contain an entry for the specified email.
|
||||
|
||||
!!! note
|
||||
You can't use both flags together. Choose either domain-based access for a shared network or email-based access for a personal network.
|
||||
|
||||
### Configuring IAM after tailnet creation
|
||||
|
||||
You can view and update the IAM policy for an existing tailnet:
|
||||
|
||||
```bash
|
||||
# View current IAM policy
|
||||
ionscale iam get-policy --tailnet "my-first-tailnet"
|
||||
|
||||
# Update IAM policy using a JSON file
|
||||
ionscale iam update-policy --tailnet "my-first-tailnet" --file policy.json
|
||||
```
|
||||
|
||||
Example policy.json file:
|
||||
```json
|
||||
{
|
||||
"filters": ["domain == example.com"],
|
||||
"emails": ["specific-user@otherdomain.com"],
|
||||
"roles": {
|
||||
"admin@example.com": "admin"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Connecting devices to your tailnet
|
||||
|
||||
There are two main methods to connect devices to your tailnet:
|
||||
|
||||
!!! tip
|
||||
For detailed instructions on configuring various Tailscale clients to use ionscale as a control server, refer to the [Tailscale Knowledge Base](https://tailscale.com/kb/1507/custom-control-server).
|
||||
|
||||
### Interactive login
|
||||
|
||||
When you have an OIDC provider configured, users can connect to their tailnet through an interactive web authentication flow:
|
||||
|
||||
```bash
|
||||
tailscale up --login-server=https://ionscale.example.com
|
||||
```
|
||||
|
||||
This opens a browser window where the user authenticates with the OIDC provider. After successful authentication, if the user has access based on the tailnet's IAM policy, the device will be connected to the tailnet.
|
||||
|
||||
!!! note
|
||||
Interactive login requires an OIDC provider to be configured on your ionscale instance.
|
||||
|
||||
### Using pre-authentication keys
|
||||
|
||||
Pre-authentication keys (auth keys) allow devices to join a tailnet without interactive authentication. This is useful for automated deployments, servers, or environments where browser-based authentication isn't practical.
|
||||
|
||||
To create an auth key:
|
||||
|
||||
```bash
|
||||
# Create an auth key
|
||||
ionscale auth-key create --tailnet "my-first-tailnet"
|
||||
|
||||
# Create an auth key with specific tags
|
||||
ionscale auth-key create --tailnet "my-first-tailnet" --tags "tag:server"
|
||||
```
|
||||
|
||||
The tags assigned to the key will determine what network access the device has once connected, based on your ACL rules.
|
||||
|
||||
!!! note
|
||||
In environments with OIDC, users with access to a tailnet can create auth keys for that tailnet. Without OIDC, only system administrators can create keys.
|
||||
|
||||
To connect a device using an auth key:
|
||||
|
||||
```bash
|
||||
# Connect using the auth key
|
||||
tailscale up --login-server=https://ionscale.example.com --auth-key=...
|
||||
```
|
||||
|
||||
## Network access and security policies
|
||||
|
||||
By default, tailnets are created with an open policy that allows all connections between devices. For production environments, you'll want to configure:
|
||||
|
||||
- **[IAM Policies](iam-policies.md)**: Manage who can access your tailnet
|
||||
- **[ACL Policies](acl-policies.md)**: Control which devices can communicate within your tailnet
|
||||
|
||||
!!! tip
|
||||
For detailed information on configuring security policies, see the dedicated documentation sections on [IAM Policies](iam-policies.md) and [ACL Policies](acl-policies.md).
|
||||
|
||||
## Managing multiple tailnets
|
||||
|
||||
You can create multiple tailnets to separate different network environments:
|
||||
|
||||
```bash
|
||||
# List all tailnets
|
||||
ionscale tailnet list
|
||||
|
||||
# Create tailnets for different teams or businesses
|
||||
ionscale tailnet create --name "tailnet-a"
|
||||
ionscale tailnet create --name "tailnet-b"
|
||||
ionscale tailnet create --name "tailnet-c"
|
||||
```
|
||||
|
||||
!!! note
|
||||
Each tailnet is a separate network with its own devices, ACLs, and IAM policies. Devices in different tailnets cannot communicate with each other by default.
|
||||
+23
-25
@@ -1,35 +1,33 @@
|
||||
# ionscale
|
||||
# Welcome to ionscale
|
||||
|
||||
> **Note**:
|
||||
> ionscale is currently beta quality, actively being developed and so subject to changes
|
||||
ionscale is an open-source alternative to Tailscale's control server, designed to provide a self-hosted coordination service for your Tailscale networks.
|
||||
|
||||
**What is Tailscale?**
|
||||
!!! info "Beta status"
|
||||
ionscale is currently in beta. While it's stable for production use for small tailnets, we're actively developing new features and improvements.
|
||||
|
||||
[Tailscale](https://tailscale.com) is a VPN service that makes the devices and applications you own accessible anywhere in the world, securely and effortlessly.
|
||||
It enables encrypted point-to-point connections using the open source [WireGuard](https://www.wireguard.com/) protocol, which means only devices on your private network can communicate with each other.
|
||||
!!! warning "Documentation status"
|
||||
This documentation is a work in progress. Some sections may be incomplete or missing. We're continuously improving the documentation to provide comprehensive coverage of all features.
|
||||
|
||||
**What is ionscale?**
|
||||
## What is ionscale?
|
||||
|
||||
While the Tailscale software running on each node is open source, their centralized "coordination server" which act as a shared drop box for public keys is not.
|
||||
Tailscale allows your devices to communicate securely across networks using WireGuard®. While Tailscale's client software is open source, their centralized coordination server (which manages public keys and network configurations) is proprietary.
|
||||
|
||||
_ionscale_ aims to implement such lightweight, open source alternative Tailscale control server.
|
||||
**ionscale aims to implement a lightweight, open-source control server that:**
|
||||
|
||||
## Features
|
||||
- Acts as a drop-in replacement for Tailscale's coordination server
|
||||
- Can be self-hosted on your infrastructure
|
||||
- Gives you full control over your network configuration
|
||||
- Works with the standard Tailscale clients
|
||||
- Supports a [wide range of Tailscale features](./overview/features.md)
|
||||
|
||||
- multi [tailnet](https://tailscale.com/kb/1136/tailnet/) support
|
||||
- multi user support
|
||||
- OIDC integration (not required, although recommended)
|
||||
- [Auth keys](https://tailscale.com/kb/1085/auth-keys/)
|
||||
- [Access control list](https://tailscale.com/kb/1018/acls/)
|
||||
- [DNS](https://tailscale.com/kb/1054/dns/)
|
||||
- nameservers
|
||||
- Split DNS
|
||||
- MagicDNS
|
||||
- [HTTPS Certs](https://tailscale.com/kb/1153/enabling-https/)
|
||||
- [Tailscale SSH](https://tailscale.com/kb/1193/tailscale-ssh/)
|
||||
- [Service collection](https://tailscale.com/kb/1100/services/)
|
||||
- [Taildrop](https://tailscale.com/kb/1106/taildrop/)
|
||||
## Getting started
|
||||
|
||||
## Disclaimer
|
||||
- [**Installation guide**](./installation/index.md) - Install ionscale using Docker or directly on Linux
|
||||
- [**CLI configuration**](./getting-started/index.md) - Set up the ionscale CLI and authenticate
|
||||
- [**Creating a tailnet**](./getting-started/tailnet.md) - Create and manage your first tailnet
|
||||
- [**OIDC authentication**](./configuration/auth-oidc.md) - Configure user authentication via OIDC
|
||||
- [**DNS providers**](./configuration/dns-providers.md) - Set up DNS integration for HTTPS certificates
|
||||
|
||||
This is not an official Tailscale or Tailscale Inc. project.
|
||||
<small>
|
||||
Disclaimer: This is not an official Tailscale or Tailscale Inc. project. Tailscale and WireGuard are trademarks of their respective owners.
|
||||
</small>
|
||||
@@ -0,0 +1,101 @@
|
||||
# Installing ionscale with Docker
|
||||
|
||||
This guide will walk you through installing and configuring ionscale using Docker containers. Docker provides a simple and consistent way to deploy ionscale across different environments.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, make sure you have:
|
||||
|
||||
- A Linux server (virtual or physical)
|
||||
- Docker installed ([official Docker installation guide](https://docs.docker.com/engine/install/))
|
||||
- Root or sudo access
|
||||
- A registered domain name pointing to your server
|
||||
- Ports 443 (HTTPS) and 3478/UDP (STUN) open in your firewall
|
||||
- Basic familiarity with the Linux command line
|
||||
|
||||
### Domain and DNS configuration
|
||||
|
||||
ionscale requires a domain name to function properly. This enables secure HTTPS connections and proper Tailscale device discovery.
|
||||
|
||||
1. Configure an A record in your domain's DNS settings:
|
||||
```
|
||||
ionscale.example.com → YOUR_SERVER_IP
|
||||
```
|
||||
(Replace "example.com" with your actual domain and "YOUR_SERVER_IP" with your server's public IP address)
|
||||
|
||||
2. Verify the DNS record has propagated:
|
||||
```bash
|
||||
dig ionscale.example.com
|
||||
```
|
||||
The command should return your server's public IP address.
|
||||
|
||||
## Container setup
|
||||
|
||||
### Creating a directory structure
|
||||
|
||||
Create a dedicated directory for ionscale files:
|
||||
|
||||
```bash
|
||||
mkdir -p ionscale/data
|
||||
cd ./ionscale
|
||||
```
|
||||
|
||||
### Generating a configuration file
|
||||
|
||||
First, set up environment variables for the configuration:
|
||||
|
||||
```bash
|
||||
export IONSCALE_ACME_EMAIL="your-email@example.com" # Used for Let's Encrypt notifications
|
||||
export IONSCALE_DOMAIN="ionscale.example.com" # Your ionscale domain
|
||||
export IONSCALE_SYSTEM_ADMIN_KEY=$(docker run --rm ghcr.io/jsiebens/ionscale:0.17.0 genkey -n)
|
||||
```
|
||||
|
||||
!!! important "System admin key"
|
||||
The system admin key is a critical security component that provides full administrative access to your ionscale instance. Make sure to save this key securely.
|
||||
|
||||
Alternatively, you can configure ionscale without a system admin key by using an OIDC provider and setting up system admin accounts through the OIDC configuration. See the [Authentication with OIDC](../configuration/auth-oidc.md) documentation for details.
|
||||
|
||||
Now create the configuration file:
|
||||
|
||||
```bash
|
||||
cat > ./config.yaml <<EOF
|
||||
listen_addr: ":443"
|
||||
public_addr: "${IONSCALE_DOMAIN}:443"
|
||||
stun_public_addr: "${IONSCALE_DOMAIN}:3478"
|
||||
|
||||
tls:
|
||||
acme: true
|
||||
acme_email: "${IONSCALE_ACME_EMAIL}"
|
||||
|
||||
keys:
|
||||
system_admin_key: "${IONSCALE_SYSTEM_ADMIN_KEY}"
|
||||
|
||||
database:
|
||||
url: "/data/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"
|
||||
|
||||
logging:
|
||||
level: info
|
||||
EOF
|
||||
```
|
||||
|
||||
### Running the container
|
||||
|
||||
Start the ionscale container with the following command:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name ionscale \
|
||||
--restart unless-stopped \
|
||||
-v $(pwd)/config.yaml:/etc/ionscale/config.yaml \
|
||||
-v $(pwd)/data:/data \
|
||||
-p 443:443 \
|
||||
-p 3478:3478/udp \
|
||||
ghcr.io/jsiebens/ionscale:0.17.0 server --config /etc/ionscale/config.yaml
|
||||
```
|
||||
|
||||
This command:
|
||||
|
||||
- Creates a persistent container named "ionscale"
|
||||
- Mounts your configuration file and data directory
|
||||
- Maps the required ports to the host
|
||||
- Automatically restarts the container if it stops unexpectedly
|
||||
@@ -0,0 +1,38 @@
|
||||
# Installation guide
|
||||
|
||||
ionscale can be installed in several ways, depending on your preferences and requirements. This section covers the different installation methods available.
|
||||
|
||||
## Choose your installation method
|
||||
|
||||
ionscale offers two primary installation methods:
|
||||
|
||||
### Docker installation
|
||||
|
||||
The [Docker installation](docker.md) method is recommended for:
|
||||
|
||||
- Quick deployments
|
||||
- Testing and evaluation
|
||||
- Users familiar with container environments
|
||||
- Simplified upgrades and maintenance
|
||||
|
||||
Docker provides an isolated environment with all dependencies included, making it the easiest way to get started with ionscale.
|
||||
|
||||
### Linux installation
|
||||
|
||||
The [Linux installation](linux.md) method is suitable for:
|
||||
|
||||
- Production environments
|
||||
- Integration with existing infrastructure
|
||||
- More control over the installation
|
||||
- Systems without Docker
|
||||
|
||||
This approach installs ionscale directly on your Linux server and configures it as a system service.
|
||||
|
||||
## Post-installation steps
|
||||
|
||||
After completing the installation, consider these next steps:
|
||||
|
||||
1. Configure an [OIDC provider](../configuration/auth-oidc.md) for user authentication
|
||||
2. Set up a [DNS provider](../configuration/dns-providers.md) to enable HTTPS certificates for Tailscale nodes
|
||||
3. Create and configure tailnets
|
||||
4. Set up access controls and permissions
|
||||
@@ -0,0 +1,194 @@
|
||||
# Linux installation
|
||||
|
||||
This guide walks you through installing ionscale directly on a Linux server. This approach gives you more control over the installation and is suitable for production environments.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, make sure you have:
|
||||
|
||||
- A Linux server (virtual or physical)
|
||||
- Root or sudo access
|
||||
- A registered domain name pointing to your server
|
||||
- Ports 443 (HTTPS) and 3478/UDP (STUN) open in your firewall
|
||||
- Basic familiarity with the Linux command line
|
||||
|
||||
### Domain and DNS configuration
|
||||
|
||||
ionscale requires a domain name to function properly. This enables secure HTTPS connections and proper Tailscale device discovery.
|
||||
|
||||
1. Configure an A record in your domain's DNS settings:
|
||||
```
|
||||
ionscale.example.com → YOUR_SERVER_IP
|
||||
```
|
||||
(Replace "example.com" with your actual domain and "YOUR_SERVER_IP" with your server's public IP address)
|
||||
|
||||
2. Verify the DNS record has propagated:
|
||||
```bash
|
||||
dig ionscale.example.com
|
||||
```
|
||||
The command should return your server's public IP address.
|
||||
|
||||
## Quick deployment
|
||||
|
||||
If you prefer an automated deployment, you can use our installation script:
|
||||
|
||||
```bash
|
||||
# Download the script
|
||||
curl -fsSL https://raw.githubusercontent.com/jsiebens/ionscale/main/scripts/install.sh -o install.sh
|
||||
chmod +x install.sh
|
||||
|
||||
# Run the script (interactive mode)
|
||||
./install.sh
|
||||
```
|
||||
|
||||
The script will prompt you for:
|
||||
1. Your domain name for ionscale
|
||||
2. Your email address (for Let's Encrypt notifications)
|
||||
|
||||
For non-interactive installation, set the required environment variables:
|
||||
|
||||
```bash
|
||||
export IONSCALE_DOMAIN="ionscale.example.com"
|
||||
export IONSCALE_ACME_EMAIL="your-email@example.com"
|
||||
./install.sh
|
||||
```
|
||||
|
||||
The script automatically:
|
||||
|
||||
1. Determines your system architecture
|
||||
2. Creates a dedicated service user
|
||||
3. Downloads and installs the latest ionscale binary
|
||||
4. Generates a secure system admin key
|
||||
5. Creates necessary configuration files
|
||||
6. Sets up and starts the systemd service
|
||||
|
||||
For a detailed explanation of each step, continue reading the manual installation instructions below.
|
||||
|
||||
## System preparation
|
||||
|
||||
### Create a dedicated service user
|
||||
|
||||
For security reasons, ionscale should run under a dedicated, unprivileged system user:
|
||||
|
||||
```bash
|
||||
# Create service user
|
||||
sudo useradd --system --no-create-home --shell /bin/false ionscale
|
||||
|
||||
# Create directories
|
||||
sudo mkdir -p /etc/ionscale
|
||||
sudo mkdir -p /var/lib/ionscale
|
||||
|
||||
# Set appropriate permissions
|
||||
sudo chown ionscale:ionscale /etc/ionscale
|
||||
sudo chown ionscale:ionscale /var/lib/ionscale
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
### Download and install the binary
|
||||
|
||||
Install the ionscale binary on your system:
|
||||
|
||||
```bash
|
||||
# Download the latest version (adjust for your CPU architecture)
|
||||
sudo curl -o "/usr/local/bin/ionscale" \
|
||||
-sfL "https://github.com/jsiebens/ionscale/releases/download/v0.17.0/ionscale_linux_amd64"
|
||||
|
||||
# Make it executable
|
||||
sudo chmod +x "/usr/local/bin/ionscale"
|
||||
|
||||
# Verify installation
|
||||
ionscale version
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
1. Generate a system admin key and store it in an environment file:
|
||||
|
||||
```bash
|
||||
sudo tee /etc/default/ionscale >/dev/null <<EOF
|
||||
IONSCALE_KEYS_SYSTEM_ADMIN_KEY=$(ionscale genkey -n)
|
||||
EOF
|
||||
```
|
||||
|
||||
!!! important "System admin key"
|
||||
The system admin key is a critical security component that provides full administrative access to your ionscale instance. Make sure to save this key securely.
|
||||
|
||||
Alternatively, you can configure ionscale without a system admin key by using an OIDC provider and setting up system admin accounts through the OIDC configuration. See the [Authentication with OIDC](../configuration/auth-oidc.md) documentation for details.
|
||||
|
||||
2. Set up environment variables for the configuration:
|
||||
|
||||
```bash
|
||||
export IONSCALE_ACME_EMAIL="your-email@example.com" # For Let's Encrypt notifications
|
||||
export IONSCALE_DOMAIN="ionscale.example.com" # Your ionscale domain
|
||||
```
|
||||
|
||||
3. Create the configuration file:
|
||||
|
||||
```bash
|
||||
sudo tee /etc/ionscale/config.yaml >/dev/null <<EOF
|
||||
listen_addr: ":443"
|
||||
public_addr: "${IONSCALE_DOMAIN}:443"
|
||||
stun_public_addr: "${IONSCALE_DOMAIN}:3478"
|
||||
|
||||
tls:
|
||||
acme: true
|
||||
acme_email: "${IONSCALE_ACME_EMAIL}"
|
||||
|
||||
database:
|
||||
url: "/var/lib/ionscale/ionscale.db?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"
|
||||
|
||||
keys:
|
||||
system_admin_key: "\${IONSCALE_KEYS_SYSTEM_ADMIN_KEY}"
|
||||
|
||||
logging:
|
||||
level: info
|
||||
EOF
|
||||
```
|
||||
|
||||
## Setting up systemd service
|
||||
|
||||
Create a systemd service file to manage the ionscale process:
|
||||
|
||||
```bash
|
||||
sudo tee /etc/systemd/system/ionscale.service >/dev/null <<EOF
|
||||
[Unit]
|
||||
Description=ionscale - a Tailscale control server
|
||||
Requires=network-online.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/etc/default/ionscale
|
||||
User=ionscale
|
||||
Group=ionscale
|
||||
ExecStart=/usr/local/bin/ionscale server --config /etc/ionscale/config.yaml
|
||||
Restart=on-failure
|
||||
RestartSec=10s
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
```
|
||||
|
||||
The `AmbientCapabilities=CAP_NET_BIND_SERVICE` line allows ionscale to bind to privileged ports (443) without running as root.
|
||||
|
||||
## Starting ionscale
|
||||
|
||||
Enable and start the ionscale service:
|
||||
|
||||
```bash
|
||||
# Reload systemd to recognize the new service
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
# Enable service to start on boot
|
||||
sudo systemctl enable ionscale
|
||||
|
||||
# Start the service
|
||||
sudo systemctl start ionscale
|
||||
|
||||
# Check status
|
||||
sudo systemctl status ionscale
|
||||
```
|
||||
|
||||
If everything started successfully, you should see an "active (running)" status.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Supported features
|
||||
|
||||
ionscale implements key Tailscale features to provide a complete control server experience. This page outlines the major features that ionscale supports.
|
||||
|
||||
## Multi-tailnet support
|
||||
|
||||
ionscale allows you to create and manage multiple tailnets (Tailscale private networks) from a single server:
|
||||
|
||||
- Create isolated networks for different teams or environments
|
||||
- Manage separate tailnets for personal and organizational use
|
||||
- Configure each tailnet with its own ACLs and settings
|
||||
|
||||
## User management
|
||||
|
||||
- **Multi-user support**: Multiple users can access and use the same tailnet based on permissions
|
||||
- **OIDC integration**: Optional but recommended for user authentication and management
|
||||
|
||||
## Authentication
|
||||
|
||||
- **[Auth keys](https://tailscale.com/kb/1085/auth-keys/)**: Generate and manage pre-authentication keys for devices
|
||||
- **[Device tagging](https://tailscale.com/kb/1068/tags/)**: Apply tags to devices for better management and ACL control
|
||||
|
||||
## Network control
|
||||
|
||||
- **[Access control lists (ACLs)](https://tailscale.com/kb/1018/acls/)**: Define fine-grained rules for who can access what
|
||||
- **[Subnet routers](https://tailscale.com/kb/1019/subnets/)**: Connect existing networks to your tailnet
|
||||
- **[Exit nodes](https://tailscale.com/kb/1103/exit-nodes/)**: Configure nodes to act as VPN exit points
|
||||
|
||||
## DNS management
|
||||
|
||||
- **[MagicDNS](https://tailscale.com/kb/1081/magicdns/)**: Automatic DNS for tailnet devices
|
||||
- **[Split DNS](https://tailscale.com/kb/1054/dns/)**: Route specific DNS queries to specific resolvers
|
||||
- **Custom nameservers**: Configure any DNS servers for your tailnet
|
||||
|
||||
## HTTPS and certificates
|
||||
|
||||
- **[HTTPS certificates](https://tailscale.com/kb/1153/enabling-https/)**: Automatic SSL/TLS certificates for devices
|
||||
- **DNS provider integration**: Support for various DNS providers to facilitate ACME challenges
|
||||
- **[Tailscale Serve](https://tailscale.com/kb/1242/tailscale-serve/)**: Share web services easily with HTTPS
|
||||
|
||||
## SSH
|
||||
|
||||
- **[Tailscale SSH](https://tailscale.com/kb/1193/tailscale-ssh/)**: Built-in SSH server support
|
||||
- **SSH policy management**: Control who can SSH into which devices
|
||||
|
||||
## DERP
|
||||
|
||||
- **Embedded DERP server**
|
||||
- **Custom DERP maps**: Configure your own DERP servers
|
||||
|
||||
## File sharing
|
||||
|
||||
- **[Taildrop](https://tailscale.com/kb/1106/taildrop/)**: Send files directly between tailnet devices
|
||||
|
||||
## Feature status
|
||||
|
||||
Most features are fully implemented and compatible with the official Tailscale clients. As ionscale is continuously developed, new features from Tailscale are regularly added.
|
||||
|
||||
If you find any issues with specific features or have requests for additional functionality, please check the [project repository](https://github.com/jsiebens/ionscale) for the latest updates or to submit feedback.
|
||||
@@ -0,0 +1,126 @@
|
||||
/* Custom CSS for ionscale documentation */
|
||||
|
||||
/* Enhance code blocks */
|
||||
.md-typeset pre {
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
/* Enhance code block headers */
|
||||
.md-typeset code {
|
||||
border-radius: 3px;
|
||||
font-size: 0.9em;
|
||||
padding: 0.2em 0.4em;
|
||||
}
|
||||
|
||||
/* Make admonitions stand out more */
|
||||
.md-typeset .admonition {
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
|
||||
.md-typeset .admonition-title {
|
||||
padding-left: 2.5rem;
|
||||
}
|
||||
|
||||
/* Make tables more professional */
|
||||
.md-typeset table:not([class]) {
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.md-typeset table:not([class]) th {
|
||||
background-color: rgba(63, 81, 181, 0.08);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Enhance UI element spacing */
|
||||
.md-typeset ul li,
|
||||
.md-typeset ol li {
|
||||
margin-bottom: 0.35em;
|
||||
}
|
||||
|
||||
.md-typeset h1,
|
||||
.md-typeset h2,
|
||||
.md-typeset h3,
|
||||
.md-typeset h4 {
|
||||
font-weight: 500;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
.md-typeset h2 {
|
||||
border-bottom: 1px solid rgba(63, 81, 181, 0.1);
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
/* Subtle border on the right for table of contents */
|
||||
.md-sidebar--secondary {
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.07);
|
||||
background-color: rgba(0, 0, 0, 0.01);
|
||||
}
|
||||
|
||||
/* Navigation improvements */
|
||||
.md-nav__item .md-nav__link--active {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Responsive improvements */
|
||||
@media screen and (min-width: 76.25em) {
|
||||
.md-sidebar--primary {
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.07);
|
||||
background-color: rgba(0, 0, 0, 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
/* Better footer */
|
||||
.md-footer-meta {
|
||||
background-color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
/* Remove the logo and style site name */
|
||||
.md-header__button.md-logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Move the site name to the left */
|
||||
.md-header__title {
|
||||
margin-left: 0;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.02em;
|
||||
font-family: Lato, sans-serif;
|
||||
}
|
||||
|
||||
.md-header__topic {
|
||||
color: white;
|
||||
font-size: 1.2rem;
|
||||
line-height: 2.4rem;
|
||||
margin-left: 0.6rem;
|
||||
}
|
||||
|
||||
/* Badge styles for version/status indicators */
|
||||
.md-typeset .md-badge {
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
font-size: 0.75em;
|
||||
font-weight: 700;
|
||||
padding: 4px 6px;
|
||||
margin: 0 0.5em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.md-typeset .md-badge--new {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.md-typeset .md-badge--beta {
|
||||
background-color: #f0ad4e;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.md-typeset .md-badge--deprecated {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
}
|
||||
+107
-11
@@ -1,28 +1,54 @@
|
||||
site_name: ionscale
|
||||
|
||||
repo_name: jsiebens/ionscale
|
||||
repo_url: https://github.com/jsiebens/ionscale
|
||||
edit_uri: ""
|
||||
# Remove the GitHub repository link from the top-right corner
|
||||
# repo_name: jsiebens/ionscale
|
||||
# repo_url: https://github.com/jsiebens/ionscale
|
||||
# edit_uri: ""
|
||||
|
||||
nav:
|
||||
- Overview:
|
||||
- Introduction: index.md
|
||||
- Supported Features: overview/features.md
|
||||
- Installation:
|
||||
- Manual: ./getting-started/manual.md
|
||||
- Docker: ./getting-started/docker.md
|
||||
- Installation: ./installation/index.md
|
||||
- Linux installation: ./installation/linux.md
|
||||
- Docker installation: ./installation/docker.md
|
||||
- Configuration:
|
||||
- Reference: ./configuration/reference.md
|
||||
- Configuration: ./configuration/index.md
|
||||
- DERP: ./configuration/derp.md
|
||||
- OIDC: ./configuration/auth-oidc.md
|
||||
- DNS providers: ./configuration/dns-providers.md
|
||||
- Getting started:
|
||||
- Getting started: ./getting-started/index.md
|
||||
- Creating a tailnet: ./getting-started/tailnet.md
|
||||
- IAM Policies: ./getting-started/iam-policies.md
|
||||
- ACL Policies: ./getting-started/acl-policies.md
|
||||
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
|
||||
# Custom stylesheets
|
||||
extra_css:
|
||||
- stylesheets/extra.css
|
||||
|
||||
# Explicitly disable the logo to show only the site name
|
||||
#logo: ""
|
||||
favicon: assets/favicon.png
|
||||
|
||||
# Enhanced color scheme
|
||||
palette:
|
||||
- scheme: default
|
||||
- media: "(prefers-color-scheme: light)"
|
||||
scheme: default
|
||||
primary: indigo
|
||||
accent: indigo
|
||||
toggle:
|
||||
icon: material/toggle-switch-off-outline
|
||||
name: Switch to dark mode
|
||||
- scheme: slate
|
||||
- media: "(prefers-color-scheme: dark)"
|
||||
scheme: slate
|
||||
primary: indigo
|
||||
accent: indigo
|
||||
toggle:
|
||||
icon: material/toggle-switch
|
||||
name: Switch to light mode
|
||||
@@ -32,9 +58,28 @@ theme:
|
||||
code: Roboto Mono
|
||||
|
||||
features:
|
||||
# Navigation
|
||||
- navigation.tracking
|
||||
- navigation.sections
|
||||
- toc.integrate
|
||||
- navigation.indexes
|
||||
- navigation.top # Back-to-top button
|
||||
- navigation.footer # Footer with previous/next links
|
||||
|
||||
# Content
|
||||
- content.code.copy # Add copy button to code blocks
|
||||
- content.code.annotate # Allow code annotations
|
||||
- content.tabs.link # Sync all tabs with the same label
|
||||
|
||||
# Search
|
||||
- search.highlight
|
||||
- search.share
|
||||
- search.suggest
|
||||
|
||||
# Table of contents
|
||||
- toc.follow
|
||||
|
||||
# Hide the table of contents on the navigation
|
||||
toc_depth: 0
|
||||
|
||||
include_search_page: false
|
||||
search_index_only: true
|
||||
@@ -42,15 +87,66 @@ theme:
|
||||
language: en
|
||||
|
||||
markdown_extensions:
|
||||
# Admonitions and callouts
|
||||
- admonition
|
||||
- pymdownx.details
|
||||
- pymdownx.superfences
|
||||
|
||||
# Code blocks with syntax highlighting
|
||||
- pymdownx.highlight:
|
||||
anchor_linenums: true
|
||||
line_spans: __span
|
||||
pygments_lang_class: true
|
||||
- pymdownx.inlinehilite
|
||||
|
||||
# Code annotations
|
||||
- pymdownx.snippets
|
||||
- pymdownx.superfences
|
||||
|
||||
# Tabbed content
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
|
||||
# Content tabs
|
||||
- pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format
|
||||
|
||||
# Better formatting options
|
||||
- attr_list # Add HTML attributes and CSS classes
|
||||
- def_list # Definition lists
|
||||
- md_in_html # Markdown within HTML
|
||||
- tables # Tables
|
||||
- footnotes # Footnotes
|
||||
|
||||
# Typography improvements
|
||||
- pymdownx.critic # Track changes
|
||||
- pymdownx.caret # Superscript/subscript
|
||||
- pymdownx.mark # Highlighting
|
||||
- pymdownx.tilde # Strikethrough
|
||||
- pymdownx.smartsymbols # Smart symbols (arrows, fractions)
|
||||
|
||||
extra:
|
||||
# Page status annotations
|
||||
status:
|
||||
new: Recently added
|
||||
deprecated: No longer supported
|
||||
beta: Currently in beta
|
||||
|
||||
# Enhanced social cards
|
||||
social:
|
||||
- icon: fontawesome/brands/github
|
||||
link: https://github.com/jsiebens/ionscale
|
||||
- icon: fontawesome/brands/docker
|
||||
link: https://github.com/jsiebens/ionscale/pkgs/container/ionscale
|
||||
|
||||
# Page customization
|
||||
# version:
|
||||
# provider: mike
|
||||
|
||||
# Footer customization
|
||||
generator: false # Hide "Made with Material for MkDocs"
|
||||
|
||||
# Analytics (existing)
|
||||
analytics:
|
||||
provider: custom
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/acl.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,20 +22,17 @@ const (
|
||||
)
|
||||
|
||||
type GetACLPolicyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetACLPolicyRequest) Reset() {
|
||||
*x = GetACLPolicyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_acl_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetACLPolicyRequest) String() string {
|
||||
@@ -45,7 +43,7 @@ func (*GetACLPolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetACLPolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_acl_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -68,20 +66,17 @@ func (x *GetACLPolicyRequest) GetTailnetId() uint64 {
|
||||
}
|
||||
|
||||
type GetACLPolicyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Policy string `protobuf:"bytes,1,opt,name=policy,proto3" json:"policy,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetACLPolicyResponse) Reset() {
|
||||
*x = GetACLPolicyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_acl_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetACLPolicyResponse) String() string {
|
||||
@@ -92,7 +87,7 @@ func (*GetACLPolicyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetACLPolicyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_acl_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -115,21 +110,18 @@ func (x *GetACLPolicyResponse) GetPolicy() string {
|
||||
}
|
||||
|
||||
type SetACLPolicyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
Policy string `protobuf:"bytes,2,opt,name=policy,proto3" json:"policy,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetACLPolicyRequest) Reset() {
|
||||
*x = SetACLPolicyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_acl_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetACLPolicyRequest) String() string {
|
||||
@@ -140,7 +132,7 @@ func (*SetACLPolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetACLPolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_acl_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -170,18 +162,16 @@ func (x *SetACLPolicyRequest) GetPolicy() string {
|
||||
}
|
||||
|
||||
type SetACLPolicyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetACLPolicyResponse) Reset() {
|
||||
*x = SetACLPolicyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_acl_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetACLPolicyResponse) String() string {
|
||||
@@ -192,7 +182,7 @@ func (*SetACLPolicyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetACLPolicyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_acl_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -209,7 +199,7 @@ func (*SetACLPolicyResponse) Descriptor() ([]byte, []int) {
|
||||
|
||||
var File_ionscale_v1_acl_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_acl_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_acl_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63,
|
||||
0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x22, 0x34, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f,
|
||||
@@ -230,22 +220,22 @@ var file_ionscale_v1_acl_proto_rawDesc = []byte{
|
||||
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_acl_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_acl_proto_rawDescData = file_ionscale_v1_acl_proto_rawDesc
|
||||
file_ionscale_v1_acl_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_acl_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_acl_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_acl_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_acl_proto_rawDescData)
|
||||
file_ionscale_v1_acl_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_acl_proto_rawDesc), len(file_ionscale_v1_acl_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_acl_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_acl_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_ionscale_v1_acl_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_acl_proto_goTypes = []any{
|
||||
(*GetACLPolicyRequest)(nil), // 0: ionscale.v1.GetACLPolicyRequest
|
||||
(*GetACLPolicyResponse)(nil), // 1: ionscale.v1.GetACLPolicyResponse
|
||||
(*SetACLPolicyRequest)(nil), // 2: ionscale.v1.SetACLPolicyRequest
|
||||
@@ -264,61 +254,11 @@ func file_ionscale_v1_acl_proto_init() {
|
||||
if File_ionscale_v1_acl_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_acl_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetACLPolicyRequest); 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[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetACLPolicyResponse); 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[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetACLPolicyRequest); 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[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetACLPolicyResponse); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_acl_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_acl_proto_rawDesc), len(file_ionscale_v1_acl_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
@@ -329,7 +269,6 @@ func file_ionscale_v1_acl_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_acl_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_acl_proto = out.File
|
||||
file_ionscale_v1_acl_proto_rawDesc = nil
|
||||
file_ionscale_v1_acl_proto_goTypes = nil
|
||||
file_ionscale_v1_acl_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/auth.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,18 +22,16 @@ const (
|
||||
)
|
||||
|
||||
type AuthenticateRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) Reset() {
|
||||
*x = AuthenticateRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) String() string {
|
||||
@@ -43,7 +42,7 @@ func (*AuthenticateRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AuthenticateRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -59,22 +58,19 @@ func (*AuthenticateRequest) Descriptor() ([]byte, []int) {
|
||||
}
|
||||
|
||||
type AuthenticateResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AuthUrl string `protobuf:"bytes,1,opt,name=auth_url,json=authUrl,proto3" json:"auth_url,omitempty"`
|
||||
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
|
||||
TailnetId *uint64 `protobuf:"varint,3,opt,name=tailnet_id,json=tailnetId,proto3,oneof" json:"tailnet_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthenticateResponse) Reset() {
|
||||
*x = AuthenticateResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthenticateResponse) String() string {
|
||||
@@ -85,7 +81,7 @@ func (*AuthenticateResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AuthenticateResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -123,7 +119,7 @@ func (x *AuthenticateResponse) GetTailnetId() uint64 {
|
||||
|
||||
var File_ionscale_v1_auth_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_auth_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_auth_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x16, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75,
|
||||
0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
|
||||
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x15, 0x0a, 0x13, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
|
||||
@@ -140,22 +136,22 @@ var file_ionscale_v1_auth_proto_rawDesc = []byte{
|
||||
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_auth_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_auth_proto_rawDescData = file_ionscale_v1_auth_proto_rawDesc
|
||||
file_ionscale_v1_auth_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_auth_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_auth_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_auth_proto_rawDescData)
|
||||
file_ionscale_v1_auth_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_auth_proto_rawDesc), len(file_ionscale_v1_auth_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_auth_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_ionscale_v1_auth_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_auth_proto_goTypes = []any{
|
||||
(*AuthenticateRequest)(nil), // 0: ionscale.v1.AuthenticateRequest
|
||||
(*AuthenticateResponse)(nil), // 1: ionscale.v1.AuthenticateResponse
|
||||
}
|
||||
@@ -172,38 +168,12 @@ func file_ionscale_v1_auth_proto_init() {
|
||||
if File_ionscale_v1_auth_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthenticateRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthenticateResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_proto_msgTypes[1].OneofWrappers = []interface{}{}
|
||||
file_ionscale_v1_auth_proto_msgTypes[1].OneofWrappers = []any{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_auth_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_auth_proto_rawDesc), len(file_ionscale_v1_auth_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
@@ -214,7 +184,6 @@ func file_ionscale_v1_auth_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_auth_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_auth_proto = out.File
|
||||
file_ionscale_v1_auth_proto_rawDesc = nil
|
||||
file_ionscale_v1_auth_proto_goTypes = nil
|
||||
file_ionscale_v1_auth_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/auth_keys.proto
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,20 +24,17 @@ const (
|
||||
)
|
||||
|
||||
type GetAuthKeyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AuthKeyId uint64 `protobuf:"varint,1,opt,name=auth_key_id,json=authKeyId,proto3" json:"auth_key_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetAuthKeyRequest) Reset() {
|
||||
*x = GetAuthKeyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetAuthKeyRequest) String() string {
|
||||
@@ -47,7 +45,7 @@ func (*GetAuthKeyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetAuthKeyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -70,20 +68,17 @@ func (x *GetAuthKeyRequest) GetAuthKeyId() uint64 {
|
||||
}
|
||||
|
||||
type GetAuthKeyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AuthKey *AuthKey `protobuf:"bytes,1,opt,name=auth_key,json=authKey,proto3" json:"auth_key,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetAuthKeyResponse) Reset() {
|
||||
*x = GetAuthKeyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetAuthKeyResponse) String() string {
|
||||
@@ -94,7 +89,7 @@ func (*GetAuthKeyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetAuthKeyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -117,24 +112,21 @@ func (x *GetAuthKeyResponse) GetAuthKey() *AuthKey {
|
||||
}
|
||||
|
||||
type CreateAuthKeyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
Ephemeral bool `protobuf:"varint,2,opt,name=ephemeral,proto3" json:"ephemeral,omitempty"`
|
||||
Expiry *durationpb.Duration `protobuf:"bytes,3,opt,name=expiry,proto3,oneof" json:"expiry,omitempty"`
|
||||
Tags []string `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||
PreAuthorized bool `protobuf:"varint,5,opt,name=pre_authorized,json=preAuthorized,proto3" json:"pre_authorized,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreateAuthKeyRequest) Reset() {
|
||||
*x = CreateAuthKeyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *CreateAuthKeyRequest) String() string {
|
||||
@@ -145,7 +137,7 @@ func (*CreateAuthKeyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *CreateAuthKeyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -196,21 +188,18 @@ func (x *CreateAuthKeyRequest) GetPreAuthorized() bool {
|
||||
}
|
||||
|
||||
type CreateAuthKeyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AuthKey *AuthKey `protobuf:"bytes,1,opt,name=auth_key,json=authKey,proto3" json:"auth_key,omitempty"`
|
||||
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreateAuthKeyResponse) Reset() {
|
||||
*x = CreateAuthKeyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *CreateAuthKeyResponse) String() string {
|
||||
@@ -221,7 +210,7 @@ func (*CreateAuthKeyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *CreateAuthKeyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -251,20 +240,17 @@ func (x *CreateAuthKeyResponse) GetValue() string {
|
||||
}
|
||||
|
||||
type DeleteAuthKeyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AuthKeyId uint64 `protobuf:"varint,1,opt,name=auth_key_id,json=authKeyId,proto3" json:"auth_key_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteAuthKeyRequest) Reset() {
|
||||
*x = DeleteAuthKeyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteAuthKeyRequest) String() string {
|
||||
@@ -275,7 +261,7 @@ func (*DeleteAuthKeyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteAuthKeyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -298,18 +284,16 @@ func (x *DeleteAuthKeyRequest) GetAuthKeyId() uint64 {
|
||||
}
|
||||
|
||||
type DeleteAuthKeyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteAuthKeyResponse) Reset() {
|
||||
*x = DeleteAuthKeyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteAuthKeyResponse) String() string {
|
||||
@@ -320,7 +304,7 @@ func (*DeleteAuthKeyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteAuthKeyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -336,20 +320,17 @@ func (*DeleteAuthKeyResponse) Descriptor() ([]byte, []int) {
|
||||
}
|
||||
|
||||
type ListAuthKeysRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListAuthKeysRequest) Reset() {
|
||||
*x = ListAuthKeysRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListAuthKeysRequest) String() string {
|
||||
@@ -360,7 +341,7 @@ func (*ListAuthKeysRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListAuthKeysRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -383,20 +364,17 @@ func (x *ListAuthKeysRequest) GetTailnetId() uint64 {
|
||||
}
|
||||
|
||||
type ListAuthKeysResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AuthKeys []*AuthKey `protobuf:"bytes,1,rep,name=auth_keys,json=authKeys,proto3" json:"auth_keys,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListAuthKeysResponse) Reset() {
|
||||
*x = ListAuthKeysResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListAuthKeysResponse) String() string {
|
||||
@@ -407,7 +385,7 @@ func (*ListAuthKeysResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListAuthKeysResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -430,10 +408,7 @@ func (x *ListAuthKeysResponse) GetAuthKeys() []*AuthKey {
|
||||
}
|
||||
|
||||
type AuthKey struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Ephemeral bool `protobuf:"varint,3,opt,name=ephemeral,proto3" json:"ephemeral,omitempty"`
|
||||
@@ -441,15 +416,15 @@ type AuthKey struct {
|
||||
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"`
|
||||
Tailnet *Ref `protobuf:"bytes,7,opt,name=tailnet,proto3" json:"tailnet,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthKey) Reset() {
|
||||
*x = AuthKey{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthKey) String() string {
|
||||
@@ -460,7 +435,7 @@ func (*AuthKey) ProtoMessage() {}
|
||||
|
||||
func (x *AuthKey) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_auth_keys_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -526,7 +501,7 @@ func (x *AuthKey) GetTailnet() *Ref {
|
||||
|
||||
var File_ionscale_v1_auth_keys_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_auth_keys_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_auth_keys_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x1b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75,
|
||||
0x74, 0x68, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
@@ -598,22 +573,22 @@ var file_ionscale_v1_auth_keys_proto_rawDesc = []byte{
|
||||
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_auth_keys_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_auth_keys_proto_rawDescData = file_ionscale_v1_auth_keys_proto_rawDesc
|
||||
file_ionscale_v1_auth_keys_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_auth_keys_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_auth_keys_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_auth_keys_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_auth_keys_proto_rawDescData)
|
||||
file_ionscale_v1_auth_keys_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_auth_keys_proto_rawDesc), len(file_ionscale_v1_auth_keys_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_auth_keys_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_auth_keys_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
var file_ionscale_v1_auth_keys_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_auth_keys_proto_goTypes = []any{
|
||||
(*GetAuthKeyRequest)(nil), // 0: ionscale.v1.GetAuthKeyRequest
|
||||
(*GetAuthKeyResponse)(nil), // 1: ionscale.v1.GetAuthKeyResponse
|
||||
(*CreateAuthKeyRequest)(nil), // 2: ionscale.v1.CreateAuthKeyRequest
|
||||
@@ -648,123 +623,13 @@ func file_ionscale_v1_auth_keys_proto_init() {
|
||||
return
|
||||
}
|
||||
file_ionscale_v1_ref_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetAuthKeyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetAuthKeyResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*CreateAuthKeyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*CreateAuthKeyResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteAuthKeyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteAuthKeyResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListAuthKeysRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListAuthKeysResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthKey); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[2].OneofWrappers = []interface{}{}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[8].OneofWrappers = []interface{}{}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[2].OneofWrappers = []any{}
|
||||
file_ionscale_v1_auth_keys_proto_msgTypes[8].OneofWrappers = []any{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_auth_keys_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_auth_keys_proto_rawDesc), len(file_ionscale_v1_auth_keys_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 9,
|
||||
NumExtensions: 0,
|
||||
@@ -775,7 +640,6 @@ func file_ionscale_v1_auth_keys_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_auth_keys_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_auth_keys_proto = out.File
|
||||
file_ionscale_v1_auth_keys_proto_rawDesc = nil
|
||||
file_ionscale_v1_auth_keys_proto_goTypes = nil
|
||||
file_ionscale_v1_auth_keys_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/derp.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,18 +22,16 @@ const (
|
||||
)
|
||||
|
||||
type GetDefaultDERPMapRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetDefaultDERPMapRequest) Reset() {
|
||||
*x = GetDefaultDERPMapRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_derp_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetDefaultDERPMapRequest) String() string {
|
||||
@@ -43,7 +42,7 @@ func (*GetDefaultDERPMapRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetDefaultDERPMapRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_derp_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -59,20 +58,17 @@ func (*GetDefaultDERPMapRequest) Descriptor() ([]byte, []int) {
|
||||
}
|
||||
|
||||
type GetDefaultDERPMapResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetDefaultDERPMapResponse) Reset() {
|
||||
*x = GetDefaultDERPMapResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_derp_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetDefaultDERPMapResponse) String() string {
|
||||
@@ -83,7 +79,7 @@ func (*GetDefaultDERPMapResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetDefaultDERPMapResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_derp_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -107,7 +103,7 @@ func (x *GetDefaultDERPMapResponse) GetValue() []byte {
|
||||
|
||||
var File_ionscale_v1_derp_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_derp_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_derp_proto_rawDesc = string([]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, 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61,
|
||||
@@ -120,22 +116,22 @@ var file_ionscale_v1_derp_proto_rawDesc = []byte{
|
||||
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_derp_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_derp_proto_rawDescData = file_ionscale_v1_derp_proto_rawDesc
|
||||
file_ionscale_v1_derp_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_derp_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_derp_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_derp_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_derp_proto_rawDescData)
|
||||
file_ionscale_v1_derp_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_derp_proto_rawDesc), len(file_ionscale_v1_derp_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_derp_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_derp_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_ionscale_v1_derp_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_derp_proto_goTypes = []any{
|
||||
(*GetDefaultDERPMapRequest)(nil), // 0: ionscale.v1.GetDefaultDERPMapRequest
|
||||
(*GetDefaultDERPMapResponse)(nil), // 1: ionscale.v1.GetDefaultDERPMapResponse
|
||||
}
|
||||
@@ -152,37 +148,11 @@ func file_ionscale_v1_derp_proto_init() {
|
||||
if File_ionscale_v1_derp_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_derp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetDefaultDERPMapRequest); 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[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetDefaultDERPMapResponse); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_derp_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_derp_proto_rawDesc), len(file_ionscale_v1_derp_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
@@ -193,7 +163,6 @@ func file_ionscale_v1_derp_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_derp_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_derp_proto = out.File
|
||||
file_ionscale_v1_derp_proto_rawDesc = nil
|
||||
file_ionscale_v1_derp_proto_goTypes = nil
|
||||
file_ionscale_v1_derp_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
+33
-125
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/dns.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,20 +22,17 @@ const (
|
||||
)
|
||||
|
||||
type GetDNSConfigRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetDNSConfigRequest) Reset() {
|
||||
*x = GetDNSConfigRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetDNSConfigRequest) String() string {
|
||||
@@ -45,7 +43,7 @@ func (*GetDNSConfigRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetDNSConfigRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -68,20 +66,17 @@ func (x *GetDNSConfigRequest) GetTailnetId() uint64 {
|
||||
}
|
||||
|
||||
type GetDNSConfigResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Config *DNSConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetDNSConfigResponse) Reset() {
|
||||
*x = GetDNSConfigResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetDNSConfigResponse) String() string {
|
||||
@@ -92,7 +87,7 @@ func (*GetDNSConfigResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetDNSConfigResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -115,21 +110,18 @@ func (x *GetDNSConfigResponse) GetConfig() *DNSConfig {
|
||||
}
|
||||
|
||||
type SetDNSConfigRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
Config *DNSConfig `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetDNSConfigRequest) Reset() {
|
||||
*x = SetDNSConfigRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetDNSConfigRequest) String() string {
|
||||
@@ -140,7 +132,7 @@ func (*SetDNSConfigRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetDNSConfigRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -170,21 +162,18 @@ func (x *SetDNSConfigRequest) GetConfig() *DNSConfig {
|
||||
}
|
||||
|
||||
type SetDNSConfigResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Config *DNSConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
|
||||
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetDNSConfigResponse) Reset() {
|
||||
*x = SetDNSConfigResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetDNSConfigResponse) String() string {
|
||||
@@ -195,7 +184,7 @@ func (*SetDNSConfigResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetDNSConfigResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -225,26 +214,23 @@ func (x *SetDNSConfigResponse) GetMessage() string {
|
||||
}
|
||||
|
||||
type DNSConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MagicDns bool `protobuf:"varint,1,opt,name=magic_dns,json=magicDns,proto3" json:"magic_dns,omitempty"`
|
||||
OverrideLocalDns bool `protobuf:"varint,2,opt,name=override_local_dns,json=overrideLocalDns,proto3" json:"override_local_dns,omitempty"`
|
||||
Nameservers []string `protobuf:"bytes,3,rep,name=nameservers,proto3" json:"nameservers,omitempty"`
|
||||
Routes map[string]*Routes `protobuf:"bytes,4,rep,name=routes,proto3" json:"routes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Routes map[string]*Routes `protobuf:"bytes,4,rep,name=routes,proto3" json:"routes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
MagicDnsSuffix string `protobuf:"bytes,5,opt,name=magic_dns_suffix,json=magicDnsSuffix,proto3" json:"magic_dns_suffix,omitempty"`
|
||||
HttpsCerts bool `protobuf:"varint,6,opt,name=https_certs,json=httpsCerts,proto3" json:"https_certs,omitempty"`
|
||||
SearchDomains []string `protobuf:"bytes,7,rep,name=search_domains,json=searchDomains,proto3" json:"search_domains,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DNSConfig) Reset() {
|
||||
*x = DNSConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DNSConfig) String() string {
|
||||
@@ -255,7 +241,7 @@ func (*DNSConfig) ProtoMessage() {}
|
||||
|
||||
func (x *DNSConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -320,20 +306,17 @@ func (x *DNSConfig) GetSearchDomains() []string {
|
||||
}
|
||||
|
||||
type Routes struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Routes []string `protobuf:"bytes,1,rep,name=routes,proto3" json:"routes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Routes) Reset() {
|
||||
*x = Routes{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Routes) String() string {
|
||||
@@ -344,7 +327,7 @@ func (*Routes) ProtoMessage() {}
|
||||
|
||||
func (x *Routes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_dns_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -368,7 +351,7 @@ func (x *Routes) GetRoutes() []string {
|
||||
|
||||
var File_ionscale_v1_dns_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_dns_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_dns_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x6e,
|
||||
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x22, 0x34, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f,
|
||||
@@ -422,22 +405,22 @@ var file_ionscale_v1_dns_proto_rawDesc = []byte{
|
||||
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_dns_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_dns_proto_rawDescData = file_ionscale_v1_dns_proto_rawDesc
|
||||
file_ionscale_v1_dns_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_dns_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_dns_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_dns_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_dns_proto_rawDescData)
|
||||
file_ionscale_v1_dns_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_dns_proto_rawDesc), len(file_ionscale_v1_dns_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_dns_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_dns_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_ionscale_v1_dns_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_dns_proto_goTypes = []any{
|
||||
(*GetDNSConfigRequest)(nil), // 0: ionscale.v1.GetDNSConfigRequest
|
||||
(*GetDNSConfigResponse)(nil), // 1: ionscale.v1.GetDNSConfigResponse
|
||||
(*SetDNSConfigRequest)(nil), // 2: ionscale.v1.SetDNSConfigRequest
|
||||
@@ -464,85 +447,11 @@ func file_ionscale_v1_dns_proto_init() {
|
||||
if File_ionscale_v1_dns_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_dns_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetDNSConfigRequest); 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[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetDNSConfigResponse); 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[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetDNSConfigRequest); 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[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetDNSConfigResponse); 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[4].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[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Routes); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_dns_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_dns_proto_rawDesc), len(file_ionscale_v1_dns_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
@@ -553,7 +462,6 @@ func file_ionscale_v1_dns_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_dns_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_dns_proto = out.File
|
||||
file_ionscale_v1_dns_proto_rawDesc = nil
|
||||
file_ionscale_v1_dns_proto_goTypes = nil
|
||||
file_ionscale_v1_dns_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/iam.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,20 +22,17 @@ const (
|
||||
)
|
||||
|
||||
type GetIAMPolicyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetIAMPolicyRequest) Reset() {
|
||||
*x = GetIAMPolicyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_iam_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetIAMPolicyRequest) String() string {
|
||||
@@ -45,7 +43,7 @@ func (*GetIAMPolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetIAMPolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_iam_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -68,20 +66,17 @@ func (x *GetIAMPolicyRequest) GetTailnetId() uint64 {
|
||||
}
|
||||
|
||||
type GetIAMPolicyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Policy string `protobuf:"bytes,1,opt,name=policy,proto3" json:"policy,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetIAMPolicyResponse) Reset() {
|
||||
*x = GetIAMPolicyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_iam_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetIAMPolicyResponse) String() string {
|
||||
@@ -92,7 +87,7 @@ func (*GetIAMPolicyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetIAMPolicyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_iam_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -115,21 +110,18 @@ func (x *GetIAMPolicyResponse) GetPolicy() string {
|
||||
}
|
||||
|
||||
type SetIAMPolicyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
Policy string `protobuf:"bytes,2,opt,name=policy,proto3" json:"policy,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetIAMPolicyRequest) Reset() {
|
||||
*x = SetIAMPolicyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_iam_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetIAMPolicyRequest) String() string {
|
||||
@@ -140,7 +132,7 @@ func (*SetIAMPolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetIAMPolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_iam_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -170,18 +162,16 @@ func (x *SetIAMPolicyRequest) GetPolicy() string {
|
||||
}
|
||||
|
||||
type SetIAMPolicyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetIAMPolicyResponse) Reset() {
|
||||
*x = SetIAMPolicyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_iam_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetIAMPolicyResponse) String() string {
|
||||
@@ -192,7 +182,7 @@ func (*SetIAMPolicyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetIAMPolicyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_iam_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -209,7 +199,7 @@ func (*SetIAMPolicyResponse) Descriptor() ([]byte, []int) {
|
||||
|
||||
var File_ionscale_v1_iam_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_iam_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_iam_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x61,
|
||||
0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x22, 0x34, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x49, 0x41, 0x4d, 0x50, 0x6f,
|
||||
@@ -230,22 +220,22 @@ var file_ionscale_v1_iam_proto_rawDesc = []byte{
|
||||
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_iam_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_iam_proto_rawDescData = file_ionscale_v1_iam_proto_rawDesc
|
||||
file_ionscale_v1_iam_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_iam_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_iam_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_iam_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_iam_proto_rawDescData)
|
||||
file_ionscale_v1_iam_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_iam_proto_rawDesc), len(file_ionscale_v1_iam_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_iam_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_iam_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_ionscale_v1_iam_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_iam_proto_goTypes = []any{
|
||||
(*GetIAMPolicyRequest)(nil), // 0: ionscale.v1.GetIAMPolicyRequest
|
||||
(*GetIAMPolicyResponse)(nil), // 1: ionscale.v1.GetIAMPolicyResponse
|
||||
(*SetIAMPolicyRequest)(nil), // 2: ionscale.v1.SetIAMPolicyRequest
|
||||
@@ -264,61 +254,11 @@ func file_ionscale_v1_iam_proto_init() {
|
||||
if File_ionscale_v1_iam_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_iam_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetIAMPolicyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_iam_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetIAMPolicyResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_iam_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetIAMPolicyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_iam_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetIAMPolicyResponse); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_iam_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_iam_proto_rawDesc), len(file_ionscale_v1_iam_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
@@ -329,7 +269,6 @@ func file_ionscale_v1_iam_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_iam_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_iam_proto = out.File
|
||||
file_ionscale_v1_iam_proto_rawDesc = nil
|
||||
file_ionscale_v1_iam_proto_goTypes = nil
|
||||
file_ionscale_v1_iam_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
+179
-169
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/ionscale.proto
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,7 +22,7 @@ const (
|
||||
|
||||
var File_ionscale_v1_ionscale_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_ionscale_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x1a, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63,
|
||||
@@ -42,7 +43,7 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
|
||||
0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x32, 0xe2, 0x1e, 0x0a, 0x0f, 0x49, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65,
|
||||
0x6f, 0x32, 0xbf, 0x1f, 0x0a, 0x0f, 0x49, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
@@ -232,70 +233,76 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
|
||||
0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68,
|
||||
0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x24, 0x2e, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f,
|
||||
0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x45,
|
||||
0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x2e, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x4d,
|
||||
0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x2e, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68,
|
||||
0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23,
|
||||
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74,
|
||||
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
|
||||
0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x24, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
|
||||
0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
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,
|
||||
0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75,
|
||||
0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x69,
|
||||
0x72, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x4d, 0x61,
|
||||
0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x69, 0x72,
|
||||
0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68,
|
||||
0x69, 0x6e, 0x65, 0x12, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69,
|
||||
0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61,
|
||||
0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x6a, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79,
|
||||
0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x27, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b,
|
||||
0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65,
|
||||
0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x47,
|
||||
0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12,
|
||||
0x24, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a,
|
||||
0x0a, 0x13, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
|
||||
0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28,
|
||||
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61,
|
||||
0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x14, 0x44, 0x69,
|
||||
0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x73, 0x12, 0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x45, 0x6e, 0x61,
|
||||
0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x2e, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x13,
|
||||
0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x70,
|
||||
0x69, 0x72, 0x79, 0x12, 0x27, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x45,
|
||||
0x78, 0x70, 0x69, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x61,
|
||||
0x63, 0x68, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d,
|
||||
0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61,
|
||||
0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x13, 0x45,
|
||||
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x73, 0x12, 0x27, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
|
||||
0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x23, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45,
|
||||
0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24,
|
||||
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65, 0x6e, 0x73, 0x2f, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6f, 0x6e, 0x73, 0x63,
|
||||
0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x14, 0x44, 0x69, 0x73, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12,
|
||||
0x28, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69,
|
||||
0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d,
|
||||
0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
|
||||
0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63,
|
||||
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69,
|
||||
0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78,
|
||||
0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74,
|
||||
0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65, 0x6e, 0x73, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63,
|
||||
0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
|
||||
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
|
||||
var file_ionscale_v1_ionscale_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_ionscale_proto_goTypes = []any{
|
||||
(*GetVersionRequest)(nil), // 0: ionscale.v1.GetVersionRequest
|
||||
(*AuthenticateRequest)(nil), // 1: ionscale.v1.AuthenticateRequest
|
||||
(*GetDefaultDERPMapRequest)(nil), // 2: ionscale.v1.GetDefaultDERPMapRequest
|
||||
@@ -329,57 +336,59 @@ var file_ionscale_v1_ionscale_proto_goTypes = []interface{}{
|
||||
(*DeleteUserRequest)(nil), // 30: ionscale.v1.DeleteUserRequest
|
||||
(*GetMachineRequest)(nil), // 31: ionscale.v1.GetMachineRequest
|
||||
(*ListMachinesRequest)(nil), // 32: ionscale.v1.ListMachinesRequest
|
||||
(*AuthorizeMachineRequest)(nil), // 33: ionscale.v1.AuthorizeMachineRequest
|
||||
(*ExpireMachineRequest)(nil), // 34: ionscale.v1.ExpireMachineRequest
|
||||
(*DeleteMachineRequest)(nil), // 35: ionscale.v1.DeleteMachineRequest
|
||||
(*SetMachineKeyExpiryRequest)(nil), // 36: ionscale.v1.SetMachineKeyExpiryRequest
|
||||
(*GetMachineRoutesRequest)(nil), // 37: ionscale.v1.GetMachineRoutesRequest
|
||||
(*EnableMachineRoutesRequest)(nil), // 38: ionscale.v1.EnableMachineRoutesRequest
|
||||
(*DisableMachineRoutesRequest)(nil), // 39: ionscale.v1.DisableMachineRoutesRequest
|
||||
(*EnableExitNodeRequest)(nil), // 40: ionscale.v1.EnableExitNodeRequest
|
||||
(*DisableExitNodeRequest)(nil), // 41: ionscale.v1.DisableExitNodeRequest
|
||||
(*GetVersionResponse)(nil), // 42: ionscale.v1.GetVersionResponse
|
||||
(*AuthenticateResponse)(nil), // 43: ionscale.v1.AuthenticateResponse
|
||||
(*GetDefaultDERPMapResponse)(nil), // 44: ionscale.v1.GetDefaultDERPMapResponse
|
||||
(*CreateTailnetResponse)(nil), // 45: ionscale.v1.CreateTailnetResponse
|
||||
(*UpdateTailnetResponse)(nil), // 46: ionscale.v1.UpdateTailnetResponse
|
||||
(*GetTailnetResponse)(nil), // 47: ionscale.v1.GetTailnetResponse
|
||||
(*ListTailnetsResponse)(nil), // 48: ionscale.v1.ListTailnetsResponse
|
||||
(*DeleteTailnetResponse)(nil), // 49: ionscale.v1.DeleteTailnetResponse
|
||||
(*GetDERPMapResponse)(nil), // 50: ionscale.v1.GetDERPMapResponse
|
||||
(*SetDERPMapResponse)(nil), // 51: ionscale.v1.SetDERPMapResponse
|
||||
(*ResetDERPMapResponse)(nil), // 52: ionscale.v1.ResetDERPMapResponse
|
||||
(*EnableFileSharingResponse)(nil), // 53: ionscale.v1.EnableFileSharingResponse
|
||||
(*DisableFileSharingResponse)(nil), // 54: ionscale.v1.DisableFileSharingResponse
|
||||
(*EnableServiceCollectionResponse)(nil), // 55: ionscale.v1.EnableServiceCollectionResponse
|
||||
(*DisableServiceCollectionResponse)(nil), // 56: ionscale.v1.DisableServiceCollectionResponse
|
||||
(*EnableSSHResponse)(nil), // 57: ionscale.v1.EnableSSHResponse
|
||||
(*DisableSSHResponse)(nil), // 58: ionscale.v1.DisableSSHResponse
|
||||
(*EnableMachineAuthorizationResponse)(nil), // 59: ionscale.v1.EnableMachineAuthorizationResponse
|
||||
(*DisableMachineAuthorizationResponse)(nil), // 60: ionscale.v1.DisableMachineAuthorizationResponse
|
||||
(*GetDNSConfigResponse)(nil), // 61: ionscale.v1.GetDNSConfigResponse
|
||||
(*SetDNSConfigResponse)(nil), // 62: ionscale.v1.SetDNSConfigResponse
|
||||
(*GetIAMPolicyResponse)(nil), // 63: ionscale.v1.GetIAMPolicyResponse
|
||||
(*SetIAMPolicyResponse)(nil), // 64: ionscale.v1.SetIAMPolicyResponse
|
||||
(*GetACLPolicyResponse)(nil), // 65: ionscale.v1.GetACLPolicyResponse
|
||||
(*SetACLPolicyResponse)(nil), // 66: ionscale.v1.SetACLPolicyResponse
|
||||
(*GetAuthKeyResponse)(nil), // 67: ionscale.v1.GetAuthKeyResponse
|
||||
(*CreateAuthKeyResponse)(nil), // 68: ionscale.v1.CreateAuthKeyResponse
|
||||
(*DeleteAuthKeyResponse)(nil), // 69: ionscale.v1.DeleteAuthKeyResponse
|
||||
(*ListAuthKeysResponse)(nil), // 70: ionscale.v1.ListAuthKeysResponse
|
||||
(*ListUsersResponse)(nil), // 71: ionscale.v1.ListUsersResponse
|
||||
(*DeleteUserResponse)(nil), // 72: ionscale.v1.DeleteUserResponse
|
||||
(*GetMachineResponse)(nil), // 73: ionscale.v1.GetMachineResponse
|
||||
(*ListMachinesResponse)(nil), // 74: ionscale.v1.ListMachinesResponse
|
||||
(*AuthorizeMachineResponse)(nil), // 75: ionscale.v1.AuthorizeMachineResponse
|
||||
(*ExpireMachineResponse)(nil), // 76: ionscale.v1.ExpireMachineResponse
|
||||
(*DeleteMachineResponse)(nil), // 77: ionscale.v1.DeleteMachineResponse
|
||||
(*SetMachineKeyExpiryResponse)(nil), // 78: ionscale.v1.SetMachineKeyExpiryResponse
|
||||
(*GetMachineRoutesResponse)(nil), // 79: ionscale.v1.GetMachineRoutesResponse
|
||||
(*EnableMachineRoutesResponse)(nil), // 80: ionscale.v1.EnableMachineRoutesResponse
|
||||
(*DisableMachineRoutesResponse)(nil), // 81: ionscale.v1.DisableMachineRoutesResponse
|
||||
(*EnableExitNodeResponse)(nil), // 82: ionscale.v1.EnableExitNodeResponse
|
||||
(*DisableExitNodeResponse)(nil), // 83: ionscale.v1.DisableExitNodeResponse
|
||||
(*SetMachineNameRequest)(nil), // 33: ionscale.v1.SetMachineNameRequest
|
||||
(*AuthorizeMachineRequest)(nil), // 34: ionscale.v1.AuthorizeMachineRequest
|
||||
(*ExpireMachineRequest)(nil), // 35: ionscale.v1.ExpireMachineRequest
|
||||
(*DeleteMachineRequest)(nil), // 36: ionscale.v1.DeleteMachineRequest
|
||||
(*SetMachineKeyExpiryRequest)(nil), // 37: ionscale.v1.SetMachineKeyExpiryRequest
|
||||
(*GetMachineRoutesRequest)(nil), // 38: ionscale.v1.GetMachineRoutesRequest
|
||||
(*EnableMachineRoutesRequest)(nil), // 39: ionscale.v1.EnableMachineRoutesRequest
|
||||
(*DisableMachineRoutesRequest)(nil), // 40: ionscale.v1.DisableMachineRoutesRequest
|
||||
(*EnableExitNodeRequest)(nil), // 41: ionscale.v1.EnableExitNodeRequest
|
||||
(*DisableExitNodeRequest)(nil), // 42: ionscale.v1.DisableExitNodeRequest
|
||||
(*GetVersionResponse)(nil), // 43: ionscale.v1.GetVersionResponse
|
||||
(*AuthenticateResponse)(nil), // 44: ionscale.v1.AuthenticateResponse
|
||||
(*GetDefaultDERPMapResponse)(nil), // 45: ionscale.v1.GetDefaultDERPMapResponse
|
||||
(*CreateTailnetResponse)(nil), // 46: ionscale.v1.CreateTailnetResponse
|
||||
(*UpdateTailnetResponse)(nil), // 47: ionscale.v1.UpdateTailnetResponse
|
||||
(*GetTailnetResponse)(nil), // 48: ionscale.v1.GetTailnetResponse
|
||||
(*ListTailnetsResponse)(nil), // 49: ionscale.v1.ListTailnetsResponse
|
||||
(*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
|
||||
(*EnableMachineAuthorizationResponse)(nil), // 60: ionscale.v1.EnableMachineAuthorizationResponse
|
||||
(*DisableMachineAuthorizationResponse)(nil), // 61: ionscale.v1.DisableMachineAuthorizationResponse
|
||||
(*GetDNSConfigResponse)(nil), // 62: ionscale.v1.GetDNSConfigResponse
|
||||
(*SetDNSConfigResponse)(nil), // 63: ionscale.v1.SetDNSConfigResponse
|
||||
(*GetIAMPolicyResponse)(nil), // 64: ionscale.v1.GetIAMPolicyResponse
|
||||
(*SetIAMPolicyResponse)(nil), // 65: ionscale.v1.SetIAMPolicyResponse
|
||||
(*GetACLPolicyResponse)(nil), // 66: ionscale.v1.GetACLPolicyResponse
|
||||
(*SetACLPolicyResponse)(nil), // 67: ionscale.v1.SetACLPolicyResponse
|
||||
(*GetAuthKeyResponse)(nil), // 68: ionscale.v1.GetAuthKeyResponse
|
||||
(*CreateAuthKeyResponse)(nil), // 69: ionscale.v1.CreateAuthKeyResponse
|
||||
(*DeleteAuthKeyResponse)(nil), // 70: ionscale.v1.DeleteAuthKeyResponse
|
||||
(*ListAuthKeysResponse)(nil), // 71: ionscale.v1.ListAuthKeysResponse
|
||||
(*ListUsersResponse)(nil), // 72: ionscale.v1.ListUsersResponse
|
||||
(*DeleteUserResponse)(nil), // 73: ionscale.v1.DeleteUserResponse
|
||||
(*GetMachineResponse)(nil), // 74: ionscale.v1.GetMachineResponse
|
||||
(*ListMachinesResponse)(nil), // 75: ionscale.v1.ListMachinesResponse
|
||||
(*SetMachineNameResponse)(nil), // 76: ionscale.v1.SetMachineNameResponse
|
||||
(*AuthorizeMachineResponse)(nil), // 77: ionscale.v1.AuthorizeMachineResponse
|
||||
(*ExpireMachineResponse)(nil), // 78: ionscale.v1.ExpireMachineResponse
|
||||
(*DeleteMachineResponse)(nil), // 79: ionscale.v1.DeleteMachineResponse
|
||||
(*SetMachineKeyExpiryResponse)(nil), // 80: ionscale.v1.SetMachineKeyExpiryResponse
|
||||
(*GetMachineRoutesResponse)(nil), // 81: ionscale.v1.GetMachineRoutesResponse
|
||||
(*EnableMachineRoutesResponse)(nil), // 82: ionscale.v1.EnableMachineRoutesResponse
|
||||
(*DisableMachineRoutesResponse)(nil), // 83: ionscale.v1.DisableMachineRoutesResponse
|
||||
(*EnableExitNodeResponse)(nil), // 84: ionscale.v1.EnableExitNodeResponse
|
||||
(*DisableExitNodeResponse)(nil), // 85: ionscale.v1.DisableExitNodeResponse
|
||||
}
|
||||
var file_ionscale_v1_ionscale_proto_depIdxs = []int32{
|
||||
0, // 0: ionscale.v1.IonscaleService.GetVersion:input_type -> ionscale.v1.GetVersionRequest
|
||||
@@ -415,59 +424,61 @@ var file_ionscale_v1_ionscale_proto_depIdxs = []int32{
|
||||
30, // 30: ionscale.v1.IonscaleService.DeleteUser:input_type -> ionscale.v1.DeleteUserRequest
|
||||
31, // 31: ionscale.v1.IonscaleService.GetMachine:input_type -> ionscale.v1.GetMachineRequest
|
||||
32, // 32: ionscale.v1.IonscaleService.ListMachines:input_type -> ionscale.v1.ListMachinesRequest
|
||||
33, // 33: ionscale.v1.IonscaleService.AuthorizeMachine:input_type -> ionscale.v1.AuthorizeMachineRequest
|
||||
34, // 34: ionscale.v1.IonscaleService.ExpireMachine:input_type -> ionscale.v1.ExpireMachineRequest
|
||||
35, // 35: ionscale.v1.IonscaleService.DeleteMachine:input_type -> ionscale.v1.DeleteMachineRequest
|
||||
36, // 36: ionscale.v1.IonscaleService.SetMachineKeyExpiry:input_type -> ionscale.v1.SetMachineKeyExpiryRequest
|
||||
37, // 37: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest
|
||||
38, // 38: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest
|
||||
39, // 39: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest
|
||||
40, // 40: ionscale.v1.IonscaleService.EnableExitNode:input_type -> ionscale.v1.EnableExitNodeRequest
|
||||
41, // 41: ionscale.v1.IonscaleService.DisableExitNode:input_type -> ionscale.v1.DisableExitNodeRequest
|
||||
42, // 42: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse
|
||||
43, // 43: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticateResponse
|
||||
44, // 44: ionscale.v1.IonscaleService.GetDefaultDERPMap:output_type -> ionscale.v1.GetDefaultDERPMapResponse
|
||||
45, // 45: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse
|
||||
46, // 46: ionscale.v1.IonscaleService.UpdateTailnet:output_type -> ionscale.v1.UpdateTailnetResponse
|
||||
47, // 47: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse
|
||||
48, // 48: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetsResponse
|
||||
49, // 49: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse
|
||||
50, // 50: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse
|
||||
51, // 51: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse
|
||||
52, // 52: ionscale.v1.IonscaleService.ResetDERPMap:output_type -> ionscale.v1.ResetDERPMapResponse
|
||||
53, // 53: ionscale.v1.IonscaleService.EnableFileSharing:output_type -> ionscale.v1.EnableFileSharingResponse
|
||||
54, // 54: ionscale.v1.IonscaleService.DisableFileSharing:output_type -> ionscale.v1.DisableFileSharingResponse
|
||||
55, // 55: ionscale.v1.IonscaleService.EnableServiceCollection:output_type -> ionscale.v1.EnableServiceCollectionResponse
|
||||
56, // 56: ionscale.v1.IonscaleService.DisableServiceCollection:output_type -> ionscale.v1.DisableServiceCollectionResponse
|
||||
57, // 57: ionscale.v1.IonscaleService.EnableSSH:output_type -> ionscale.v1.EnableSSHResponse
|
||||
58, // 58: ionscale.v1.IonscaleService.DisableSSH:output_type -> ionscale.v1.DisableSSHResponse
|
||||
59, // 59: ionscale.v1.IonscaleService.EnableMachineAuthorization:output_type -> ionscale.v1.EnableMachineAuthorizationResponse
|
||||
60, // 60: ionscale.v1.IonscaleService.DisableMachineAuthorization:output_type -> ionscale.v1.DisableMachineAuthorizationResponse
|
||||
61, // 61: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse
|
||||
62, // 62: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse
|
||||
63, // 63: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse
|
||||
64, // 64: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse
|
||||
65, // 65: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse
|
||||
66, // 66: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse
|
||||
67, // 67: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse
|
||||
68, // 68: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse
|
||||
69, // 69: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse
|
||||
70, // 70: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse
|
||||
71, // 71: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse
|
||||
72, // 72: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse
|
||||
73, // 73: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse
|
||||
74, // 74: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse
|
||||
75, // 75: ionscale.v1.IonscaleService.AuthorizeMachine:output_type -> ionscale.v1.AuthorizeMachineResponse
|
||||
76, // 76: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse
|
||||
77, // 77: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse
|
||||
78, // 78: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse
|
||||
79, // 79: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
|
||||
80, // 80: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.EnableMachineRoutesResponse
|
||||
81, // 81: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.DisableMachineRoutesResponse
|
||||
82, // 82: ionscale.v1.IonscaleService.EnableExitNode:output_type -> ionscale.v1.EnableExitNodeResponse
|
||||
83, // 83: ionscale.v1.IonscaleService.DisableExitNode:output_type -> ionscale.v1.DisableExitNodeResponse
|
||||
42, // [42:84] is the sub-list for method output_type
|
||||
0, // [0:42] is the sub-list for method input_type
|
||||
33, // 33: ionscale.v1.IonscaleService.SetMachineName:input_type -> ionscale.v1.SetMachineNameRequest
|
||||
34, // 34: ionscale.v1.IonscaleService.AuthorizeMachine:input_type -> ionscale.v1.AuthorizeMachineRequest
|
||||
35, // 35: ionscale.v1.IonscaleService.ExpireMachine:input_type -> ionscale.v1.ExpireMachineRequest
|
||||
36, // 36: ionscale.v1.IonscaleService.DeleteMachine:input_type -> ionscale.v1.DeleteMachineRequest
|
||||
37, // 37: ionscale.v1.IonscaleService.SetMachineKeyExpiry:input_type -> ionscale.v1.SetMachineKeyExpiryRequest
|
||||
38, // 38: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest
|
||||
39, // 39: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest
|
||||
40, // 40: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest
|
||||
41, // 41: ionscale.v1.IonscaleService.EnableExitNode:input_type -> ionscale.v1.EnableExitNodeRequest
|
||||
42, // 42: ionscale.v1.IonscaleService.DisableExitNode:input_type -> ionscale.v1.DisableExitNodeRequest
|
||||
43, // 43: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse
|
||||
44, // 44: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticateResponse
|
||||
45, // 45: ionscale.v1.IonscaleService.GetDefaultDERPMap:output_type -> ionscale.v1.GetDefaultDERPMapResponse
|
||||
46, // 46: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse
|
||||
47, // 47: ionscale.v1.IonscaleService.UpdateTailnet:output_type -> ionscale.v1.UpdateTailnetResponse
|
||||
48, // 48: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse
|
||||
49, // 49: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetsResponse
|
||||
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.EnableFileSharing:output_type -> ionscale.v1.EnableFileSharingResponse
|
||||
55, // 55: ionscale.v1.IonscaleService.DisableFileSharing:output_type -> ionscale.v1.DisableFileSharingResponse
|
||||
56, // 56: ionscale.v1.IonscaleService.EnableServiceCollection:output_type -> ionscale.v1.EnableServiceCollectionResponse
|
||||
57, // 57: ionscale.v1.IonscaleService.DisableServiceCollection:output_type -> ionscale.v1.DisableServiceCollectionResponse
|
||||
58, // 58: ionscale.v1.IonscaleService.EnableSSH:output_type -> ionscale.v1.EnableSSHResponse
|
||||
59, // 59: ionscale.v1.IonscaleService.DisableSSH:output_type -> ionscale.v1.DisableSSHResponse
|
||||
60, // 60: ionscale.v1.IonscaleService.EnableMachineAuthorization:output_type -> ionscale.v1.EnableMachineAuthorizationResponse
|
||||
61, // 61: ionscale.v1.IonscaleService.DisableMachineAuthorization:output_type -> ionscale.v1.DisableMachineAuthorizationResponse
|
||||
62, // 62: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse
|
||||
63, // 63: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse
|
||||
64, // 64: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse
|
||||
65, // 65: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse
|
||||
66, // 66: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse
|
||||
67, // 67: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse
|
||||
68, // 68: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse
|
||||
69, // 69: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse
|
||||
70, // 70: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse
|
||||
71, // 71: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse
|
||||
72, // 72: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse
|
||||
73, // 73: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse
|
||||
74, // 74: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse
|
||||
75, // 75: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse
|
||||
76, // 76: ionscale.v1.IonscaleService.SetMachineName:output_type -> ionscale.v1.SetMachineNameResponse
|
||||
77, // 77: ionscale.v1.IonscaleService.AuthorizeMachine:output_type -> ionscale.v1.AuthorizeMachineResponse
|
||||
78, // 78: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse
|
||||
79, // 79: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse
|
||||
80, // 80: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse
|
||||
81, // 81: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
|
||||
82, // 82: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.EnableMachineRoutesResponse
|
||||
83, // 83: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.DisableMachineRoutesResponse
|
||||
84, // 84: ionscale.v1.IonscaleService.EnableExitNode:output_type -> ionscale.v1.EnableExitNodeResponse
|
||||
85, // 85: ionscale.v1.IonscaleService.DisableExitNode:output_type -> ionscale.v1.DisableExitNodeResponse
|
||||
43, // [43:86] is the sub-list for method output_type
|
||||
0, // [0:43] is the sub-list for method input_type
|
||||
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
|
||||
@@ -493,7 +504,7 @@ func file_ionscale_v1_ionscale_proto_init() {
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_ionscale_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_ionscale_proto_rawDesc), len(file_ionscale_v1_ionscale_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
@@ -503,7 +514,6 @@ func file_ionscale_v1_ionscale_proto_init() {
|
||||
DependencyIndexes: file_ionscale_v1_ionscale_proto_depIdxs,
|
||||
}.Build()
|
||||
File_ionscale_v1_ionscale_proto = out.File
|
||||
file_ionscale_v1_ionscale_proto_rawDesc = nil
|
||||
file_ionscale_v1_ionscale_proto_goTypes = nil
|
||||
file_ionscale_v1_ionscale_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -132,6 +132,9 @@ const (
|
||||
// IonscaleServiceListMachinesProcedure is the fully-qualified name of the IonscaleService's
|
||||
// ListMachines RPC.
|
||||
IonscaleServiceListMachinesProcedure = "/ionscale.v1.IonscaleService/ListMachines"
|
||||
// IonscaleServiceSetMachineNameProcedure is the fully-qualified name of the IonscaleService's
|
||||
// SetMachineName RPC.
|
||||
IonscaleServiceSetMachineNameProcedure = "/ionscale.v1.IonscaleService/SetMachineName"
|
||||
// IonscaleServiceAuthorizeMachineProcedure is the fully-qualified name of the IonscaleService's
|
||||
// AuthorizeMachine RPC.
|
||||
IonscaleServiceAuthorizeMachineProcedure = "/ionscale.v1.IonscaleService/AuthorizeMachine"
|
||||
@@ -196,6 +199,7 @@ type IonscaleServiceClient interface {
|
||||
DeleteUser(context.Context, *connect_go.Request[v1.DeleteUserRequest]) (*connect_go.Response[v1.DeleteUserResponse], error)
|
||||
GetMachine(context.Context, *connect_go.Request[v1.GetMachineRequest]) (*connect_go.Response[v1.GetMachineResponse], error)
|
||||
ListMachines(context.Context, *connect_go.Request[v1.ListMachinesRequest]) (*connect_go.Response[v1.ListMachinesResponse], error)
|
||||
SetMachineName(context.Context, *connect_go.Request[v1.SetMachineNameRequest]) (*connect_go.Response[v1.SetMachineNameResponse], error)
|
||||
AuthorizeMachine(context.Context, *connect_go.Request[v1.AuthorizeMachineRequest]) (*connect_go.Response[v1.AuthorizeMachineResponse], error)
|
||||
ExpireMachine(context.Context, *connect_go.Request[v1.ExpireMachineRequest]) (*connect_go.Response[v1.ExpireMachineResponse], error)
|
||||
DeleteMachine(context.Context, *connect_go.Request[v1.DeleteMachineRequest]) (*connect_go.Response[v1.DeleteMachineResponse], error)
|
||||
@@ -382,6 +386,11 @@ func NewIonscaleServiceClient(httpClient connect_go.HTTPClient, baseURL string,
|
||||
baseURL+IonscaleServiceListMachinesProcedure,
|
||||
opts...,
|
||||
),
|
||||
setMachineName: connect_go.NewClient[v1.SetMachineNameRequest, v1.SetMachineNameResponse](
|
||||
httpClient,
|
||||
baseURL+IonscaleServiceSetMachineNameProcedure,
|
||||
opts...,
|
||||
),
|
||||
authorizeMachine: connect_go.NewClient[v1.AuthorizeMachineRequest, v1.AuthorizeMachineResponse](
|
||||
httpClient,
|
||||
baseURL+IonscaleServiceAuthorizeMachineProcedure,
|
||||
@@ -465,6 +474,7 @@ type ionscaleServiceClient struct {
|
||||
deleteUser *connect_go.Client[v1.DeleteUserRequest, v1.DeleteUserResponse]
|
||||
getMachine *connect_go.Client[v1.GetMachineRequest, v1.GetMachineResponse]
|
||||
listMachines *connect_go.Client[v1.ListMachinesRequest, v1.ListMachinesResponse]
|
||||
setMachineName *connect_go.Client[v1.SetMachineNameRequest, v1.SetMachineNameResponse]
|
||||
authorizeMachine *connect_go.Client[v1.AuthorizeMachineRequest, v1.AuthorizeMachineResponse]
|
||||
expireMachine *connect_go.Client[v1.ExpireMachineRequest, v1.ExpireMachineResponse]
|
||||
deleteMachine *connect_go.Client[v1.DeleteMachineRequest, v1.DeleteMachineResponse]
|
||||
@@ -641,6 +651,11 @@ func (c *ionscaleServiceClient) ListMachines(ctx context.Context, req *connect_g
|
||||
return c.listMachines.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// SetMachineName calls ionscale.v1.IonscaleService.SetMachineName.
|
||||
func (c *ionscaleServiceClient) SetMachineName(ctx context.Context, req *connect_go.Request[v1.SetMachineNameRequest]) (*connect_go.Response[v1.SetMachineNameResponse], error) {
|
||||
return c.setMachineName.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// AuthorizeMachine calls ionscale.v1.IonscaleService.AuthorizeMachine.
|
||||
func (c *ionscaleServiceClient) AuthorizeMachine(ctx context.Context, req *connect_go.Request[v1.AuthorizeMachineRequest]) (*connect_go.Response[v1.AuthorizeMachineResponse], error) {
|
||||
return c.authorizeMachine.CallUnary(ctx, req)
|
||||
@@ -721,6 +736,7 @@ type IonscaleServiceHandler interface {
|
||||
DeleteUser(context.Context, *connect_go.Request[v1.DeleteUserRequest]) (*connect_go.Response[v1.DeleteUserResponse], error)
|
||||
GetMachine(context.Context, *connect_go.Request[v1.GetMachineRequest]) (*connect_go.Response[v1.GetMachineResponse], error)
|
||||
ListMachines(context.Context, *connect_go.Request[v1.ListMachinesRequest]) (*connect_go.Response[v1.ListMachinesResponse], error)
|
||||
SetMachineName(context.Context, *connect_go.Request[v1.SetMachineNameRequest]) (*connect_go.Response[v1.SetMachineNameResponse], error)
|
||||
AuthorizeMachine(context.Context, *connect_go.Request[v1.AuthorizeMachineRequest]) (*connect_go.Response[v1.AuthorizeMachineResponse], error)
|
||||
ExpireMachine(context.Context, *connect_go.Request[v1.ExpireMachineRequest]) (*connect_go.Response[v1.ExpireMachineResponse], error)
|
||||
DeleteMachine(context.Context, *connect_go.Request[v1.DeleteMachineRequest]) (*connect_go.Response[v1.DeleteMachineResponse], error)
|
||||
@@ -903,6 +919,11 @@ func NewIonscaleServiceHandler(svc IonscaleServiceHandler, opts ...connect_go.Ha
|
||||
svc.ListMachines,
|
||||
opts...,
|
||||
)
|
||||
ionscaleServiceSetMachineNameHandler := connect_go.NewUnaryHandler(
|
||||
IonscaleServiceSetMachineNameProcedure,
|
||||
svc.SetMachineName,
|
||||
opts...,
|
||||
)
|
||||
ionscaleServiceAuthorizeMachineHandler := connect_go.NewUnaryHandler(
|
||||
IonscaleServiceAuthorizeMachineProcedure,
|
||||
svc.AuthorizeMachine,
|
||||
@@ -1016,6 +1037,8 @@ func NewIonscaleServiceHandler(svc IonscaleServiceHandler, opts ...connect_go.Ha
|
||||
ionscaleServiceGetMachineHandler.ServeHTTP(w, r)
|
||||
case IonscaleServiceListMachinesProcedure:
|
||||
ionscaleServiceListMachinesHandler.ServeHTTP(w, r)
|
||||
case IonscaleServiceSetMachineNameProcedure:
|
||||
ionscaleServiceSetMachineNameHandler.ServeHTTP(w, r)
|
||||
case IonscaleServiceAuthorizeMachineProcedure:
|
||||
ionscaleServiceAuthorizeMachineHandler.ServeHTTP(w, r)
|
||||
case IonscaleServiceExpireMachineProcedure:
|
||||
@@ -1175,6 +1198,10 @@ func (UnimplementedIonscaleServiceHandler) ListMachines(context.Context, *connec
|
||||
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.ListMachines is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedIonscaleServiceHandler) SetMachineName(context.Context, *connect_go.Request[v1.SetMachineNameRequest]) (*connect_go.Response[v1.SetMachineNameResponse], error) {
|
||||
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.SetMachineName is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedIonscaleServiceHandler) AuthorizeMachine(context.Context, *connect_go.Request[v1.AuthorizeMachineRequest]) (*connect_go.Response[v1.AuthorizeMachineResponse], error) {
|
||||
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.AuthorizeMachine is not implemented"))
|
||||
}
|
||||
|
||||
+244
-345
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/machines.proto
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -22,20 +23,17 @@ const (
|
||||
)
|
||||
|
||||
type ListMachinesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListMachinesRequest) Reset() {
|
||||
*x = ListMachinesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListMachinesRequest) String() string {
|
||||
@@ -46,7 +44,7 @@ func (*ListMachinesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListMachinesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -69,20 +67,17 @@ func (x *ListMachinesRequest) GetTailnetId() uint64 {
|
||||
}
|
||||
|
||||
type ListMachinesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Machines []*Machine `protobuf:"bytes,1,rep,name=machines,proto3" json:"machines,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListMachinesResponse) Reset() {
|
||||
*x = ListMachinesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListMachinesResponse) String() string {
|
||||
@@ -93,7 +88,7 @@ func (*ListMachinesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListMachinesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -116,20 +111,17 @@ func (x *ListMachinesResponse) GetMachines() []*Machine {
|
||||
}
|
||||
|
||||
type DeleteMachineRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteMachineRequest) Reset() {
|
||||
*x = DeleteMachineRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteMachineRequest) String() string {
|
||||
@@ -140,7 +132,7 @@ func (*DeleteMachineRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteMachineRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -163,18 +155,16 @@ func (x *DeleteMachineRequest) GetMachineId() uint64 {
|
||||
}
|
||||
|
||||
type DeleteMachineResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteMachineResponse) Reset() {
|
||||
*x = DeleteMachineResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteMachineResponse) String() string {
|
||||
@@ -185,7 +175,7 @@ func (*DeleteMachineResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteMachineResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -201,20 +191,17 @@ func (*DeleteMachineResponse) Descriptor() ([]byte, []int) {
|
||||
}
|
||||
|
||||
type ExpireMachineRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ExpireMachineRequest) Reset() {
|
||||
*x = ExpireMachineRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExpireMachineRequest) String() string {
|
||||
@@ -225,7 +212,7 @@ func (*ExpireMachineRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ExpireMachineRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -248,18 +235,16 @@ func (x *ExpireMachineRequest) GetMachineId() uint64 {
|
||||
}
|
||||
|
||||
type ExpireMachineResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ExpireMachineResponse) Reset() {
|
||||
*x = ExpireMachineResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExpireMachineResponse) String() string {
|
||||
@@ -270,7 +255,7 @@ func (*ExpireMachineResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ExpireMachineResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -286,21 +271,18 @@ func (*ExpireMachineResponse) Descriptor() ([]byte, []int) {
|
||||
}
|
||||
|
||||
type SetMachineKeyExpiryRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
Disabled bool `protobuf:"varint,2,opt,name=disabled,proto3" json:"disabled,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetMachineKeyExpiryRequest) Reset() {
|
||||
*x = SetMachineKeyExpiryRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetMachineKeyExpiryRequest) String() string {
|
||||
@@ -311,7 +293,7 @@ func (*SetMachineKeyExpiryRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetMachineKeyExpiryRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -341,18 +323,16 @@ func (x *SetMachineKeyExpiryRequest) GetDisabled() bool {
|
||||
}
|
||||
|
||||
type SetMachineKeyExpiryResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetMachineKeyExpiryResponse) Reset() {
|
||||
*x = SetMachineKeyExpiryResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SetMachineKeyExpiryResponse) String() string {
|
||||
@@ -363,7 +343,7 @@ func (*SetMachineKeyExpiryResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetMachineKeyExpiryResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -379,20 +359,17 @@ func (*SetMachineKeyExpiryResponse) Descriptor() ([]byte, []int) {
|
||||
}
|
||||
|
||||
type GetMachineRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetMachineRequest) Reset() {
|
||||
*x = GetMachineRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetMachineRequest) String() string {
|
||||
@@ -403,7 +380,7 @@ func (*GetMachineRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetMachineRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -426,20 +403,17 @@ func (x *GetMachineRequest) GetMachineId() uint64 {
|
||||
}
|
||||
|
||||
type GetMachineResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Machine *Machine `protobuf:"bytes,1,opt,name=machine,proto3" json:"machine,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetMachineResponse) Reset() {
|
||||
*x = GetMachineResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetMachineResponse) String() string {
|
||||
@@ -450,7 +424,7 @@ func (*GetMachineResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetMachineResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -473,20 +447,17 @@ func (x *GetMachineResponse) GetMachine() *Machine {
|
||||
}
|
||||
|
||||
type AuthorizeMachineRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthorizeMachineRequest) Reset() {
|
||||
*x = AuthorizeMachineRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthorizeMachineRequest) String() string {
|
||||
@@ -497,7 +468,7 @@ func (*AuthorizeMachineRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AuthorizeMachineRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -520,18 +491,16 @@ func (x *AuthorizeMachineRequest) GetMachineId() uint64 {
|
||||
}
|
||||
|
||||
type AuthorizeMachineResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthorizeMachineResponse) Reset() {
|
||||
*x = AuthorizeMachineResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthorizeMachineResponse) String() string {
|
||||
@@ -542,7 +511,7 @@ func (*AuthorizeMachineResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AuthorizeMachineResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -557,11 +526,104 @@ func (*AuthorizeMachineResponse) Descriptor() ([]byte, []int) {
|
||||
return file_ionscale_v1_machines_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
type Machine struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
type SetMachineNameRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
UseOsHostname bool `protobuf:"varint,2,opt,name=use_os_hostname,json=useOsHostname,proto3" json:"use_os_hostname,omitempty"`
|
||||
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetMachineNameRequest) Reset() {
|
||||
*x = SetMachineNameRequest{}
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SetMachineNameRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetMachineNameRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetMachineNameRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[12]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SetMachineNameRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SetMachineNameRequest) Descriptor() ([]byte, []int) {
|
||||
return file_ionscale_v1_machines_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
func (x *SetMachineNameRequest) GetMachineId() uint64 {
|
||||
if x != nil {
|
||||
return x.MachineId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SetMachineNameRequest) GetUseOsHostname() bool {
|
||||
if x != nil {
|
||||
return x.UseOsHostname
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *SetMachineNameRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SetMachineNameResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetMachineNameResponse) Reset() {
|
||||
*x = SetMachineNameResponse{}
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[13]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SetMachineNameResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetMachineNameResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetMachineNameResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[13]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SetMachineNameResponse.ProtoReflect.Descriptor instead.
|
||||
func (*SetMachineNameResponse) Descriptor() ([]byte, []int) {
|
||||
return file_ionscale_v1_machines_proto_rawDescGZIP(), []int{13}
|
||||
}
|
||||
|
||||
type Machine struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Ipv4 string `protobuf:"bytes,3,opt,name=ipv4,proto3" json:"ipv4,omitempty"`
|
||||
@@ -583,15 +645,15 @@ type Machine struct {
|
||||
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"`
|
||||
Authorized bool `protobuf:"varint,21,opt,name=authorized,proto3" json:"authorized,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Machine) Reset() {
|
||||
*x = Machine{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[12]
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[14]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Machine) String() string {
|
||||
@@ -601,8 +663,8 @@ func (x *Machine) String() string {
|
||||
func (*Machine) ProtoMessage() {}
|
||||
|
||||
func (x *Machine) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[12]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[14]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -614,7 +676,7 @@ func (x *Machine) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Machine.ProtoReflect.Descriptor instead.
|
||||
func (*Machine) Descriptor() ([]byte, []int) {
|
||||
return file_ionscale_v1_machines_proto_rawDescGZIP(), []int{12}
|
||||
return file_ionscale_v1_machines_proto_rawDescGZIP(), []int{14}
|
||||
}
|
||||
|
||||
func (x *Machine) GetId() uint64 {
|
||||
@@ -765,20 +827,17 @@ func (x *Machine) GetAuthorized() bool {
|
||||
}
|
||||
|
||||
type ClientConnectivity struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Endpoints []string `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ClientConnectivity) Reset() {
|
||||
*x = ClientConnectivity{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[13]
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[15]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ClientConnectivity) String() string {
|
||||
@@ -788,8 +847,8 @@ func (x *ClientConnectivity) String() string {
|
||||
func (*ClientConnectivity) ProtoMessage() {}
|
||||
|
||||
func (x *ClientConnectivity) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[13]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
mi := &file_ionscale_v1_machines_proto_msgTypes[15]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -801,7 +860,7 @@ func (x *ClientConnectivity) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ClientConnectivity.ProtoReflect.Descriptor instead.
|
||||
func (*ClientConnectivity) Descriptor() ([]byte, []int) {
|
||||
return file_ionscale_v1_machines_proto_rawDescGZIP(), []int{13}
|
||||
return file_ionscale_v1_machines_proto_rawDescGZIP(), []int{15}
|
||||
}
|
||||
|
||||
func (x *ClientConnectivity) GetEndpoints() []string {
|
||||
@@ -813,7 +872,7 @@ func (x *ClientConnectivity) GetEndpoints() []string {
|
||||
|
||||
var File_ionscale_v1_machines_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_machines_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_machines_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x1a, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61,
|
||||
0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
@@ -858,82 +917,91 @@ var file_ionscale_v1_machines_proto_rawDesc = []byte{
|
||||
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, 0x1a, 0x0a,
|
||||
0x18, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb1, 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, 0x09, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x69, 0x70, 0x76, 0x36, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x70, 0x76,
|
||||
0x36, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x12,
|
||||
0x37, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x72, 0x0a, 0x15, 0x53, 0x65, 0x74,
|
||||
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 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, 0x12, 0x26, 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x68, 0x6f, 0x73, 0x74,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x4f,
|
||||
0x73, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x18, 0x0a,
|
||||
0x16, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb1, 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, 0x09, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x12, 0x0a, 0x04, 0x69,
|
||||
0x70, 0x76, 0x36, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x70, 0x76, 0x36, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x09, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x37, 0x0a,
|
||||
0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x6c, 0x61,
|
||||
0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
|
||||
0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
|
||||
0x63, 0x74, 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
|
||||
0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
|
||||
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66,
|
||||
0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x0a,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c,
|
||||
0x69, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f,
|
||||
0x73, 0x12, 0x50, 0x0a, 0x13, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x6e,
|
||||
0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,
|
||||
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52,
|
||||
0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76,
|
||||
0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61,
|
||||
0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39,
|
||||
0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x0f, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08,
|
||||
0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e,
|
||||
0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6e,
|
||||
0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65,
|
||||
0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
|
||||
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e,
|
||||
0x65, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x10, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52,
|
||||
0x65, 0x66, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73,
|
||||
0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e,
|
||||
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x02, 0x6f, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f,
|
||||
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09,
|
||||
0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x6b, 0x65, 0x79,
|
||||
0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64,
|
||||
0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x69, 0x72,
|
||||
0x79, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e, 0x61,
|
||||
0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x0d, 0x65, 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, 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, 0x12, 0x1e, 0x0a, 0x0a, 0x61,
|
||||
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x22, 0x32, 0x0a, 0x12, 0x43,
|
||||
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74,
|
||||
0x79, 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
|
||||
0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
|
||||
0x5f, 0x61, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
|
||||
0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x0f,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x6b,
|
||||
0x65, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x45, 0x78, 0x70,
|
||||
0x69, 0x72, 0x79, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x65,
|
||||
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x11, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 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, 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, 0x12, 0x1e, 0x0a,
|
||||
0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 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,
|
||||
}
|
||||
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 (
|
||||
file_ionscale_v1_machines_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_machines_proto_rawDescData = file_ionscale_v1_machines_proto_rawDesc
|
||||
file_ionscale_v1_machines_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_machines_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_machines_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_machines_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_machines_proto_rawDescData)
|
||||
file_ionscale_v1_machines_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_machines_proto_rawDesc), len(file_ionscale_v1_machines_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_machines_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_machines_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
||||
var file_ionscale_v1_machines_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_machines_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
|
||||
var file_ionscale_v1_machines_proto_goTypes = []any{
|
||||
(*ListMachinesRequest)(nil), // 0: ionscale.v1.ListMachinesRequest
|
||||
(*ListMachinesResponse)(nil), // 1: ionscale.v1.ListMachinesResponse
|
||||
(*DeleteMachineRequest)(nil), // 2: ionscale.v1.DeleteMachineRequest
|
||||
@@ -946,20 +1014,22 @@ var file_ionscale_v1_machines_proto_goTypes = []interface{}{
|
||||
(*GetMachineResponse)(nil), // 9: ionscale.v1.GetMachineResponse
|
||||
(*AuthorizeMachineRequest)(nil), // 10: ionscale.v1.AuthorizeMachineRequest
|
||||
(*AuthorizeMachineResponse)(nil), // 11: ionscale.v1.AuthorizeMachineResponse
|
||||
(*Machine)(nil), // 12: ionscale.v1.Machine
|
||||
(*ClientConnectivity)(nil), // 13: ionscale.v1.ClientConnectivity
|
||||
(*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp
|
||||
(*Ref)(nil), // 15: ionscale.v1.Ref
|
||||
(*SetMachineNameRequest)(nil), // 12: ionscale.v1.SetMachineNameRequest
|
||||
(*SetMachineNameResponse)(nil), // 13: ionscale.v1.SetMachineNameResponse
|
||||
(*Machine)(nil), // 14: ionscale.v1.Machine
|
||||
(*ClientConnectivity)(nil), // 15: ionscale.v1.ClientConnectivity
|
||||
(*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp
|
||||
(*Ref)(nil), // 17: ionscale.v1.Ref
|
||||
}
|
||||
var file_ionscale_v1_machines_proto_depIdxs = []int32{
|
||||
12, // 0: ionscale.v1.ListMachinesResponse.machines:type_name -> ionscale.v1.Machine
|
||||
12, // 1: ionscale.v1.GetMachineResponse.machine:type_name -> ionscale.v1.Machine
|
||||
14, // 2: ionscale.v1.Machine.last_seen:type_name -> google.protobuf.Timestamp
|
||||
15, // 3: ionscale.v1.Machine.tailnet:type_name -> ionscale.v1.Ref
|
||||
15, // 4: ionscale.v1.Machine.user:type_name -> ionscale.v1.Ref
|
||||
13, // 5: ionscale.v1.Machine.client_connectivity:type_name -> ionscale.v1.ClientConnectivity
|
||||
14, // 6: ionscale.v1.Machine.created_at:type_name -> google.protobuf.Timestamp
|
||||
14, // 7: ionscale.v1.Machine.expires_at:type_name -> google.protobuf.Timestamp
|
||||
14, // 0: ionscale.v1.ListMachinesResponse.machines:type_name -> ionscale.v1.Machine
|
||||
14, // 1: ionscale.v1.GetMachineResponse.machine:type_name -> ionscale.v1.Machine
|
||||
16, // 2: ionscale.v1.Machine.last_seen:type_name -> google.protobuf.Timestamp
|
||||
17, // 3: ionscale.v1.Machine.tailnet:type_name -> ionscale.v1.Ref
|
||||
17, // 4: ionscale.v1.Machine.user:type_name -> ionscale.v1.Ref
|
||||
15, // 5: ionscale.v1.Machine.client_connectivity:type_name -> ionscale.v1.ClientConnectivity
|
||||
16, // 6: ionscale.v1.Machine.created_at:type_name -> google.protobuf.Timestamp
|
||||
16, // 7: ionscale.v1.Machine.expires_at:type_name -> google.protobuf.Timestamp
|
||||
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
|
||||
@@ -973,183 +1043,13 @@ func file_ionscale_v1_machines_proto_init() {
|
||||
return
|
||||
}
|
||||
file_ionscale_v1_ref_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_machines_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListMachinesRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListMachinesResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteMachineRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteMachineResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExpireMachineRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExpireMachineResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetMachineKeyExpiryRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SetMachineKeyExpiryResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetMachineRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetMachineResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthorizeMachineRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthorizeMachineResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Machine); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_machines_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ClientConnectivity); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_machines_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_machines_proto_rawDesc), len(file_ionscale_v1_machines_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 14,
|
||||
NumMessages: 16,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
@@ -1158,7 +1058,6 @@ func file_ionscale_v1_machines_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_machines_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_machines_proto = out.File
|
||||
file_ionscale_v1_machines_proto_rawDesc = nil
|
||||
file_ionscale_v1_machines_proto_goTypes = nil
|
||||
file_ionscale_v1_machines_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/ref.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,21 +22,18 @@ const (
|
||||
)
|
||||
|
||||
type Ref struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Ref) Reset() {
|
||||
*x = Ref{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_ref_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Ref) String() string {
|
||||
@@ -46,7 +44,7 @@ func (*Ref) ProtoMessage() {}
|
||||
|
||||
func (x *Ref) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_ref_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -77,7 +75,7 @@ func (x *Ref) GetName() string {
|
||||
|
||||
var File_ionscale_v1_ref_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_ref_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_ref_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65,
|
||||
0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x22, 0x29, 0x0a, 0x03, 0x52, 0x65, 0x66, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
@@ -88,22 +86,22 @@ var file_ionscale_v1_ref_proto_rawDesc = []byte{
|
||||
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_ref_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_ref_proto_rawDescData = file_ionscale_v1_ref_proto_rawDesc
|
||||
file_ionscale_v1_ref_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_ref_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_ref_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_ref_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_ref_proto_rawDescData)
|
||||
file_ionscale_v1_ref_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_ref_proto_rawDesc), len(file_ionscale_v1_ref_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_ref_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_ref_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_ionscale_v1_ref_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_ref_proto_goTypes = []any{
|
||||
(*Ref)(nil), // 0: ionscale.v1.Ref
|
||||
}
|
||||
var file_ionscale_v1_ref_proto_depIdxs = []int32{
|
||||
@@ -119,25 +117,11 @@ func file_ionscale_v1_ref_proto_init() {
|
||||
if File_ionscale_v1_ref_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_ref_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Ref); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_ref_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_ref_proto_rawDesc), len(file_ionscale_v1_ref_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
@@ -148,7 +132,6 @@ func file_ionscale_v1_ref_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_ref_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_ref_proto = out.File
|
||||
file_ionscale_v1_ref_proto_rawDesc = nil
|
||||
file_ionscale_v1_ref_proto_goTypes = nil
|
||||
file_ionscale_v1_ref_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/routes.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,20 +22,17 @@ const (
|
||||
)
|
||||
|
||||
type GetMachineRoutesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetMachineRoutesRequest) Reset() {
|
||||
*x = GetMachineRoutesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetMachineRoutesRequest) String() string {
|
||||
@@ -45,7 +43,7 @@ func (*GetMachineRoutesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetMachineRoutesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -68,21 +66,18 @@ func (x *GetMachineRoutesRequest) GetMachineId() uint64 {
|
||||
}
|
||||
|
||||
type GetMachineRoutesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
Routes *MachineRoutes `protobuf:"bytes,2,opt,name=routes,proto3" json:"routes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetMachineRoutesResponse) Reset() {
|
||||
*x = GetMachineRoutesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetMachineRoutesResponse) String() string {
|
||||
@@ -93,7 +88,7 @@ func (*GetMachineRoutesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetMachineRoutesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -123,22 +118,19 @@ func (x *GetMachineRoutesResponse) GetRoutes() *MachineRoutes {
|
||||
}
|
||||
|
||||
type EnableMachineRoutesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
Routes []string `protobuf:"bytes,2,rep,name=routes,proto3" json:"routes,omitempty"`
|
||||
Replace bool `protobuf:"varint,3,opt,name=replace,proto3" json:"replace,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EnableMachineRoutesRequest) Reset() {
|
||||
*x = EnableMachineRoutesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EnableMachineRoutesRequest) String() string {
|
||||
@@ -149,7 +141,7 @@ func (*EnableMachineRoutesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *EnableMachineRoutesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -186,21 +178,18 @@ func (x *EnableMachineRoutesRequest) GetReplace() bool {
|
||||
}
|
||||
|
||||
type EnableMachineRoutesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
Routes *MachineRoutes `protobuf:"bytes,2,opt,name=routes,proto3" json:"routes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EnableMachineRoutesResponse) Reset() {
|
||||
*x = EnableMachineRoutesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EnableMachineRoutesResponse) String() string {
|
||||
@@ -211,7 +200,7 @@ func (*EnableMachineRoutesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *EnableMachineRoutesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -241,21 +230,18 @@ func (x *EnableMachineRoutesResponse) GetRoutes() *MachineRoutes {
|
||||
}
|
||||
|
||||
type DisableMachineRoutesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
Routes []string `protobuf:"bytes,2,rep,name=routes,proto3" json:"routes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DisableMachineRoutesRequest) Reset() {
|
||||
*x = DisableMachineRoutesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DisableMachineRoutesRequest) String() string {
|
||||
@@ -266,7 +252,7 @@ func (*DisableMachineRoutesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DisableMachineRoutesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -296,21 +282,18 @@ func (x *DisableMachineRoutesRequest) GetRoutes() []string {
|
||||
}
|
||||
|
||||
type DisableMachineRoutesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
Routes *MachineRoutes `protobuf:"bytes,2,opt,name=routes,proto3" json:"routes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DisableMachineRoutesResponse) Reset() {
|
||||
*x = DisableMachineRoutesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DisableMachineRoutesResponse) String() string {
|
||||
@@ -321,7 +304,7 @@ func (*DisableMachineRoutesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DisableMachineRoutesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -351,20 +334,17 @@ func (x *DisableMachineRoutesResponse) GetRoutes() *MachineRoutes {
|
||||
}
|
||||
|
||||
type EnableExitNodeRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EnableExitNodeRequest) Reset() {
|
||||
*x = EnableExitNodeRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EnableExitNodeRequest) String() string {
|
||||
@@ -375,7 +355,7 @@ func (*EnableExitNodeRequest) ProtoMessage() {}
|
||||
|
||||
func (x *EnableExitNodeRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -398,21 +378,18 @@ func (x *EnableExitNodeRequest) GetMachineId() uint64 {
|
||||
}
|
||||
|
||||
type EnableExitNodeResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
Routes *MachineRoutes `protobuf:"bytes,2,opt,name=routes,proto3" json:"routes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EnableExitNodeResponse) Reset() {
|
||||
*x = EnableExitNodeResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EnableExitNodeResponse) String() string {
|
||||
@@ -423,7 +400,7 @@ func (*EnableExitNodeResponse) ProtoMessage() {}
|
||||
|
||||
func (x *EnableExitNodeResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -453,20 +430,17 @@ func (x *EnableExitNodeResponse) GetRoutes() *MachineRoutes {
|
||||
}
|
||||
|
||||
type DisableExitNodeRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DisableExitNodeRequest) Reset() {
|
||||
*x = DisableExitNodeRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DisableExitNodeRequest) String() string {
|
||||
@@ -477,7 +451,7 @@ func (*DisableExitNodeRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DisableExitNodeRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -500,21 +474,18 @@ func (x *DisableExitNodeRequest) GetMachineId() uint64 {
|
||||
}
|
||||
|
||||
type DisableExitNodeResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
|
||||
Routes *MachineRoutes `protobuf:"bytes,2,opt,name=routes,proto3" json:"routes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DisableExitNodeResponse) Reset() {
|
||||
*x = DisableExitNodeResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DisableExitNodeResponse) String() string {
|
||||
@@ -525,7 +496,7 @@ func (*DisableExitNodeResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DisableExitNodeResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -555,23 +526,20 @@ func (x *DisableExitNodeResponse) GetRoutes() *MachineRoutes {
|
||||
}
|
||||
|
||||
type MachineRoutes struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
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"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *MachineRoutes) Reset() {
|
||||
*x = MachineRoutes{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MachineRoutes) String() string {
|
||||
@@ -582,7 +550,7 @@ func (*MachineRoutes) ProtoMessage() {}
|
||||
|
||||
func (x *MachineRoutes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_routes_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -627,7 +595,7 @@ func (x *MachineRoutes) GetEnabledExitNode() bool {
|
||||
|
||||
var File_ionscale_v1_routes_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_routes_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_routes_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x18, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x38, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4d, 0x61,
|
||||
@@ -706,22 +674,22 @@ var file_ionscale_v1_routes_proto_rawDesc = []byte{
|
||||
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_routes_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_routes_proto_rawDescData = file_ionscale_v1_routes_proto_rawDesc
|
||||
file_ionscale_v1_routes_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_routes_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_routes_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_routes_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_routes_proto_rawDescData)
|
||||
file_ionscale_v1_routes_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_routes_proto_rawDesc), len(file_ionscale_v1_routes_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_routes_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_ionscale_v1_routes_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_routes_proto_goTypes = []any{
|
||||
(*GetMachineRoutesRequest)(nil), // 0: ionscale.v1.GetMachineRoutesRequest
|
||||
(*GetMachineRoutesResponse)(nil), // 1: ionscale.v1.GetMachineRoutesResponse
|
||||
(*EnableMachineRoutesRequest)(nil), // 2: ionscale.v1.EnableMachineRoutesRequest
|
||||
@@ -752,145 +720,11 @@ func file_ionscale_v1_routes_proto_init() {
|
||||
if File_ionscale_v1_routes_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_routes_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetMachineRoutesRequest); 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[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetMachineRoutesResponse); 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[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EnableMachineRoutesRequest); 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[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EnableMachineRoutesResponse); 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[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DisableMachineRoutesRequest); 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.(*DisableMachineRoutesResponse); 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[6].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[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EnableExitNodeResponse); 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[8].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
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_routes_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DisableExitNodeResponse); 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[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MachineRoutes); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_routes_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_routes_proto_rawDesc), len(file_ionscale_v1_routes_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 11,
|
||||
NumExtensions: 0,
|
||||
@@ -901,7 +735,6 @@ func file_ionscale_v1_routes_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_routes_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_routes_proto = out.File
|
||||
file_ionscale_v1_routes_proto_rawDesc = nil
|
||||
file_ionscale_v1_routes_proto_goTypes = nil
|
||||
file_ionscale_v1_routes_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
+279
-770
File diff suppressed because it is too large
Load Diff
+27
-103
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/users.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,22 +22,19 @@ const (
|
||||
)
|
||||
|
||||
type User struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Role string `protobuf:"bytes,3,opt,name=role,proto3" json:"role,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *User) Reset() {
|
||||
*x = User{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *User) String() string {
|
||||
@@ -47,7 +45,7 @@ func (*User) ProtoMessage() {}
|
||||
|
||||
func (x *User) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -84,20 +82,17 @@ func (x *User) GetRole() string {
|
||||
}
|
||||
|
||||
type ListUsersRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListUsersRequest) Reset() {
|
||||
*x = ListUsersRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListUsersRequest) String() string {
|
||||
@@ -108,7 +103,7 @@ func (*ListUsersRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListUsersRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -131,20 +126,17 @@ func (x *ListUsersRequest) GetTailnetId() uint64 {
|
||||
}
|
||||
|
||||
type ListUsersResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Users []*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListUsersResponse) Reset() {
|
||||
*x = ListUsersResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListUsersResponse) String() string {
|
||||
@@ -155,7 +147,7 @@ func (*ListUsersResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListUsersResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -178,20 +170,17 @@ func (x *ListUsersResponse) GetUsers() []*User {
|
||||
}
|
||||
|
||||
type DeleteUserRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId uint64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteUserRequest) Reset() {
|
||||
*x = DeleteUserRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteUserRequest) String() string {
|
||||
@@ -202,7 +191,7 @@ func (*DeleteUserRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -225,18 +214,16 @@ func (x *DeleteUserRequest) GetUserId() uint64 {
|
||||
}
|
||||
|
||||
type DeleteUserResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteUserResponse) Reset() {
|
||||
*x = DeleteUserResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteUserResponse) String() string {
|
||||
@@ -247,7 +234,7 @@ func (*DeleteUserResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_users_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -264,7 +251,7 @@ func (*DeleteUserResponse) Descriptor() ([]byte, []int) {
|
||||
|
||||
var File_ionscale_v1_users_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_users_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_users_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x17, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73,
|
||||
0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e, 0x73, 0x63,
|
||||
0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x3e, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e,
|
||||
@@ -288,22 +275,22 @@ var file_ionscale_v1_users_proto_rawDesc = []byte{
|
||||
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_users_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_users_proto_rawDescData = file_ionscale_v1_users_proto_rawDesc
|
||||
file_ionscale_v1_users_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_users_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_users_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_users_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_users_proto_rawDescData)
|
||||
file_ionscale_v1_users_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_users_proto_rawDesc), len(file_ionscale_v1_users_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_users_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_users_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_ionscale_v1_users_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_users_proto_goTypes = []any{
|
||||
(*User)(nil), // 0: ionscale.v1.User
|
||||
(*ListUsersRequest)(nil), // 1: ionscale.v1.ListUsersRequest
|
||||
(*ListUsersResponse)(nil), // 2: ionscale.v1.ListUsersResponse
|
||||
@@ -324,73 +311,11 @@ func file_ionscale_v1_users_proto_init() {
|
||||
if File_ionscale_v1_users_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_users_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*User); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_users_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListUsersRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_users_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListUsersResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_users_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteUserRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_users_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteUserResponse); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_users_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_users_proto_rawDesc), len(file_ionscale_v1_users_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
@@ -401,7 +326,6 @@ func file_ionscale_v1_users_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_users_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_users_proto = out.File
|
||||
file_ionscale_v1_users_proto_rawDesc = nil
|
||||
file_ionscale_v1_users_proto_goTypes = nil
|
||||
file_ionscale_v1_users_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.32.0
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc (unknown)
|
||||
// source: ionscale/v1/version.proto
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,18 +22,16 @@ const (
|
||||
)
|
||||
|
||||
type GetVersionRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetVersionRequest) Reset() {
|
||||
*x = GetVersionRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_version_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetVersionRequest) String() string {
|
||||
@@ -43,7 +42,7 @@ func (*GetVersionRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetVersionRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_version_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -59,21 +58,18 @@ func (*GetVersionRequest) Descriptor() ([]byte, []int) {
|
||||
}
|
||||
|
||||
type GetVersionResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetVersionResponse) Reset() {
|
||||
*x = GetVersionResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ionscale_v1_version_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetVersionResponse) String() string {
|
||||
@@ -84,7 +80,7 @@ func (*GetVersionResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetVersionResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ionscale_v1_version_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -115,7 +111,7 @@ func (x *GetVersionResponse) GetRevision() string {
|
||||
|
||||
var File_ionscale_v1_version_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ionscale_v1_version_proto_rawDesc = []byte{
|
||||
var file_ionscale_v1_version_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x19, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56,
|
||||
@@ -129,22 +125,22 @@ var file_ionscale_v1_version_proto_rawDesc = []byte{
|
||||
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_version_proto_rawDescOnce sync.Once
|
||||
file_ionscale_v1_version_proto_rawDescData = file_ionscale_v1_version_proto_rawDesc
|
||||
file_ionscale_v1_version_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_ionscale_v1_version_proto_rawDescGZIP() []byte {
|
||||
file_ionscale_v1_version_proto_rawDescOnce.Do(func() {
|
||||
file_ionscale_v1_version_proto_rawDescData = protoimpl.X.CompressGZIP(file_ionscale_v1_version_proto_rawDescData)
|
||||
file_ionscale_v1_version_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ionscale_v1_version_proto_rawDesc), len(file_ionscale_v1_version_proto_rawDesc)))
|
||||
})
|
||||
return file_ionscale_v1_version_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ionscale_v1_version_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_ionscale_v1_version_proto_goTypes = []interface{}{
|
||||
var file_ionscale_v1_version_proto_goTypes = []any{
|
||||
(*GetVersionRequest)(nil), // 0: ionscale.v1.GetVersionRequest
|
||||
(*GetVersionResponse)(nil), // 1: ionscale.v1.GetVersionResponse
|
||||
}
|
||||
@@ -161,37 +157,11 @@ func file_ionscale_v1_version_proto_init() {
|
||||
if File_ionscale_v1_version_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ionscale_v1_version_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetVersionRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ionscale_v1_version_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetVersionResponse); 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{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ionscale_v1_version_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ionscale_v1_version_proto_rawDesc), len(file_ionscale_v1_version_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
@@ -202,7 +172,6 @@ func file_ionscale_v1_version_proto_init() {
|
||||
MessageInfos: file_ionscale_v1_version_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ionscale_v1_version_proto = out.File
|
||||
file_ionscale_v1_version_proto_rawDesc = nil
|
||||
file_ionscale_v1_version_proto_goTypes = nil
|
||||
file_ionscale_v1_version_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ service IonscaleService {
|
||||
|
||||
rpc GetMachine(GetMachineRequest) returns (GetMachineResponse) {}
|
||||
rpc ListMachines(ListMachinesRequest) returns (ListMachinesResponse) {}
|
||||
rpc SetMachineName(SetMachineNameRequest) returns (SetMachineNameResponse) {}
|
||||
rpc AuthorizeMachine(AuthorizeMachineRequest) returns (AuthorizeMachineResponse) {}
|
||||
rpc ExpireMachine(ExpireMachineRequest) returns (ExpireMachineResponse) {}
|
||||
rpc DeleteMachine(DeleteMachineRequest) returns (DeleteMachineResponse) {}
|
||||
|
||||
@@ -48,6 +48,14 @@ message AuthorizeMachineRequest {
|
||||
|
||||
message AuthorizeMachineResponse {}
|
||||
|
||||
message SetMachineNameRequest {
|
||||
uint64 machine_id = 1;
|
||||
bool use_os_hostname = 2;
|
||||
string name = 3;
|
||||
}
|
||||
|
||||
message SetMachineNameResponse {}
|
||||
|
||||
message Machine {
|
||||
uint64 id = 1;
|
||||
string name = 2;
|
||||
|
||||
+162
-66
@@ -1,166 +1,262 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# ionscale linux installation script
|
||||
# This script automates the installation of ionscale on a Linux server with systemd
|
||||
|
||||
# Display functions
|
||||
info() {
|
||||
echo '[INFO] ->' "$@"
|
||||
echo "===> [INFO]" "$@"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo "===> [WARN]" "$@"
|
||||
}
|
||||
|
||||
fatal() {
|
||||
echo '[ERROR] ->' "$@"
|
||||
echo "===> [ERROR]" "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
verify_system() {
|
||||
if ! [ -d /run/systemd ]; then
|
||||
fatal 'Can not find systemd to use as a process supervisor for ionscale'
|
||||
fi
|
||||
}
|
||||
# Welcome message
|
||||
echo "===================================================="
|
||||
echo "ionscale Installation Script"
|
||||
echo "===================================================="
|
||||
|
||||
setup_env() {
|
||||
SUDO=sudo
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
# Check for systemd
|
||||
if ! [ -d /run/systemd ]; then
|
||||
fatal "Cannot find systemd to use as a process supervisor for ionscale"
|
||||
fi
|
||||
|
||||
# Check for root or sudo privileges
|
||||
SUDO=sudo
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
SUDO=
|
||||
fi
|
||||
info "Running as root"
|
||||
else
|
||||
info "Running with sudo"
|
||||
fi
|
||||
|
||||
# Get required input
|
||||
if [ -z "${IONSCALE_DOMAIN}" ]; then
|
||||
read -p "Enter your ionscale domain (e.g. ionscale.example.com): " IONSCALE_DOMAIN
|
||||
if [ -z "${IONSCALE_DOMAIN}" ]; then
|
||||
fatal "env variable IONSCALE_DOMAIN is undefined"
|
||||
fatal "Domain is required"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${IONSCALE_ACME_EMAIL}" ]; then
|
||||
read -p "Enter your email address (for Let's Encrypt notifications): " IONSCALE_ACME_EMAIL
|
||||
if [ -z "${IONSCALE_ACME_EMAIL}" ]; then
|
||||
fatal "env variable IONSCALE_ACME_EMAIL is undefined"
|
||||
fatal "Email address is required"
|
||||
fi
|
||||
fi
|
||||
|
||||
IONSCALE_VERSION=v0.12.0
|
||||
IONSCALE_DATA_DIR=/var/lib/ionscale
|
||||
IONSCALE_CONFIG_DIR=/etc/ionscale
|
||||
IONSCALE_SERVICE_FILE=/etc/systemd/system/ionscale.service
|
||||
# Set up directories and paths
|
||||
IONSCALE_VERSION=v0.17.0
|
||||
IONSCALE_DATA_DIR=/var/lib/ionscale
|
||||
IONSCALE_CONFIG_DIR=/etc/ionscale
|
||||
IONSCALE_SERVICE_FILE=/etc/systemd/system/ionscale.service
|
||||
IONSCALE_ENV_FILE=/etc/default/ionscale
|
||||
BIN_DIR=/usr/local/bin
|
||||
|
||||
BIN_DIR=/usr/local/bin
|
||||
}
|
||||
|
||||
# --- set arch and suffix, fatal if architecture not supported ---
|
||||
setup_verify_arch() {
|
||||
# --- Architecture detection ---
|
||||
setup_arch() {
|
||||
info "Detecting architecture"
|
||||
if [ -z "$ARCH" ]; then
|
||||
ARCH=$(uname -m)
|
||||
fi
|
||||
case $ARCH in
|
||||
amd64)
|
||||
amd64|x86_64)
|
||||
SUFFIX=amd64
|
||||
;;
|
||||
x86_64)
|
||||
SUFFIX=amd64
|
||||
;;
|
||||
arm64)
|
||||
SUFFIX=arm64
|
||||
;;
|
||||
aarch64)
|
||||
arm64|aarch64)
|
||||
SUFFIX=arm64
|
||||
;;
|
||||
*)
|
||||
fatal "Unsupported architecture $ARCH"
|
||||
;;
|
||||
esac
|
||||
info "Architecture: $ARCH (using $SUFFIX)"
|
||||
}
|
||||
|
||||
has_yum() {
|
||||
[ -n "$(command -v yum)" ]
|
||||
}
|
||||
|
||||
has_apt_get() {
|
||||
[ -n "$(command -v apt-get)" ]
|
||||
}
|
||||
|
||||
# --- Dependencies check ---
|
||||
install_dependencies() {
|
||||
info "Checking for dependencies"
|
||||
if ! [ -x "$(command -v curl)" ]; then
|
||||
if $(has_apt_get); then
|
||||
info "Installing curl"
|
||||
if [ -n "$(command -v apt-get)" ]; then
|
||||
$SUDO apt-get update
|
||||
$SUDO apt-get install -y curl
|
||||
elif $(has_yum); then
|
||||
elif [ -n "$(command -v yum)" ]; then
|
||||
$SUDO yum install -y curl
|
||||
else
|
||||
fatal "Could not find apt-get or yum. Cannot install dependencies on this OS"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Create service user ---
|
||||
create_service_user() {
|
||||
info "Creating service user"
|
||||
|
||||
# Only create user if it doesn't exist
|
||||
if ! id ionscale &>/dev/null; then
|
||||
$SUDO useradd --system --no-create-home --shell /bin/false ionscale
|
||||
info "Created user 'ionscale'"
|
||||
else
|
||||
fatal "User 'ionscale' already exists"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Binary installation ---
|
||||
download_and_install() {
|
||||
info "Downloading ionscale binary"
|
||||
info "Downloading ionscale binary $IONSCALE_VERSION"
|
||||
$SUDO curl -o "$BIN_DIR/ionscale" -sfL "https://github.com/jsiebens/ionscale/releases/download/${IONSCALE_VERSION}/ionscale_linux_${SUFFIX}"
|
||||
$SUDO chmod +x "$BIN_DIR/ionscale"
|
||||
|
||||
# Verify installation
|
||||
if [ -x "$BIN_DIR/ionscale" ]; then
|
||||
info "ionscale binary installed successfully"
|
||||
$SUDO $BIN_DIR/ionscale version
|
||||
else
|
||||
fatal "Failed to install ionscale binary"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Create configuration files ---
|
||||
create_folders_and_config() {
|
||||
$SUDO mkdir --parents ${IONSCALE_DATA_DIR}
|
||||
$SUDO mkdir --parents ${IONSCALE_CONFIG_DIR}
|
||||
info "Creating directories"
|
||||
$SUDO mkdir -p ${IONSCALE_DATA_DIR}
|
||||
$SUDO mkdir -p ${IONSCALE_CONFIG_DIR}
|
||||
|
||||
if [ ! -f "/etc/default/ionscale" ]; then
|
||||
$SUDO tee /etc/default/ionscale >/dev/null <<EOF
|
||||
IONSCALE_KEYS_SYSTEM_ADMIN_KEY=$($BIN_DIR/ionscale genkey -n)
|
||||
# Set appropriate ownership
|
||||
$SUDO chown ionscale:ionscale ${IONSCALE_DATA_DIR}
|
||||
$SUDO chown ionscale:ionscale ${IONSCALE_CONFIG_DIR}
|
||||
|
||||
info "Generating system admin key"
|
||||
ADMIN_KEY=$($BIN_DIR/ionscale genkey -n)
|
||||
$SUDO tee $IONSCALE_ENV_FILE >/dev/null <<EOF
|
||||
IONSCALE_KEYS_SYSTEM_ADMIN_KEY=$ADMIN_KEY
|
||||
EOF
|
||||
fi
|
||||
info "Generated system admin key:"
|
||||
echo "$ADMIN_KEY"
|
||||
echo "IMPORTANT: Save this key securely. You'll need it to administer ionscale."
|
||||
|
||||
info "Creating configuration file"
|
||||
$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}"
|
||||
listen_addr: ":443"
|
||||
public_addr: "${IONSCALE_DOMAIN}:443"
|
||||
stun_listen_addr: ":3478"
|
||||
stun_public_addr: "${IONSCALE_DOMAIN}:3478"
|
||||
|
||||
tls:
|
||||
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)&_pragma=foreign_keys(ON)"
|
||||
|
||||
keys:
|
||||
system_admin_key: "\${IONSCALE_KEYS_SYSTEM_ADMIN_KEY}"
|
||||
|
||||
logging:
|
||||
level: info
|
||||
EOF
|
||||
|
||||
info "Configuration created at ${IONSCALE_CONFIG_DIR}/config.yaml"
|
||||
}
|
||||
|
||||
# --- write systemd service file ---
|
||||
# --- Create systemd service file ---
|
||||
create_systemd_service_file() {
|
||||
info "Adding systemd service file ${IONSCALE_SERVICE_FILE}"
|
||||
info "Creating systemd service file ${IONSCALE_SERVICE_FILE}"
|
||||
$SUDO tee ${IONSCALE_SERVICE_FILE} >/dev/null <<EOF
|
||||
[Unit]
|
||||
Description=ionscale - a Tailscale Controller server
|
||||
After=syslog.target
|
||||
Description=ionscale - a Tailscale control server
|
||||
Requires=network-online.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/etc/default/ionscale
|
||||
User=ionscale
|
||||
Group=ionscale
|
||||
ExecStart=${BIN_DIR}/ionscale server --config ${IONSCALE_CONFIG_DIR}/config.yaml
|
||||
Restart=on-failure
|
||||
RestartSec=10s
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
}
|
||||
|
||||
# --- startup systemd service ---
|
||||
# --- Enable and start service ---
|
||||
systemd_enable_and_start() {
|
||||
[ "${SKIP_ENABLE}" = true ] && return
|
||||
if [ "${SKIP_ENABLE}" = true ]; then
|
||||
info "Skipping service enablement (SKIP_ENABLE=true)"
|
||||
return
|
||||
fi
|
||||
|
||||
info "Enabling systemd service"
|
||||
$SUDO systemctl enable ${IONSCALE_SERVICE_FILE} >/dev/null
|
||||
$SUDO systemctl daemon-reload >/dev/null
|
||||
$SUDO systemctl enable ${IONSCALE_SERVICE_FILE} >/dev/null
|
||||
|
||||
[ "${SKIP_START}" = true ] && return
|
||||
if [ "${SKIP_START}" = true ]; then
|
||||
info "Skipping service start (SKIP_START=true)"
|
||||
return
|
||||
fi
|
||||
|
||||
info "Starting systemd service"
|
||||
info "Starting ionscale service"
|
||||
$SUDO systemctl restart ionscale
|
||||
|
||||
return 0
|
||||
# Check service status
|
||||
ATTEMPTS=0
|
||||
MAX_ATTEMPTS=5
|
||||
DELAY=2
|
||||
|
||||
while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do
|
||||
if $SUDO systemctl is-active --quiet ionscale; then
|
||||
info "ionscale service is running"
|
||||
break
|
||||
else
|
||||
ATTEMPTS=$((ATTEMPTS + 1))
|
||||
if [ $ATTEMPTS -eq $MAX_ATTEMPTS ]; then
|
||||
warn "ionscale service failed to start. Check status with: sudo systemctl status ionscale"
|
||||
else
|
||||
info "Waiting for service to start ($ATTEMPTS/$MAX_ATTEMPTS)..."
|
||||
sleep $DELAY
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
setup_env
|
||||
setup_verify_arch
|
||||
verify_system
|
||||
# Main execution sequence
|
||||
setup_arch
|
||||
install_dependencies
|
||||
create_service_user
|
||||
download_and_install
|
||||
create_folders_and_config
|
||||
create_systemd_service_file
|
||||
systemd_enable_and_start
|
||||
|
||||
# Completion message
|
||||
echo
|
||||
echo "===================================================="
|
||||
echo "ionscale installation complete!"
|
||||
echo "===================================================="
|
||||
echo
|
||||
echo "Your ionscale instance is now available at: https://${IONSCALE_DOMAIN}"
|
||||
echo
|
||||
echo "Next steps:"
|
||||
echo "1. Configure OIDC authentication if needed"
|
||||
echo "2. Set up DNS provider if needed"
|
||||
echo "3. Create your first tailnet"
|
||||
echo
|
||||
echo "To view logs: sudo journalctl -u ionscale -f"
|
||||
echo "To restart the service: sudo systemctl restart ionscale"
|
||||
echo
|
||||
echo "Configure ionscale CLI:"
|
||||
echo "export IONSCALE_ADDR=https://${IONSCALE_DOMAIN}"
|
||||
echo "export IONSCALE_SYSTEM_ADMIN_KEY=${ADMIN_KEY}"
|
||||
echo "Then you can run: ionscale tailnets list"
|
||||
@@ -0,0 +1,136 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/jsiebens/ionscale/pkg/client/ionscale"
|
||||
"github.com/jsiebens/ionscale/pkg/defaults"
|
||||
"github.com/jsiebens/ionscale/tests/sc"
|
||||
"github.com/jsiebens/ionscale/tests/tsn"
|
||||
"github.com/stretchr/testify/require"
|
||||
"net/netip"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAdvertiseRoutesAutoApprovedOnNewNode(t *testing.T) {
|
||||
route1 := netip.MustParsePrefix("10.1.0.0/24")
|
||||
route2 := netip.MustParsePrefix("10.2.0.0/24")
|
||||
|
||||
sc.Run(t, func(s *sc.Scenario) {
|
||||
aclPolicy := defaults.DefaultACLPolicy()
|
||||
aclPolicy.AutoApprovers = &ionscale.ACLAutoApprovers{
|
||||
Routes: map[string][]string{
|
||||
route1.String(): {"tag:test-route"},
|
||||
},
|
||||
}
|
||||
|
||||
tailnet := s.CreateTailnet()
|
||||
s.SetACLPolicy(tailnet.Id, aclPolicy)
|
||||
|
||||
testNode := s.NewTailscaleNode()
|
||||
require.NoError(t, testNode.Up(
|
||||
s.CreateAuthKey(tailnet.Id, true, "tag:test-route"),
|
||||
tsn.WithAdvertiseTags("tag:test-route"),
|
||||
tsn.WithAdvertiseRoutes([]string{
|
||||
route1.String(),
|
||||
route2.String()},
|
||||
),
|
||||
))
|
||||
|
||||
require.NoError(t, testNode.WaitFor(tsn.HasTailnet(tailnet.Name)))
|
||||
|
||||
mid, err := s.FindMachine(tailnet.Id, testNode.Hostname())
|
||||
require.NoError(t, err)
|
||||
|
||||
machineRoutes := s.GetMachineRoutes(mid)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, []string{route1.String(), route2.String()}, machineRoutes.AdvertisedRoutes)
|
||||
require.Equal(t, []string{route1.String()}, machineRoutes.EnabledRoutes)
|
||||
|
||||
require.NoError(t, testNode.Check(tsn.HasAllowedIP(route1)))
|
||||
require.NoError(t, testNode.Check(tsn.IsMissingAllowedIP(route2)))
|
||||
})
|
||||
}
|
||||
|
||||
func TestAdvertiseRoutesAutoApprovedOnExistingNode(t *testing.T) {
|
||||
route1 := netip.MustParsePrefix("10.1.0.0/24")
|
||||
route2 := netip.MustParsePrefix("10.2.0.0/24")
|
||||
route3 := netip.MustParsePrefix("10.3.0.0/24")
|
||||
|
||||
sc.Run(t, func(s *sc.Scenario) {
|
||||
aclPolicy := defaults.DefaultACLPolicy()
|
||||
aclPolicy.AutoApprovers = &ionscale.ACLAutoApprovers{
|
||||
Routes: map[string][]string{
|
||||
route1.String(): {"tag:test-route"},
|
||||
route3.String(): {"tag:test-route"},
|
||||
},
|
||||
}
|
||||
|
||||
tailnet := s.CreateTailnet()
|
||||
s.SetACLPolicy(tailnet.Id, aclPolicy)
|
||||
|
||||
testNode := s.NewTailscaleNode()
|
||||
require.NoError(t, testNode.Up(
|
||||
s.CreateAuthKey(tailnet.Id, true, "tag:test-route"),
|
||||
tsn.WithAdvertiseTags("tag:test-route"),
|
||||
))
|
||||
|
||||
require.NoError(t, testNode.Check(tsn.HasTailnet(tailnet.Name)))
|
||||
|
||||
testNode.Set(tsn.WithAdvertiseRoutes([]string{
|
||||
route3.String(),
|
||||
route1.String(),
|
||||
route2.String()},
|
||||
))
|
||||
|
||||
require.NoError(t, testNode.WaitFor(tsn.HasAllowedIP(route1)))
|
||||
require.NoError(t, testNode.WaitFor(tsn.HasAllowedIP(route3)))
|
||||
require.NoError(t, testNode.WaitFor(tsn.IsMissingAllowedIP(route2)))
|
||||
|
||||
mid, err := s.FindMachine(tailnet.Id, testNode.Hostname())
|
||||
require.NoError(t, err)
|
||||
|
||||
machineRoutes := s.GetMachineRoutes(mid)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, []string{route1.String(), route2.String(), route3.String()}, machineRoutes.AdvertisedRoutes)
|
||||
require.Equal(t, []string{route1.String(), route3.String()}, machineRoutes.EnabledRoutes)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAdvertiseRemoveRoutesAutoApprovedOnExistingNode(t *testing.T) {
|
||||
route1 := netip.MustParsePrefix("10.1.0.0/24")
|
||||
route2 := netip.MustParsePrefix("10.2.0.0/24")
|
||||
|
||||
sc.Run(t, func(s *sc.Scenario) {
|
||||
aclPolicy := defaults.DefaultACLPolicy()
|
||||
aclPolicy.AutoApprovers = &ionscale.ACLAutoApprovers{
|
||||
Routes: map[string][]string{
|
||||
route1.String(): {"tag:test-route"},
|
||||
route2.String(): {"tag:test-route"},
|
||||
},
|
||||
}
|
||||
|
||||
tailnet := s.CreateTailnet()
|
||||
s.SetACLPolicy(tailnet.Id, aclPolicy)
|
||||
|
||||
testNode := s.NewTailscaleNode()
|
||||
require.NoError(t, testNode.Up(
|
||||
s.CreateAuthKey(tailnet.Id, true, "tag:test-route"),
|
||||
tsn.WithAdvertiseTags("tag:test-route"),
|
||||
tsn.WithAdvertiseRoutes([]string{
|
||||
route1.String(),
|
||||
route2.String()},
|
||||
),
|
||||
))
|
||||
|
||||
require.NoError(t, testNode.WaitFor(tsn.HasTailnet(tailnet.Name)))
|
||||
require.NoError(t, testNode.Check(tsn.HasAllowedIP(route1)))
|
||||
require.NoError(t, testNode.Check(tsn.HasAllowedIP(route2)))
|
||||
|
||||
testNode.Set(tsn.WithAdvertiseRoutes([]string{
|
||||
route1.String(),
|
||||
}))
|
||||
|
||||
require.NoError(t, testNode.WaitFor(tsn.IsMissingAllowedIP(route2)))
|
||||
})
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.22-bullseye as builder
|
||||
FROM golang:1.24-bullseye as builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
@@ -80,3 +80,16 @@ func TestNodeWithSameHostname(t *testing.T) {
|
||||
}, machines)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNodeShouldSeeAssignedTags(t *testing.T) {
|
||||
sc.Run(t, func(s *sc.Scenario) {
|
||||
tailnet := s.CreateTailnet()
|
||||
key := s.CreateAuthKey(tailnet.Id, true, "tag:server")
|
||||
|
||||
nodeA := s.NewTailscaleNode()
|
||||
|
||||
require.NoError(t, nodeA.Up(key, tsn.WithAdvertiseTags("tag:test")))
|
||||
require.NoError(t, nodeA.WaitFor(tsn.HasTag("tag:server")))
|
||||
require.NoError(t, nodeA.WaitFor(tsn.HasTag("tag:test")))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -85,6 +85,23 @@ func (s *Scenario) ExpireMachines(tailnetID uint64) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scenario) FindMachine(tailnetID uint64, name string) (uint64, error) {
|
||||
machines := s.ListMachines(tailnetID)
|
||||
|
||||
for _, m := range machines {
|
||||
if m.Name == name {
|
||||
return m.Id, nil
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("machine %s not found", name)
|
||||
}
|
||||
|
||||
func (s *Scenario) SetMachineName(machineID uint64, useOSHostname bool, name string) error {
|
||||
req := &api.SetMachineNameRequest{MachineId: machineID, UseOsHostname: useOSHostname, Name: name}
|
||||
_, err := s.ionscaleClient.SetMachineName(context.Background(), connect.NewRequest(req))
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Scenario) SetACLPolicy(tailnetID uint64, policy *ionscaleclt.ACLPolicy) {
|
||||
_, err := s.ionscaleClient.SetACLPolicy(context.Background(), connect.NewRequest(&api.SetACLPolicyRequest{TailnetId: tailnetID, Policy: policy.Marshal()}))
|
||||
require.NoError(s.t, err)
|
||||
@@ -100,6 +117,12 @@ func (s *Scenario) EnableMachineAutorization(tailnetID uint64) {
|
||||
require.NoError(s.t, err)
|
||||
}
|
||||
|
||||
func (s *Scenario) GetMachineRoutes(machineID uint64) *api.MachineRoutes {
|
||||
routes, err := s.ionscaleClient.GetMachineRoutes(context.Background(), connect.NewRequest(&api.GetMachineRoutesRequest{MachineId: machineID}))
|
||||
require.NoError(s.t, err)
|
||||
return routes.Msg.Routes
|
||||
}
|
||||
|
||||
func (s *Scenario) PushOIDCUser(sub, email, preferredUsername string) {
|
||||
_, err := s.mockoidcClient.PushUser(context.Background(), connect.NewRequest(&mockoidcv1.PushUserRequest{Subject: sub, Email: email, PreferredUsername: preferredUsername}))
|
||||
require.NoError(s.t, err)
|
||||
@@ -136,6 +159,10 @@ type TailscaleNodeConfig struct {
|
||||
|
||||
type TailscaleNodeOpt = func(*TailscaleNodeConfig)
|
||||
|
||||
func RandomName() string {
|
||||
return petname.Generate(3, "-")
|
||||
}
|
||||
|
||||
func WithName(name string) TailscaleNodeOpt {
|
||||
return func(config *TailscaleNodeConfig) {
|
||||
config.Hostname = name
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/jsiebens/ionscale/tests/sc"
|
||||
"github.com/jsiebens/ionscale/tests/tsn"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewHostnameShouldPropagateToPeersWhenSet(t *testing.T) {
|
||||
sc.Run(t, func(s *sc.Scenario) {
|
||||
tailnet := s.CreateTailnet()
|
||||
key := s.CreateAuthKey(tailnet.Id, true)
|
||||
|
||||
initialName := sc.RandomName()
|
||||
|
||||
nodeA := s.NewTailscaleNode()
|
||||
nodeB := s.NewTailscaleNode(sc.WithName(initialName))
|
||||
|
||||
require.NoError(t, nodeA.Up(key))
|
||||
require.NoError(t, nodeB.Up(key))
|
||||
|
||||
require.NoError(t, nodeA.WaitFor(tsn.HasPeer(initialName)))
|
||||
|
||||
newName := sc.RandomName()
|
||||
|
||||
require.NoError(t, nodeB.SetHostname(newName))
|
||||
|
||||
require.NoError(t, nodeA.WaitFor(tsn.HasPeer(newName)))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetHostname(t *testing.T) {
|
||||
sc.Run(t, func(s *sc.Scenario) {
|
||||
tailnet := s.CreateTailnet()
|
||||
key := s.CreateAuthKey(tailnet.Id, true)
|
||||
|
||||
initialName := sc.RandomName()
|
||||
|
||||
nodeA := s.NewTailscaleNode()
|
||||
nodeB := s.NewTailscaleNode(sc.WithName(initialName))
|
||||
|
||||
require.NoError(t, nodeA.Up(key))
|
||||
require.NoError(t, nodeB.Up(key))
|
||||
|
||||
require.NoError(t, nodeA.WaitFor(tsn.HasPeer(initialName)))
|
||||
|
||||
mid, err := s.FindMachine(tailnet.Id, initialName)
|
||||
require.NoError(t, err)
|
||||
|
||||
newName := sc.RandomName()
|
||||
|
||||
require.NoError(t, s.SetMachineName(mid, false, newName))
|
||||
require.NoError(t, nodeA.WaitFor(tsn.HasPeer(newName)))
|
||||
|
||||
require.NoError(t, s.SetMachineName(mid, true, ""))
|
||||
require.NoError(t, nodeA.WaitFor(tsn.HasPeer(initialName)))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetHostnameWhenNameAlreadyInUse(t *testing.T) {
|
||||
sc.Run(t, func(s *sc.Scenario) {
|
||||
tailnet := s.CreateTailnet()
|
||||
key := s.CreateAuthKey(tailnet.Id, true)
|
||||
|
||||
nodeA := s.NewTailscaleNode(sc.WithName("node-a"))
|
||||
nodeB := s.NewTailscaleNode(sc.WithName("node-b"))
|
||||
|
||||
require.NoError(t, nodeA.Up(key))
|
||||
require.NoError(t, nodeB.Up(key))
|
||||
|
||||
require.NoError(t, nodeA.WaitFor(tsn.PeerCount(1)))
|
||||
require.NoError(t, nodeB.WaitFor(tsn.PeerCount(1)))
|
||||
|
||||
mida, err := s.FindMachine(tailnet.Id, "node-a")
|
||||
require.NoError(t, err)
|
||||
|
||||
midb, err := s.FindMachine(tailnet.Id, "node-b")
|
||||
require.NoError(t, err)
|
||||
|
||||
newName := sc.RandomName()
|
||||
|
||||
require.NoError(t, s.SetMachineName(mida, false, newName))
|
||||
require.NoError(t, nodeB.WaitFor(tsn.HasPeer(newName)))
|
||||
|
||||
err = s.SetMachineName(midb, false, newName)
|
||||
require.ErrorContains(t, err, "machine name already in use")
|
||||
})
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package tsn
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"slices"
|
||||
"strings"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
@@ -60,6 +61,24 @@ func HasUser(email string) Condition {
|
||||
}
|
||||
}
|
||||
|
||||
func HasAllowedIP(route netip.Prefix) Condition {
|
||||
return func(status *ipnstate.Status) bool {
|
||||
if status.Self == nil || status.Self.AllowedIPs.Len() == 0 {
|
||||
return false
|
||||
}
|
||||
return slices.Contains(status.Self.AllowedIPs.AsSlice(), route)
|
||||
}
|
||||
}
|
||||
|
||||
func IsMissingAllowedIP(route netip.Prefix) Condition {
|
||||
return func(status *ipnstate.Status) bool {
|
||||
if status.Self == nil || status.Self.AllowedIPs.Len() == 0 {
|
||||
return true
|
||||
}
|
||||
return !slices.Contains(status.Self.AllowedIPs.AsSlice(), route)
|
||||
}
|
||||
}
|
||||
|
||||
func PeerCount(expected int) Condition {
|
||||
return func(status *ipnstate.Status) bool {
|
||||
return len(status.Peers()) == expected
|
||||
@@ -77,6 +96,17 @@ func HasExpiredPeer(name string) Condition {
|
||||
}
|
||||
}
|
||||
|
||||
func HasPeer(name string) Condition {
|
||||
return func(status *ipnstate.Status) bool {
|
||||
for _, peer := range status.Peer {
|
||||
if strings.HasPrefix(peer.DNSName, name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func HasCapability(capability tailcfg.NodeCapability) Condition {
|
||||
return func(status *ipnstate.Status) bool {
|
||||
self := status.Self
|
||||
|
||||
+24
-2
@@ -38,11 +38,25 @@ func (t *TailscaleNode) Hostname() string {
|
||||
return t.hostname
|
||||
}
|
||||
|
||||
func (t *TailscaleNode) Up(authkey string) error {
|
||||
t.mustExecTailscaleCmd("up", "--login-server", t.loginServer, "--authkey", authkey)
|
||||
func (t *TailscaleNode) Up(authkey string, flags ...UpFlag) error {
|
||||
cmd := []string{"up", "--login-server", t.loginServer, "--authkey", authkey}
|
||||
for _, f := range flags {
|
||||
cmd = append(cmd, f...)
|
||||
}
|
||||
|
||||
t.mustExecTailscaleCmd(cmd...)
|
||||
return t.WaitFor(Connected())
|
||||
}
|
||||
|
||||
func (t *TailscaleNode) Set(flags ...UpFlag) string {
|
||||
cmd := []string{"set"}
|
||||
for _, f := range flags {
|
||||
cmd = append(cmd, f...)
|
||||
}
|
||||
|
||||
return t.mustExecTailscaleCmd(cmd...)
|
||||
}
|
||||
|
||||
func (t *TailscaleNode) LoginWithOidc(flags ...UpFlag) (int, error) {
|
||||
check := func(stdout, stderr string) bool {
|
||||
return strings.Contains(stderr, "To authenticate, visit:")
|
||||
@@ -148,6 +162,14 @@ func (t *TailscaleNode) Ping(target string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TailscaleNode) SetHostname(hostname string) error {
|
||||
_, _, err := t.execTailscaleCmd("set", "--hostname", hostname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TailscaleNode) NetCheck() (*netcheck.Report, error) {
|
||||
result, _, err := t.execTailscaleCmd("netcheck", "--format=json")
|
||||
if err != nil {
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
package tsn
|
||||
|
||||
import "strings"
|
||||
|
||||
type UpFlag = []string
|
||||
|
||||
func WithAdvertiseTags(tags string) UpFlag {
|
||||
return []string{"--advertise-tags", tags}
|
||||
}
|
||||
|
||||
func WithAdvertiseRoutes(routes []string) UpFlag {
|
||||
return []string{"--advertise-routes", strings.Join(routes, ",")}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user