Compare commits

...

16 Commits

Author SHA1 Message Date
Johan Siebens 45572397ea fix: use correct context 2022-09-28 14:58:04 +02:00
Johan Siebens e5a3d3c589 fix: sanitize tailnet name properly 2022-09-28 11:50:31 +02:00
Johan Siebens 2a5fe7f136 feat: generate control keys by default in db 2022-09-27 16:40:48 +02:00
Johan Siebens 7ee4b27688 feat: add cmd to enable/disable exit nodes and print information properly 2022-09-27 11:14:22 +02:00
Johan Siebens 69f7c22307 feat: add support for autogroup:internet in acls 2022-09-27 09:36:10 +02:00
Johan Siebens 4e5f89ab7e feat: add autoapprovers support in acls 2022-09-27 07:52:37 +02:00
Johan Siebens c1ffe03e81 feat: mark machines as ephemeral when requested by the client 2022-09-25 08:11:10 +02:00
Johan Siebens 7ad91c4c20 feat: add support for autogroup:self and autogroup:members 2022-09-24 15:42:55 +02:00
Johan Siebens fb04248db4 chore(ci): add some security analysis 2022-09-24 09:37:26 +02:00
Johan Siebens d84bad12d0 chore: fixes 2022-09-24 08:16:52 +02:00
Johan Siebens cadf938e2a chore(ci): update build targets 2022-09-24 08:09:26 +02:00
Johan Siebens 980ae6dd85 feat: add flags to create tailnet with some proper default IAM policies 2022-09-23 14:04:23 +02:00
Johan Siebens 6e3e22bc72 chore: remove config flags for now 2022-09-23 10:36:55 +02:00
Johan Siebens 0051eec355 feat: configure magic dns suffix 2022-09-22 18:23:42 +02:00
Johan Siebens 617575803c chore: remove auth provider config from flags and env variables 2022-09-22 18:05:03 +02:00
Johan Siebens 8c6ea9041b fix: system admin can always use tags 2022-09-22 16:49:38 +02:00
39 changed files with 1967 additions and 465 deletions
+4
View File
@@ -4,6 +4,9 @@ on:
push:
branches:
- '*'
pull_request:
branches:
- main
jobs:
build:
@@ -19,4 +22,5 @@ jobs:
- name: Build
run: |
go test ./...
go build cmd/ionscale/main.go
+48
View File
@@ -0,0 +1,48 @@
name: "Security Analysis"
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0'
jobs:
codeql:
name: CodeQL
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: go
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
trivy:
name: Trivy
runs-on: ubuntu-latest
permissions:
actions: read
security-events: write
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ghcr.io/jsiebens/ionscale:latest
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: 'trivy-results.sarif'
+4 -14
View File
@@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"github.com/lib/pq"
"github.com/pkg/errors"
"time"
)
@@ -16,13 +15,9 @@ type pgPubsub struct {
target Pubsub
}
// NewPubsub creates a new Pubsub implementation using a PostgreSQL connection.
func NewPubsub(ctx context.Context, database *sql.DB, connectURL string) (Pubsub, error) {
// Creates a new listener using pq.
errCh := make(chan error)
listener := pq.NewListener(connectURL, time.Second, time.Minute, func(event pq.ListenerEventType, err error) {
// This callback gets events whenever the connection state changes.
// Don't send if the errChannel has already been closed.
select {
case <-errCh:
return
@@ -35,14 +30,14 @@ func NewPubsub(ctx context.Context, database *sql.DB, connectURL string) (Pubsub
select {
case err := <-errCh:
if err != nil {
return nil, errors.Errorf("create pq listener: %w", err)
return nil, fmt.Errorf("create pq listener: %w", err)
}
case <-ctx.Done():
return nil, ctx.Err()
}
if err := listener.Listen("ionscale_events"); err != nil {
return nil, errors.Errorf("listen: %w", err)
return nil, fmt.Errorf("listen: %w", err)
}
pubsub := &pgPubsub{
@@ -55,7 +50,6 @@ func NewPubsub(ctx context.Context, database *sql.DB, connectURL string) (Pubsub
return pubsub, nil
}
// Close closes the pubsub instance.
func (p *pgPubsub) Close() error {
return p.pgListener.Close()
}
@@ -75,18 +69,14 @@ func (p *pgPubsub) Publish(tailnet uint64, message *Signal) error {
return err
}
// This is safe because we are calling pq.QuoteLiteral. pg_notify doesn't
// support the first parameter being a prepared statement.
//nolint:gosec
_, err = p.db.ExecContext(context.Background(), `select pg_notify(`+pq.QuoteLiteral("ionscale_events")+`, $1)`, payload)
if err != nil {
fmt.Println(err)
return errors.Errorf("exec pg_notify: %w", err)
return fmt.Errorf("exec pg_notify: %w", err)
}
return nil
}
// listen begins receiving messages on the pq listener.
func (p *pgPubsub) listen(ctx context.Context) {
var (
notif *pq.Notification
+111 -53
View File
@@ -29,6 +29,8 @@ func machineCommands() *coral.Command {
command.AddCommand(enableMachineRoutesCommand())
command.AddCommand(disableMachineRoutesCommand())
command.AddCommand(enableMachineKeyExpiryCommand())
command.AddCommand(enableExitNodeCommand())
command.AddCommand(disableExitNodeCommand())
command.AddCommand(disableMachineKeyExpiryCommand())
return command
@@ -126,6 +128,16 @@ func getMachineCommand() *coral.Command {
}
}
if m.AdvertisedExitNode {
if m.EnabledExitNode {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "enabled")
} else {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "disabled")
}
} else {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "no")
}
return nil
}
@@ -279,25 +291,7 @@ func getMachineRoutesCommand() *coral.Command {
return err
}
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
defer w.Flush()
for i, t := range resp.Msg.AdvertisedRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Advertised routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
for i, t := range resp.Msg.EnabledRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Enabled routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
printMachinesRoutesResponse(resp.Msg)
return nil
}
@@ -341,25 +335,7 @@ func enableMachineRoutesCommand() *coral.Command {
return err
}
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
defer w.Flush()
for i, t := range resp.Msg.AdvertisedRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Advertised routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
for i, t := range resp.Msg.EnabledRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Enabled routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
printMachinesRoutesResponse(resp.Msg)
return nil
}
@@ -401,26 +377,76 @@ func disableMachineRoutesCommand() *coral.Command {
return err
}
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
defer w.Flush()
printMachinesRoutesResponse(resp.Msg)
for i, t := range resp.Msg.AdvertisedRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Advertised routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
return nil
}
return command
}
func enableExitNodeCommand() *coral.Command {
command := &coral.Command{
Use: "enable-exit-node",
Short: "Enable given machine as an exit node",
SilenceUsage: true,
}
var machineID uint64
var target = Target{}
target.prepareCommand(command)
command.Flags().Uint64Var(&machineID, "machine-id", 0, "Machine ID")
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
}
for i, t := range resp.Msg.EnabledRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Enabled routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
req := api.EnableExitNodeRequest{MachineId: machineID}
resp, err := client.EnableExitNode(context.Background(), connect.NewRequest(&req))
if err != nil {
return err
}
printMachinesRoutesResponse(resp.Msg)
return nil
}
return command
}
func disableExitNodeCommand() *coral.Command {
command := &coral.Command{
Use: "disable-exit-node",
Short: "Disable given machine as an exit node",
SilenceUsage: true,
}
var machineID uint64
var target = Target{}
target.prepareCommand(command)
command.Flags().Uint64Var(&machineID, "machine-id", 0, "Machine ID")
_ = command.MarkFlagRequired("machine-id")
command.RunE = func(command *coral.Command, args []string) error {
client, err := target.createGRPCClient()
if err != nil {
return err
}
req := api.DisableExitNodeRequest{MachineId: machineID}
resp, err := client.DisableExitNode(context.Background(), connect.NewRequest(&req))
if err != nil {
return err
}
printMachinesRoutesResponse(resp.Msg)
return nil
}
@@ -472,3 +498,35 @@ func configureSetMachineKeyExpiryCommand(command *coral.Command, v bool) *coral.
return command
}
func printMachinesRoutesResponse(msg *api.GetMachineRoutesResponse) {
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
defer w.Flush()
for i, t := range msg.AdvertisedRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Advertised routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
for i, t := range msg.EnabledRoutes {
if i == 0 {
fmt.Fprintf(w, "%s\t%s\n", "Enabled routes", t)
} else {
fmt.Fprintf(w, "%s\t%s\n", "", t)
}
}
if msg.AdvertisedExitNode {
if msg.EnabledExitNode {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "enabled")
} else {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "disabled")
}
} else {
fmt.Fprintf(w, "%s\t%s\n", "Exit node", "no")
}
}
+1 -45
View File
@@ -4,7 +4,6 @@ import (
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/server"
"github.com/muesli/coral"
"time"
)
func serverCommand() *coral.Command {
@@ -14,15 +13,13 @@ func serverCommand() *coral.Command {
SilenceUsage: true,
}
var cbf = configByFlags{}
var configFile string
cbf.prepareCommand(command)
command.Flags().StringVarP(&configFile, "config", "c", "", "Path to the configuration file.")
command.RunE = func(command *coral.Command, args []string) error {
c, err := config.LoadConfig(configFile, &cbf.c)
c, err := config.LoadConfig(configFile)
if err != nil {
return err
}
@@ -32,44 +29,3 @@ func serverCommand() *coral.Command {
return command
}
type configByFlags struct {
c config.Config
}
func (c *configByFlags) prepareCommand(cmd *coral.Command) {
cmd.Flags().StringVar(&c.c.HttpListenAddr, "http-listen-addr", "", "")
cmd.Flags().StringVar(&c.c.HttpsListenAddr, "https-listen-addr", "", "")
cmd.Flags().StringVar(&c.c.MetricsListenAddr, "metrics-listen-addr", "", "")
cmd.Flags().StringVar(&c.c.ServerUrl, "server-url", "", "")
cmd.Flags().BoolVar(&c.c.Tls.Disable, "tls-disable", false, "")
cmd.Flags().BoolVar(&c.c.Tls.ForceHttps, "tls-force-https", true, "")
cmd.Flags().StringVar(&c.c.Tls.CertFile, "tls-cert-file", "", "")
cmd.Flags().StringVar(&c.c.Tls.KeyFile, "tls-key-file", "", "")
cmd.Flags().BoolVar(&c.c.Tls.AcmeEnabled, "tls-acme", false, "")
cmd.Flags().StringVar(&c.c.Tls.AcmeEmail, "tls-acme-email", "", "")
cmd.Flags().StringVar(&c.c.Tls.AcmeCA, "tls-acme-ca", "", "")
cmd.Flags().StringVar(&c.c.Tls.AcmePath, "tls-acme-path", "", "")
cmd.Flags().DurationVar(&c.c.PollNet.KeepAliveInterval, "poll-net-keep-alive-interval", 1*time.Minute, "")
cmd.Flags().StringVar(&c.c.Keys.SystemAdminKey, "system-admin-key", "", "")
cmd.Flags().StringVar(&c.c.Keys.ControlKey, "control-key", "", "")
cmd.Flags().StringVar(&c.c.Keys.LegacyControlKey, "legacy-control-key", "", "")
cmd.Flags().StringVar(&c.c.Database.Type, "database-type", "", "")
cmd.Flags().StringVar(&c.c.Database.Url, "database-url", "", "")
cmd.Flags().StringVar(&c.c.AuthProvider.Issuer, "auth-provider-issuer", "", "")
cmd.Flags().StringVar(&c.c.AuthProvider.ClientID, "auth-provider-client-id", "", "")
cmd.Flags().StringVar(&c.c.AuthProvider.ClientSecret, "auth-provider-client-secret", "", "")
cmd.Flags().StringSliceVar(&c.c.AuthProvider.Scopes, "auth-provider-additional-scopes", []string{}, "")
cmd.Flags().StringSliceVar(&c.c.AuthProvider.SystemAdminPolicy.Subs, "auth-provider-system-admins-subs", []string{}, "")
cmd.Flags().StringSliceVar(&c.c.AuthProvider.SystemAdminPolicy.Emails, "auth-provider-system-admins-emails", []string{}, "")
cmd.Flags().StringSliceVar(&c.c.AuthProvider.SystemAdminPolicy.Filters, "auth-provider-system-admins-filters", []string{}, "")
cmd.Flags().StringVar(&c.c.Logging.Level, "logging-level", "", "")
cmd.Flags().StringVar(&c.c.Logging.Format, "logging-format", "", "")
cmd.Flags().StringVar(&c.c.Logging.File, "logging-file", "", "")
}
+46 -2
View File
@@ -4,9 +4,11 @@ import (
"context"
"fmt"
"github.com/bufbuild/connect-go"
idomain "github.com/jsiebens/ionscale/internal/domain"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/rodaine/table"
"strings"
)
func tailnetCommand() *coral.Command {
@@ -71,20 +73,62 @@ func createTailnetsCommand() *coral.Command {
}
var name string
var domain string
var email string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVarP(&name, "name", "n", "", "")
_ = command.MarkFlagRequired("name")
command.Flags().StringVar(&domain, "domain", "", "")
command.Flags().StringVar(&email, "email", "", "")
command.PreRunE = func(cmd *coral.Command, args []string) error {
if name == "" && email == "" && domain == "" {
return fmt.Errorf("at least flag --name, --email or --domain is required")
}
if domain != "" && email != "" {
return fmt.Errorf("flags --email and --domain are mutually exclusive")
}
return nil
}
command.RunE = func(command *coral.Command, args []string) error {
var tailnetName = ""
var iamPolicy = api.IAMPolicy{}
if len(domain) != 0 {
domainToLower := strings.ToLower(domain)
tailnetName = domainToLower
iamPolicy = api.IAMPolicy{
Filters: []string{fmt.Sprintf("domain == %s", domainToLower)},
}
}
if len(email) != 0 {
emailToLower := strings.ToLower(email)
tailnetName = emailToLower
iamPolicy = api.IAMPolicy{
Emails: []string{emailToLower},
Roles: map[string]string{
emailToLower: string(idomain.UserRoleAdmin),
},
}
}
if len(name) != 0 {
tailnetName = name
}
client, err := target.createGRPCClient()
if err != nil {
return err
}
resp, err := client.CreateTailnet(context.Background(), connect.NewRequest(&api.CreateTailnetRequest{Name: name}))
resp, err := client.CreateTailnet(context.Background(), connect.NewRequest(&api.CreateTailnetRequest{
Name: tailnetName,
IamPolicy: &iamPolicy,
}))
if err != nil {
return err
+61 -29
View File
@@ -5,6 +5,7 @@ import (
"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"
@@ -16,11 +17,25 @@ import (
"time"
)
var (
KeepAliveInterval = 1 * time.Minute
const (
defaultKeepAliveInterval = 1 * time.Minute
defaultMagicDNSSuffix = "ionscale.net"
)
func LoadConfig(path string, flagsCfg *Config) (*Config, error) {
var (
keepAliveInterval = defaultKeepAliveInterval
magicDNSSuffix = defaultMagicDNSSuffix
)
func KeepAliveInterval() time.Duration {
return keepAliveInterval
}
func MagicDNSSuffix() string {
return magicDNSSuffix
}
func LoadConfig(path string) (*Config, error) {
cfg := defaultConfig()
if len(path) != 0 {
@@ -49,16 +64,14 @@ func LoadConfig(path string, flagsCfg *Config) (*Config, error) {
return nil, err
}
// merge flag configuration on top of the default/file configuration
if err := mergo.Merge(cfg, flagsCfg, mergo.WithOverride); 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
magicDNSSuffix = cfg.DNS.MagicDNSSuffix
return cfg, nil
}
@@ -79,8 +92,15 @@ func defaultConfig() *Config {
AcmeCA: certmagic.LetsEncryptProductionCA,
AcmePath: "./acme",
},
PollNet: PollNet{KeepAliveInterval: 1 * time.Minute},
Logging: Logging{Level: "info"},
PollNet: PollNet{
KeepAliveInterval: defaultKeepAliveInterval,
},
DNS: DNS{
MagicDNSSuffix: defaultMagicDNSSuffix,
},
Logging: Logging{
Level: "info",
},
}
}
@@ -99,7 +119,8 @@ type Config struct {
PollNet PollNet `yaml:"poll_net,omitempty" envPrefix:"POLL_NET_"`
Keys Keys `yaml:"keys,omitempty" envPrefix:"KEYS_"`
Database Database `yaml:"database,omitempty" envPrefix:"DB_"`
AuthProvider AuthProvider `yaml:"auth_provider,omitempty" envPrefix:"AUTH_PROVIDER_"`
AuthProvider AuthProvider `yaml:"auth_provider,omitempty"`
DNS DNS `yaml:"dns,omitempty"`
Logging Logging `yaml:"logging,omitempty" envPrefix:"LOGGING_"`
}
@@ -136,17 +157,21 @@ type Keys struct {
}
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:"ADDITIONAL_SCOPES"`
SystemAdminPolicy SystemAdminPolicy `yaml:"system_admins" envPrefix:"SYSTEM_ADMINS_"`
Issuer string `yaml:"issuer"`
ClientID string `yaml:"client_id"`
ClientSecret string `yaml:"client_secret"`
Scopes []string `yaml:"additional_scopes"`
SystemAdminPolicy SystemAdminPolicy `yaml:"system_admins"`
}
type DNS struct {
MagicDNSSuffix string `yaml:"magic_dns_suffix"`
}
type SystemAdminPolicy struct {
Subs []string `json:"subs,omitempty" env:"SUBS"`
Emails []string `json:"emails,omitempty" env:"EMAILS"`
Filters []string `json:"filters,omitempty" env:"FILTERS"`
Subs []string `json:"subs,omitempty"`
Emails []string `json:"emails,omitempty"`
Filters []string `json:"filters,omitempty"`
}
func (c *Config) CreateUrl(format string, a ...interface{}) string {
@@ -154,8 +179,11 @@ func (c *Config) CreateUrl(format string, a ...interface{}) string {
return strings.TrimSuffix(c.ServerUrl, "/") + "/" + strings.TrimPrefix(path, "/")
}
func (c *Config) ReadServerKeys() (*ServerKeys, error) {
keys := &ServerKeys{}
func (c *Config) ReadServerKeys(defaultKeys *domain.ControlKeys) (*ServerKeys, error) {
keys := &ServerKeys{
ControlKey: defaultKeys.ControlKey,
LegacyControlKey: defaultKeys.LegacyControlKey,
}
if len(c.Keys.SystemAdminKey) != 0 {
systemAdminKey, err := key.ParsePrivateKey(c.Keys.SystemAdminKey)
@@ -166,17 +194,21 @@ func (c *Config) ReadServerKeys() (*ServerKeys, error) {
keys.SystemAdminKey = systemAdminKey
}
controlKey, err := util.ParseMachinePrivateKey(c.Keys.ControlKey)
if err != nil {
return nil, fmt.Errorf("error reading control key: %v", err)
if len(c.Keys.ControlKey) != 0 {
controlKey, err := util.ParseMachinePrivateKey(c.Keys.ControlKey)
if err != nil {
return nil, fmt.Errorf("error reading control key: %v", err)
}
keys.ControlKey = *controlKey
}
keys.ControlKey = *controlKey
legacyControlKey, err := util.ParseMachinePrivateKey(c.Keys.LegacyControlKey)
if err != nil {
return nil, fmt.Errorf("error reading legacy control key: %v", err)
if len(c.Keys.LegacyControlKey) != 0 {
legacyControlKey, err := util.ParseMachinePrivateKey(c.Keys.LegacyControlKey)
if err != nil {
return nil, fmt.Errorf("error reading legacy control key: %v", err)
}
keys.LegacyControlKey = *legacyControlKey
}
keys.LegacyControlKey = *legacyControlKey
return keys, nil
}
+28
View File
@@ -8,6 +8,7 @@ import (
"github.com/hashicorp/go-hclog"
"github.com/jsiebens/ionscale/internal/broker"
"github.com/jsiebens/ionscale/internal/database/migration"
"tailscale.com/types/key"
"time"
"github.com/jsiebens/ionscale/internal/config"
@@ -77,6 +78,33 @@ func migrate(db *gorm.DB) error {
return err
}
ctx := context.Background()
repository := domain.NewRepository(db)
if err := createServerKey(ctx, repository); err != nil {
return err
}
return nil
}
func createServerKey(ctx context.Context, repository domain.Repository) error {
serverKey, err := repository.GetControlKeys(ctx)
if err != nil {
return err
}
if serverKey != nil {
return nil
}
keys := domain.ControlKeys{
ControlKey: key.NewMachine(),
LegacyControlKey: key.NewMachine(),
}
if err := repository.SetControlKeys(ctx, &keys); err != nil {
return err
}
return nil
}
@@ -0,0 +1,23 @@
package migration
import (
"github.com/go-gormigrate/gormigrate/v2"
"github.com/jsiebens/ionscale/internal/domain"
"gorm.io/gorm"
)
func m202209251530_add_autoallowips_column() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202209251530",
Migrate: func(db *gorm.DB) error {
type Machine struct {
AutoAllowIPs domain.AllowIPs
}
return db.AutoMigrate(
&Machine{},
)
},
Rollback: nil,
}
}
@@ -7,6 +7,7 @@ import (
func Migrations() []*gormigrate.Migration {
var migrations = []*gormigrate.Migration{
m202209070900_initial_schema(),
m202209251530_add_autoallowips_column(),
}
return migrations
}
+203 -45
View File
@@ -8,16 +8,29 @@ import (
"gorm.io/gorm"
"gorm.io/gorm/schema"
"net/netip"
"sort"
"strconv"
"strings"
"tailscale.com/tailcfg"
)
const (
AutoGroupSelf = "autogroup:self"
AutoGroupMembers = "autogroup:members"
AutoGroupInternet = "autogroup:internet"
)
type AutoApprovers struct {
Routes map[string][]string `json:"routes"`
ExitNode []string `json:"exitNode"`
}
type ACLPolicy struct {
Groups map[string][]string `json:"groups,omitempty"`
Hosts map[string]string `json:"hosts,omitempty"`
ACLs []ACL `json:"acls"`
TagOwners map[string][]string `json:"tagowners"`
Groups map[string][]string `json:"groups,omitempty"`
Hosts map[string]string `json:"hosts,omitempty"`
ACLs []ACL `json:"acls"`
TagOwners map[string][]string `json:"tagowners"`
AutoApprovers AutoApprovers `json:"autoApprovers"`
}
type ACL struct {
@@ -38,14 +51,69 @@ func DefaultPolicy() ACLPolicy {
}
}
func (a ACLPolicy) CheckTags(tags []string) error {
var result *multierror.Error
for _, t := range tags {
if _, ok := a.TagOwners[t]; !ok {
result = multierror.Append(result, fmt.Errorf("tag [%s] is invalid or not permitted", t))
func (a ACLPolicy) FindAutoApprovedIPs(routableIPs []netip.Prefix, tags []string, u *User) []netip.Prefix {
if len(routableIPs) == 0 {
return nil
}
matches := func(values []string) bool {
for _, alias := range values {
if alias == u.Name {
return true
}
group, ok := a.Groups[alias]
if ok {
for _, g := range group {
if g == u.Name {
return true
}
}
}
if strings.HasPrefix(alias, "tag:") {
for _, tag := range tags {
if alias == tag {
return true
}
}
}
}
return false
}
isAutoApproved := func(candidate netip.Prefix, approvedIPs []netip.Prefix) bool {
for _, approvedIP := range approvedIPs {
if candidate.Bits() >= approvedIP.Bits() && approvedIP.Contains(candidate.Masked().Addr()) {
return true
}
}
return false
}
autoApprovedIPs := []netip.Prefix{}
for route, autoApprovers := range a.AutoApprovers.Routes {
candidate, err := netip.ParsePrefix(route)
if err != nil {
return nil
}
if matches(autoApprovers) {
autoApprovedIPs = append(autoApprovedIPs, candidate)
}
}
return result.ErrorOrNil()
result := []netip.Prefix{}
for _, c := range routableIPs {
if c.Bits() == 0 && matches(a.AutoApprovers.ExitNode) {
result = append(result, c)
}
if isAutoApproved(c, autoApprovedIPs) {
result = append(result, c)
}
}
return result
}
func (a ACLPolicy) CheckTagOwners(tags []string, p *User) error {
@@ -93,33 +161,34 @@ func (a ACLPolicy) IsValidPeer(src *Machine, dest *Machine) bool {
}
for _, acl := range a.ACLs {
allDestPorts := a.expandMachineToDstPorts(dest, acl.Dst)
if len(allDestPorts) == 0 {
continue
selfDestPorts, allDestPorts := a.expandMachineToDstPorts(dest, acl.Dst)
if len(selfDestPorts) != 0 {
for _, alias := range acl.Src {
if len(a.expandMachineAlias(src, alias, true, &dest.User)) != 0 {
return true
}
}
}
for _, alias := range acl.Src {
if len(a.expandMachineAlias(src, alias, true)) != 0 {
return true
if len(allDestPorts) != 0 {
for _, alias := range acl.Src {
if len(a.expandMachineAlias(src, alias, true, nil)) != 0 {
return true
}
}
}
}
return false
}
func (a ACLPolicy) BuildFilterRules(srcs []Machine, dst *Machine) []tailcfg.FilterRule {
var rules []tailcfg.FilterRule
for _, acl := range a.ACLs {
allDestPorts := a.expandMachineToDstPorts(dst, acl.Dst)
if len(allDestPorts) == 0 {
continue
}
transform := func(src []string, destPorts []tailcfg.NetPortRange, u *User) tailcfg.FilterRule {
var allSrcIPsSet = &StringSet{}
for _, alias := range acl.Src {
for _, alias := range src {
for _, src := range srcs {
srcIPs := a.expandMachineAlias(&src, alias, true)
srcIPs := a.expandMachineAlias(&src, alias, true, u)
allSrcIPsSet.Add(srcIPs...)
}
}
@@ -130,12 +199,20 @@ func (a ACLPolicy) BuildFilterRules(srcs []Machine, dst *Machine) []tailcfg.Filt
allSrcIPs = nil
}
rule := tailcfg.FilterRule{
return tailcfg.FilterRule{
SrcIPs: allSrcIPs,
DstPorts: allDestPorts,
DstPorts: destPorts,
}
}
rules = append(rules, rule)
for _, acl := range a.ACLs {
selfDestPorts, allDestPorts := a.expandMachineToDstPorts(dst, acl.Dst)
if len(selfDestPorts) != 0 {
rules = append(rules, transform(acl.Src, selfDestPorts, &dst.User))
}
if len(allDestPorts) != 0 {
rules = append(rules, transform(acl.Src, allDestPorts, nil))
}
}
if len(rules) == 0 {
@@ -145,19 +222,24 @@ func (a ACLPolicy) BuildFilterRules(srcs []Machine, dst *Machine) []tailcfg.Filt
return rules
}
func (a ACLPolicy) expandMachineToDstPorts(m *Machine, ports []string) []tailcfg.NetPortRange {
allDestRanges := []tailcfg.NetPortRange{}
func (a ACLPolicy) expandMachineToDstPorts(m *Machine, ports []string) ([]tailcfg.NetPortRange, []tailcfg.NetPortRange) {
selfDestRanges := []tailcfg.NetPortRange{}
otherDestRanges := []tailcfg.NetPortRange{}
for _, d := range ports {
ranges := a.expandMachineDestToNetPortRanges(m, d)
allDestRanges = append(allDestRanges, ranges...)
self, ranges := a.expandMachineDestToNetPortRanges(m, d)
if self {
selfDestRanges = append(selfDestRanges, ranges...)
} else {
otherDestRanges = append(otherDestRanges, ranges...)
}
}
return allDestRanges
return selfDestRanges, otherDestRanges
}
func (a ACLPolicy) expandMachineDestToNetPortRanges(m *Machine, dest string) []tailcfg.NetPortRange {
func (a ACLPolicy) expandMachineDestToNetPortRanges(m *Machine, dest string) (bool, []tailcfg.NetPortRange) {
tokens := strings.Split(dest, ":")
if len(tokens) < 2 || len(tokens) > 3 {
return nil
return false, nil
}
var alias string
@@ -169,12 +251,12 @@ func (a ACLPolicy) expandMachineDestToNetPortRanges(m *Machine, dest string) []t
ports, err := a.expandValuePortToPortRange(tokens[len(tokens)-1])
if err != nil {
return nil
return false, nil
}
ips := a.expandMachineAlias(m, alias, false)
ips := a.expandMachineAlias(m, alias, false, nil)
if len(ips) == 0 {
return nil
return false, nil
}
dests := []tailcfg.NetPortRange{}
@@ -188,18 +270,40 @@ func (a ACLPolicy) expandMachineDestToNetPortRanges(m *Machine, dest string) []t
}
}
return dests
return alias == AutoGroupSelf, dests
}
func (a ACLPolicy) expandMachineAlias(m *Machine, alias string, src bool) []string {
func (a ACLPolicy) expandMachineAlias(m *Machine, alias string, src bool, u *User) []string {
if u != nil && m.HasTags() {
return []string{}
}
if u != nil && !m.HasUser(u.Name) {
return []string{}
}
if alias == "*" && u != nil {
return m.IPs()
}
if alias == "*" {
if alias == "*" {
return []string{"*"}
return []string{"*"}
}
if alias == AutoGroupMembers || alias == AutoGroupSelf {
if !m.HasTags() {
return m.IPs()
} else {
return []string{}
}
}
if alias == AutoGroupInternet && m.IsExitNode() {
return autogroupInternetRanges()
}
if strings.Contains(alias, "@") && !m.HasTags() && m.HasUser(alias) {
return []string{m.IPv4.String(), m.IPv6.String()}
return m.IPs()
}
if strings.HasPrefix(alias, "group:") && !m.HasTags() {
@@ -211,7 +315,7 @@ func (a ACLPolicy) expandMachineAlias(m *Machine, alias string, src bool) []stri
for _, u := range users {
if m.HasUser(u) {
return []string{m.IPv4.String(), m.IPv6.String()}
return m.IPs()
}
}
@@ -219,7 +323,7 @@ func (a ACLPolicy) expandMachineAlias(m *Machine, alias string, src bool) []stri
}
if strings.HasPrefix(alias, "tag:") && m.HasTag(alias) {
return []string{m.IPv4.String(), m.IPv6.String()}
return m.IPs()
}
if h, ok := a.Hosts[alias]; ok {
@@ -332,5 +436,59 @@ func (s *StringSet) Items() []string {
for i := range s.items {
items = append(items, i)
}
sort.Strings(items)
return items
}
func autogroupInternetRanges() []string {
return []string{
"0.0.0.0/5",
"8.0.0.0/7",
"11.0.0.0/8",
"12.0.0.0/6",
"16.0.0.0/4",
"32.0.0.0/3",
"64.0.0.0/3",
"96.0.0.0/6",
"100.0.0.0/10",
"100.128.0.0/9",
"101.0.0.0/8",
"102.0.0.0/7",
"104.0.0.0/5",
"112.0.0.0/4",
"128.0.0.0/3",
"160.0.0.0/5",
"168.0.0.0/8",
"169.0.0.0/9",
"169.128.0.0/10",
"169.192.0.0/11",
"169.224.0.0/12",
"169.240.0.0/13",
"169.248.0.0/14",
"169.252.0.0/15",
"169.255.0.0/16",
"170.0.0.0/7",
"172.0.0.0/12",
"172.32.0.0/11",
"172.64.0.0/10",
"172.128.0.0/9",
"173.0.0.0/8",
"174.0.0.0/7",
"176.0.0.0/4",
"192.0.0.0/9",
"192.128.0.0/11",
"192.160.0.0/13",
"192.169.0.0/16",
"192.170.0.0/15",
"192.172.0.0/14",
"192.176.0.0/12",
"192.192.0.0/10",
"193.0.0.0/8",
"194.0.0.0/7",
"196.0.0.0/6",
"200.0.0.0/5",
"208.0.0.0/4",
"224.0.0.0/3",
"2000::/3",
}
}
+576
View File
@@ -1,10 +1,493 @@
package domain
import (
"encoding/json"
"fmt"
"github.com/jsiebens/ionscale/internal/addr"
"github.com/stretchr/testify/assert"
"net/netip"
"sort"
"tailscale.com/tailcfg"
"testing"
)
func printRules(rules []tailcfg.FilterRule) {
indent, err := json.MarshalIndent(rules, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(indent))
}
func TestACLPolicy_BuildFilterRulesWildcards(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"*:*"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{"*"},
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesWithGroups(t *testing.T) {
p1 := createMachine("jane@example.com")
p2 := createMachine("nick@example.com")
p3 := createMachine("joe@example.com")
policy := ACLPolicy{
Groups: map[string][]string{
"group:admin": []string{"jane@example.com"},
"group:audit": []string{"nick@example.com"},
},
ACLs: []ACL{
{
Action: "accept",
Src: []string{"group:admin"},
Dst: []string{"*:22"},
},
{
Action: "accept",
Src: []string{"group:audit"},
Dst: []string{"*:8000-8080"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2, *p3}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 22,
Last: 22,
},
},
},
},
{
SrcIPs: []string{
p2.IPv4.String(),
p2.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 8000,
Last: 8080,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesWithAutoGroupMembers(t *testing.T) {
p1 := createMachine("jane@example.com")
p2 := createMachine("nick@example.com")
p3 := createMachine("joe@example.com", "tag:web")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"autogroup:members"},
Dst: []string{"*:22"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2, *p3}, dst)
expectedSrcIPs := []string{
p1.IPv4.String(), p1.IPv6.String(),
p2.IPv4.String(), p2.IPv6.String(),
}
sort.Strings(expectedSrcIPs)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: expectedSrcIPs,
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 22,
Last: 22,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupSelf(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"autogroup:self:*"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: dst.IPv4.String(),
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
{
IP: dst.IPv6.String(),
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupSelfAndTags(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("john@example.com", "tag:web")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"autogroup:self:*"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: dst.IPv4.String(),
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
{
IP: dst.IPv6.String(),
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupSelfAndOtherDestinations(t *testing.T) {
p1 := createMachine("john@example.com")
p2 := createMachine("john@example.com", "tag:web")
p3 := createMachine("jane@example.com")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"autogroup:self:22", "john@example.com:80"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2, *p3}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: p1.IPs(),
DstPorts: []tailcfg.NetPortRange{
{
IP: dst.IPv4.String(),
Ports: tailcfg.PortRange{
First: 22,
Last: 22,
},
},
{
IP: dst.IPv6.String(),
Ports: tailcfg.PortRange{
First: 22,
Last: 22,
},
},
},
},
{
SrcIPs: []string{"*"},
DstPorts: []tailcfg.NetPortRange{
{
IP: dst.IPv4.String(),
Ports: tailcfg.PortRange{
First: 80,
Last: 80,
},
},
{
IP: dst.IPv6.String(),
Ports: tailcfg.PortRange{
First: 80,
Last: 80,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupMember(t *testing.T) {
p1 := createMachine("jane@example.com")
p2 := createMachine("jane@example.com", "tag:web")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"autogroup:members"},
Dst: []string{"*:*"},
},
},
}
dst := createMachine("john@example.com")
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: []tailcfg.NetPortRange{
{
IP: "*",
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
},
},
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestACLPolicy_BuildFilterRulesAutogroupInternet(t *testing.T) {
p1 := createMachine("nick@example.com")
p2 := createMachine("jane@example.com")
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"nick@example.com"},
Dst: []string{"autogroup:internet:*"},
},
},
}
dst := createMachine("john@example.com")
dst.AllowIPs = []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
}
expectedDstPorts := []tailcfg.NetPortRange{}
for _, r := range autogroupInternetRanges() {
expectedDstPorts = append(expectedDstPorts, tailcfg.NetPortRange{
IP: r,
Ports: tailcfg.PortRange{
First: 0,
Last: 65535,
},
})
}
actualRules := policy.BuildFilterRules([]Machine{*p1, *p2}, dst)
expectedRules := []tailcfg.FilterRule{
{
SrcIPs: []string{
p1.IPv4.String(),
p1.IPv6.String(),
},
DstPorts: expectedDstPorts,
},
}
assert.Equal(t, expectedRules, actualRules)
}
func TestWithUser(t *testing.T) {
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"john@example.com:*"},
},
},
}
src := createMachine("john@example.com")
assert.True(t, policy.IsValidPeer(src, createMachine("john@example.com")))
assert.False(t, policy.IsValidPeer(src, createMachine("john@example.com", "tag:web")))
assert.False(t, policy.IsValidPeer(src, createMachine("jane@example.com")))
}
func TestWithGroup(t *testing.T) {
policy := ACLPolicy{
Groups: map[string][]string{
"group:admin": {"john@example.com"},
},
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"group:admin:*"},
},
},
}
src := createMachine("john@example.com")
assert.True(t, policy.IsValidPeer(src, createMachine("john@example.com")))
assert.False(t, policy.IsValidPeer(src, createMachine("jane@example.com")))
}
func TestWithTags(t *testing.T) {
policy := ACLPolicy{
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"tag:web:*"},
},
},
}
src := createMachine("john@example.com")
assert.True(t, policy.IsValidPeer(src, createMachine("john@example.com", "tag:web")))
assert.False(t, policy.IsValidPeer(src, createMachine("john@example.com", "tag:ci")))
}
func TestWithHosts(t *testing.T) {
dst1 := createMachine("john@example.com")
dst2 := createMachine("john@example.com")
policy := ACLPolicy{
Hosts: map[string]string{
"dst1": dst1.IPv4.String(),
},
ACLs: []ACL{
{
Action: "accept",
Src: []string{"*"},
Dst: []string{"dst1:*"},
},
},
}
src := createMachine("jane@example.com")
assert.True(t, policy.IsValidPeer(src, dst1))
assert.False(t, policy.IsValidPeer(src, dst2))
}
func createMachine(user string, tags ...string) *Machine {
ipv4, ipv6, err := addr.SelectIP(func(addr netip.Addr) (bool, error) {
return true, nil
})
if err != nil {
return nil
}
return &Machine{
IPv4: IP{ipv4},
IPv6: IP{ipv6},
User: User{
Name: user,
},
Tags: tags,
}
}
func TestACLPolicy_IsTagOwner(t *testing.T) {
policy := ACLPolicy{
Groups: map[string][]string{
@@ -76,3 +559,96 @@ func TestACLPolicy_IsTagOwner(t *testing.T) {
})
}
}
func TestACLPolicy_FindAutoApprovedIPs(t *testing.T) {
route1 := netip.MustParsePrefix("10.160.0.0/20")
route2 := netip.MustParsePrefix("10.161.0.0/20")
route3 := netip.MustParsePrefix("10.162.0.0/20")
policy := ACLPolicy{
Groups: map[string][]string{
"group:admins": {"jane@example.com"},
},
AutoApprovers: AutoApprovers{
Routes: map[string][]string{
route1.String(): {"group:admins"},
route2.String(): {"john@example.com", "tag:router"},
},
ExitNode: []string{"nick@example.com"},
},
}
testCases := []struct {
name string
tag []string
userName string
routableIPs []netip.Prefix
expected []netip.Prefix
}{
{
name: "nil",
tag: []string{},
userName: "john@example.com",
routableIPs: nil,
expected: nil,
},
{
name: "empty",
tag: []string{},
userName: "john@example.com",
routableIPs: []netip.Prefix{},
expected: nil,
},
{
name: "by user",
tag: []string{},
userName: "john@example.com",
routableIPs: []netip.Prefix{route1, route2, route3},
expected: []netip.Prefix{route2},
},
{
name: "partial by user",
tag: []string{},
userName: "john@example.com",
routableIPs: []netip.Prefix{netip.MustParsePrefix("10.161.4.0/22")},
expected: []netip.Prefix{netip.MustParsePrefix("10.161.4.0/22")},
},
{
name: "by tag",
tag: []string{"tag:router"},
routableIPs: []netip.Prefix{route1, route2, route3},
expected: []netip.Prefix{route2},
},
{
name: "by group",
userName: "jane@example.com",
routableIPs: []netip.Prefix{route1, route2, route3},
expected: []netip.Prefix{route1},
},
{
name: "no match",
userName: "nick@example.com",
routableIPs: []netip.Prefix{route1, route2, route3},
expected: []netip.Prefix{},
},
{
name: "exit",
userName: "nick@example.com",
routableIPs: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")},
expected: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")},
},
{
name: "exit no match",
userName: "john@example.com",
routableIPs: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")},
expected: []netip.Prefix{},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actualAllowedIPs := policy.FindAutoApprovedIPs(tc.routableIPs, tc.tag, &User{Name: tc.userName})
assert.Equal(t, tc.expected, actualAllowedIPs)
})
}
}
+80 -3
View File
@@ -25,9 +25,10 @@ type Machine struct {
Tags Tags
KeyExpiryDisabled bool
HostInfo HostInfo
Endpoints Endpoints
AllowIPs AllowIPs
HostInfo HostInfo
Endpoints Endpoints
AllowIPs AllowIPs
AutoAllowIPs AllowIPs
IPv4 IP
IPv6 IP
@@ -45,6 +46,10 @@ type Machine struct {
type Machines []Machine
func (m *Machine) IPs() []string {
return []string{m.IPv4.String(), m.IPv6.String()}
}
func (m *Machine) IsExpired() bool {
return !m.KeyExpiryDisabled && !m.ExpiresAt.IsZero() && m.ExpiresAt.Before(time.Now())
}
@@ -70,6 +75,54 @@ func (m *Machine) HasTags() bool {
return len(m.Tags) != 0
}
func (m *Machine) IsAdvertisedExitNode() bool {
for _, r := range m.HostInfo.RoutableIPs {
if r.Bits() == 0 {
return true
}
}
return false
}
func (m *Machine) IsAllowedExitNode() bool {
for _, r := range m.AllowIPs {
if r.Bits() == 0 {
return true
}
}
for _, r := range m.AutoAllowIPs {
if r.Bits() == 0 {
return true
}
}
return false
}
func (m *Machine) AdvertisedPrefixes() []string {
result := []string{}
for _, r := range m.HostInfo.RoutableIPs {
if r.Bits() != 0 {
result = append(result, r.String())
}
}
return result
}
func (m *Machine) AllowedPrefixes() []string {
result := StringSet{}
for _, r := range m.AllowIPs {
if r.Bits() != 0 {
result.Add(r.String())
}
}
for _, r := range m.AutoAllowIPs {
if r.Bits() != 0 {
result.Add(r.String())
}
}
return result.Items()
}
func (m *Machine) IsAllowedIP(i netip.Addr) bool {
if m.HasIP(i) {
return true
@@ -79,6 +132,11 @@ func (m *Machine) IsAllowedIP(i netip.Addr) bool {
return true
}
}
for _, t := range m.AutoAllowIPs {
if t.Contains(i) {
return true
}
}
return false
}
@@ -88,6 +146,25 @@ func (m *Machine) IsAllowedIPPrefix(i netip.Prefix) bool {
return true
}
}
for _, t := range m.AutoAllowIPs {
if t.Overlaps(i) {
return true
}
}
return false
}
func (m *Machine) IsExitNode() bool {
for _, t := range m.AllowIPs {
if t.Bits() == 0 {
return true
}
}
for _, t := range m.AutoAllowIPs {
if t.Bits() == 0 {
return true
}
}
return false
}
+4 -1
View File
@@ -11,6 +11,9 @@ import (
)
type Repository interface {
GetControlKeys(ctx context.Context) (*ControlKeys, error)
SetControlKeys(ctx context.Context, keys *ControlKeys) error
GetDERPMap(ctx context.Context) (*tailcfg.DERPMap, error)
SetDERPMap(ctx context.Context, v *tailcfg.DERPMap) error
@@ -18,7 +21,7 @@ type Repository interface {
GetOrCreateAccount(ctx context.Context, externalID, loginName string) (*Account, bool, error)
SaveTailnet(ctx context.Context, tailnet *Tailnet) error
GetOrCreateTailnet(ctx context.Context, name string) (*Tailnet, bool, error)
GetOrCreateTailnet(ctx context.Context, name string, iamPolicy IAMPolicy) (*Tailnet, bool, error)
GetTailnet(ctx context.Context, id uint64) (*Tailnet, error)
ListTailnets(ctx context.Context) ([]Tailnet, error)
DeleteTailnet(ctx context.Context, id uint64) error
+27 -1
View File
@@ -6,12 +6,14 @@ import (
"errors"
"gorm.io/gorm"
"tailscale.com/tailcfg"
tkey "tailscale.com/types/key"
)
type configKey string
const (
derpMapConfigKey configKey = "derp_map"
derpMapConfigKey configKey = "derp_map"
controlKeysConfigKey configKey = "control_keys"
)
type ServerConfig struct {
@@ -19,6 +21,30 @@ type ServerConfig struct {
Value []byte
}
type ControlKeys struct {
ControlKey tkey.MachinePrivate
LegacyControlKey tkey.MachinePrivate
}
func (r *repository) GetControlKeys(ctx context.Context) (*ControlKeys, error) {
var m ControlKeys
err := r.getServerConfig(ctx, controlKeysConfigKey, &m)
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
if err != nil {
return nil, err
}
return &m, nil
}
func (r *repository) SetControlKeys(ctx context.Context, v *ControlKeys) error {
return r.setServerConfig(ctx, controlKeysConfigKey, v)
}
func (r *repository) GetDERPMap(ctx context.Context) (*tailcfg.DERPMap, error) {
var m tailcfg.DERPMap
+22 -2
View File
@@ -5,6 +5,9 @@ import (
"errors"
"github.com/jsiebens/ionscale/internal/util"
"gorm.io/gorm"
"net/mail"
"strings"
"tailscale.com/util/dnsname"
)
type Tailnet struct {
@@ -15,6 +18,23 @@ type Tailnet struct {
ACLPolicy ACLPolicy
}
func SanitizeTailnetName(name string) string {
name = strings.ToLower(name)
a, err := mail.ParseAddress(name)
if err == nil && a.Address == name {
s := strings.Split(name, "@")
return strings.Join([]string{dnsname.SanitizeLabel(s[0]), s[1]}, ".")
}
labels := strings.Split(name, ".")
for i, s := range labels {
labels[i] = dnsname.SanitizeLabel(s)
}
return strings.Join(labels, ".")
}
func (r *repository) SaveTailnet(ctx context.Context, tailnet *Tailnet) error {
tx := r.withContext(ctx).Save(tailnet)
@@ -25,13 +45,13 @@ func (r *repository) SaveTailnet(ctx context.Context, tailnet *Tailnet) error {
return nil
}
func (r *repository) GetOrCreateTailnet(ctx context.Context, name string) (*Tailnet, bool, error) {
func (r *repository) GetOrCreateTailnet(ctx context.Context, name string, iamPolicy IAMPolicy) (*Tailnet, bool, error) {
tailnet := &Tailnet{}
id := util.NextID()
tx := r.withContext(ctx).
Where(Tailnet{Name: name}).
Attrs(Tailnet{ID: id, ACLPolicy: DefaultPolicy()}).
Attrs(Tailnet{ID: id, ACLPolicy: DefaultPolicy(), IAMPolicy: iamPolicy}).
FirstOrCreate(tailnet)
if tx.Error != nil {
+15
View File
@@ -0,0 +1,15 @@
package domain
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestSanitizeTailnetName(t *testing.T) {
assert.Equal(t, "john.example.com", SanitizeTailnetName("john@example.com"))
assert.Equal(t, "john.example.com", SanitizeTailnetName("john@examPle.Com"))
assert.Equal(t, "john-doe.example.com", SanitizeTailnetName("john.doe@example.com"))
assert.Equal(t, "johns-network", SanitizeTailnetName("John's Network"))
assert.Equal(t, "example.com", SanitizeTailnetName("example.com"))
assert.Equal(t, "johns-example.com", SanitizeTailnetName("John's example.com"))
}
+6 -2
View File
@@ -393,6 +393,8 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
return c.Redirect(http.StatusFound, "/a/error?e=nto")
}
autoAllowIPs := tailnet.ACLPolicy.FindAutoApprovedIPs(req.Hostinfo.RoutableIPs, tags, user)
var m *domain.Machine
m, err := h.repository.GetMachineByKey(ctx, tailnet.ID, machineKey)
@@ -419,9 +421,10 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
NameIdx: nameIdx,
MachineKey: machineKey,
NodeKey: nodeKey,
Ephemeral: ephemeral,
Ephemeral: ephemeral || req.Ephemeral,
RegisteredTags: registeredTags,
Tags: domain.SanitizeTags(tags),
AutoAllowIPs: autoAllowIPs,
CreatedAt: now,
ExpiresAt: now.Add(180 * 24 * time.Hour).UTC(),
KeyExpiryDisabled: len(tags) != 0,
@@ -451,9 +454,10 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, regi
m.NameIdx = nameIdx
}
m.NodeKey = nodeKey
m.Ephemeral = ephemeral
m.Ephemeral = ephemeral || req.Ephemeral
m.RegisteredTags = registeredTags
m.Tags = domain.SanitizeTags(tags)
m.AutoAllowIPs = autoAllowIPs
m.UserID = user.ID
m.User = *user
m.TailnetID = tailnet.ID
+1 -2
View File
@@ -1,7 +1,6 @@
package handlers
import (
"context"
"github.com/labstack/echo/v4"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
@@ -26,7 +25,7 @@ func NewNoiseHandlers(controlKey key.MachinePrivate, createPeerHandler CreatePee
}
func (h *NoiseHandlers) Upgrade(c echo.Context) error {
conn, err := controlhttp.AcceptHTTP(context.Background(), c.Response(), c.Request(), h.controlKey)
conn, err := controlhttp.AcceptHTTP(c.Request().Context(), c.Response(), c.Request(), h.controlKey)
if err != nil {
return err
}
+4 -5
View File
@@ -10,7 +10,6 @@ import (
"github.com/labstack/echo/v4"
"net/http"
"tailscale.com/tailcfg"
"tailscale.com/util/dnsname"
"time"
)
@@ -114,7 +113,7 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
if err != nil {
return err
}
keepAliveTicker := time.NewTicker(config.KeepAliveInterval)
keepAliveTicker := time.NewTicker(config.KeepAliveInterval())
syncTicker := time.NewTicker(5 * time.Second)
c.Response().WriteHeader(http.StatusOK)
@@ -286,7 +285,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
DNSConfig: mapping.ToDNSConfig(&m.Tailnet, &dnsConfig),
PacketFilter: rules,
DERPMap: derpMap,
Domain: dnsname.SanitizeHostname(m.Tailnet.Name),
Domain: domain.SanitizeTailnetName(m.Tailnet.Name),
Peers: changedPeers,
UserProfiles: users,
ControlTime: &controlTime,
@@ -300,7 +299,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
DNSConfig: mapping.ToDNSConfig(&m.Tailnet, &dnsConfig),
PacketFilter: rules,
DERPMap: derpMap,
Domain: dnsname.SanitizeHostname(m.Tailnet.Name),
Domain: domain.SanitizeTailnetName(m.Tailnet.Name),
PeersChanged: changedPeers,
PeersRemoved: removedPeers,
UserProfiles: users,
@@ -355,7 +354,7 @@ func (o *OfflineTimers) scheduleOfflineMessage(tailnetID, machineID uint64) {
delete(o.data, machineID)
}
timer := time.NewTimer(config.KeepAliveInterval)
timer := time.NewTimer(config.KeepAliveInterval())
go func() {
<-timer.C
o.pubsub.Publish(tailnetID, &broker.Signal{PeerUpdated: &machineID})
+10 -10
View File
@@ -156,6 +156,12 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
return binder.WriteResponse(c, http.StatusOK, response)
}
registeredTags := authKey.Tags
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
tags := append(registeredTags, advertisedTags...)
autoAllowIPs := tailnet.ACLPolicy.FindAutoApprovedIPs(req.Hostinfo.RoutableIPs, tags, &user)
var m *domain.Machine
m, err = h.repository.GetMachineByKey(ctx, tailnet.ID, machineKey)
@@ -166,10 +172,6 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
now := time.Now().UTC()
if m == nil {
registeredTags := authKey.Tags
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
tags := append(registeredTags, advertisedTags...)
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
if err != nil {
@@ -182,9 +184,10 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
NameIdx: nameIdx,
MachineKey: machineKey,
NodeKey: nodeKey,
Ephemeral: authKey.Ephemeral,
Ephemeral: authKey.Ephemeral || req.Ephemeral,
RegisteredTags: registeredTags,
Tags: domain.SanitizeTags(tags),
AutoAllowIPs: autoAllowIPs,
CreatedAt: now,
ExpiresAt: now.Add(180 * 24 * time.Hour).UTC(),
KeyExpiryDisabled: len(tags) != 0,
@@ -204,10 +207,6 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
m.IPv4 = domain.IP{Addr: ipv4}
m.IPv6 = domain.IP{Addr: ipv6}
} else {
registeredTags := authKey.Tags
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
tags := append(registeredTags, advertisedTags...)
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
if m.Name != sanitizeHostname {
nameIdx, err := h.repository.GetNextMachineNameIndex(ctx, tailnet.ID, sanitizeHostname)
@@ -218,9 +217,10 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, bi
m.NameIdx = nameIdx
}
m.NodeKey = nodeKey
m.Ephemeral = authKey.Ephemeral
m.Ephemeral = authKey.Ephemeral || req.Ephemeral
m.RegisteredTags = registeredTags
m.Tags = domain.SanitizeTags(tags)
m.AutoAllowIPs = autoAllowIPs
m.UserID = user.ID
m.User = user
m.TailnetID = tailnet.ID
+13 -15
View File
@@ -11,12 +11,9 @@ import (
"tailscale.com/tailcfg"
"tailscale.com/types/dnstype"
"tailscale.com/types/key"
"tailscale.com/util/dnsname"
"time"
)
const NetworkMagicDNSSuffix = "ionscale.net"
func CopyViaJson[F any, T any](f F, t T) error {
raw, err := json.Marshal(f)
if err != nil {
@@ -31,7 +28,7 @@ func CopyViaJson[F any, T any](f F, t T) error {
}
func ToDNSConfig(tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfig {
tailnetDomain := dnsname.SanitizeHostname(tailnet.Name)
tailnetDomain := domain.SanitizeTailnetName(tailnet.Name)
resolvers := []*dnstype.Resolver{}
for _, r := range c.Nameservers {
resolver := &dnstype.Resolver{
@@ -40,19 +37,19 @@ func ToDNSConfig(tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfi
resolvers = append(resolvers, resolver)
}
config := &tailcfg.DNSConfig{}
dnsConfig := &tailcfg.DNSConfig{}
var domains []string
if c.MagicDNS {
domains = append(domains, fmt.Sprintf("%s.%s", tailnetDomain, NetworkMagicDNSSuffix))
config.Proxied = true
domains = append(domains, fmt.Sprintf("%s.%s", tailnetDomain, config.MagicDNSSuffix()))
dnsConfig.Proxied = true
}
if c.OverrideLocalDNS {
config.Resolvers = resolvers
dnsConfig.Resolvers = resolvers
} else {
config.FallbackResolvers = resolvers
dnsConfig.FallbackResolvers = resolvers
}
if len(c.Routes) != 0 {
@@ -66,12 +63,12 @@ func ToDNSConfig(tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfi
routes[r] = routeResolver
domains = append(domains, r)
}
config.Routes = routes
dnsConfig.Routes = routes
}
config.Domains = domains
dnsConfig.Domains = domains
return config
return dnsConfig
}
func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
@@ -119,6 +116,7 @@ func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
}
allowedIPs = append(allowedIPs, m.AllowIPs...)
allowedIPs = append(allowedIPs, m.AutoAllowIPs...)
var derp string
if hostinfo.NetInfo != nil {
@@ -132,7 +130,7 @@ func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
name = fmt.Sprintf("%s-%d", m.Name, m.NameIdx)
}
sanitizedTailnetName := dnsname.SanitizeHostname(m.Tailnet.Name)
sanitizedTailnetName := domain.SanitizeTailnetName(m.Tailnet.Name)
hostInfo := tailcfg.Hostinfo{
OS: hostinfo.OS,
@@ -143,7 +141,7 @@ func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
n := tailcfg.Node{
ID: tailcfg.NodeID(m.ID),
StableID: tailcfg.StableNodeID(strconv.FormatUint(m.ID, 10)),
Name: fmt.Sprintf("%s.%s.%s.", name, sanitizedTailnetName, NetworkMagicDNSSuffix),
Name: fmt.Sprintf("%s.%s.%s.", name, sanitizedTailnetName, config.MagicDNSSuffix()),
Key: *nKey,
Machine: *mKey,
DiscoKey: discoKey,
@@ -171,7 +169,7 @@ func ToNode(m *domain.Machine) (*tailcfg.Node, *tailcfg.UserProfile, error) {
if m.LastSeen != nil {
l := m.LastSeen.UTC()
online := m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval))
online := m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval()))
n.LastSeen = &l
n.Online = &online
}
+4
View File
@@ -85,10 +85,14 @@ func (p *OIDCProvider) Exchange(redirectURI, code string) (*User, error) {
return nil, err
}
domain := strings.Split(email, "@")[1]
return &User{
ID: sub,
Name: email,
Attr: map[string]interface{}{
"email": email,
"domain": domain,
"token": tokenClaims,
"userinfo": userInfoClaims,
},
+7 -2
View File
@@ -37,12 +37,17 @@ func Start(c *config.Config) error {
logger.Info("Starting ionscale server")
serverKey, err := c.ReadServerKeys()
repository, brokers, err := database.OpenDB(&c.Database, logger)
if err != nil {
return err
}
repository, brokers, err := database.OpenDB(&c.Database, logger)
defaultControlKeys, err := repository.GetControlKeys(context.Background())
if err != nil {
return err
}
serverKey, err := c.ReadServerKeys(defaultControlKeys)
if err != nil {
return err
}
+1 -5
View File
@@ -134,11 +134,7 @@ func (s *Service) CreateAuthKey(ctx context.Context, req *connect.Request[api.Cr
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
if principal.IsSystemAdmin() {
if err := tailnet.ACLPolicy.CheckTags(req.Msg.Tags); err != nil {
return nil, connect.NewError(connect.CodeInvalidArgument, err)
}
} else {
if !principal.IsSystemAdmin() {
if err := tailnet.ACLPolicy.CheckTagOwners(req.Msg.Tags, principal.User); err != nil {
return nil, connect.NewError(connect.CodeInvalidArgument, err)
}
+8 -9
View File
@@ -6,10 +6,9 @@ import (
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/broker"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/domain"
"github.com/jsiebens/ionscale/internal/mapping"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"tailscale.com/util/dnsname"
)
func (s *Service) GetDNSConfig(ctx context.Context, req *connect.Request[api.GetDNSConfigRequest]) (*connect.Response[api.GetDNSConfigResponse], error) {
@@ -26,16 +25,16 @@ func (s *Service) GetDNSConfig(ctx context.Context, req *connect.Request[api.Get
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
}
config := tailnet.DNSConfig
tailnetDomain := dnsname.SanitizeHostname(tailnet.Name)
dnsConfig := tailnet.DNSConfig
tailnetDomain := domain.SanitizeTailnetName(tailnet.Name)
resp := &api.GetDNSConfigResponse{
Config: &api.DNSConfig{
MagicDns: config.MagicDNS,
MagicDnsSuffix: fmt.Sprintf("%s.%s", tailnetDomain, mapping.NetworkMagicDNSSuffix),
OverrideLocalDns: config.OverrideLocalDNS,
Nameservers: config.Nameservers,
Routes: domainRoutesToApiRoutes(config.Routes),
MagicDns: dnsConfig.MagicDNS,
MagicDnsSuffix: fmt.Sprintf("%s.%s", tailnetDomain, config.MagicDNSSuffix()),
OverrideLocalDns: dnsConfig.OverrideLocalDNS,
Nameservers: dnsConfig.Nameservers,
Routes: domainRoutesToApiRoutes(dnsConfig.Routes),
},
}
+100 -36
View File
@@ -25,17 +25,7 @@ func (s *Service) machineToApi(m *domain.Machine) *api.Machine {
online := false
if m.LastSeen != nil {
lastSeen = timestamppb.New(*m.LastSeen)
online = m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval))
}
var advertisedRoutes []string
for _, r := range m.HostInfo.RoutableIPs {
advertisedRoutes = append(advertisedRoutes, r.String())
}
var enabledRoutes []string
for _, r := range m.AllowIPs {
enabledRoutes = append(enabledRoutes, r.String())
online = m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval()))
}
return &api.Machine{
@@ -63,8 +53,10 @@ func (s *Service) machineToApi(m *domain.Machine) *api.Machine {
ClientConnectivity: &api.ClientConnectivity{
Endpoints: m.Endpoints,
},
AdvertisedRoutes: advertisedRoutes,
EnabledRoutes: enabledRoutes,
AdvertisedRoutes: m.AdvertisedPrefixes(),
EnabledRoutes: m.AllowedPrefixes(),
AdvertisedExitNode: m.IsAdvertisedExitNode(),
EnabledExitNode: m.IsAllowedExitNode(),
}
}
@@ -169,19 +161,11 @@ func (s *Service) ExpireMachine(ctx context.Context, req *connect.Request[api.Ex
}
func (s *Service) createMachineRoutesResponse(m *domain.Machine) (*connect.Response[api.GetMachineRoutesResponse], error) {
var advertisedRoutes []string
for _, r := range m.HostInfo.RoutableIPs {
advertisedRoutes = append(advertisedRoutes, r.String())
}
var enabledRoutes []string
for _, r := range m.AllowIPs {
enabledRoutes = append(enabledRoutes, r.String())
}
response := api.GetMachineRoutesResponse{
AdvertisedRoutes: advertisedRoutes,
EnabledRoutes: enabledRoutes,
AdvertisedRoutes: m.AdvertisedPrefixes(),
EnabledRoutes: m.AllowedPrefixes(),
AdvertisedExitNode: m.IsAdvertisedExitNode(),
EnabledExitNode: m.IsAllowedExitNode(),
}
return connect.NewResponse(&response), nil
@@ -222,23 +206,24 @@ func (s *Service) EnableMachineRoutes(ctx context.Context, req *connect.Request[
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
var enabledRoutes = domain.NewAllowIPsSet(m.AllowIPs)
var allowIPs = domain.NewAllowIPsSet(m.AllowIPs)
var autoAllowIPs = domain.NewAllowIPsSet(m.AutoAllowIPs)
if req.Msg.Replace {
enabledRoutes = domain.NewAllowIPsSet([]netip.Prefix{})
allowIPs = domain.NewAllowIPsSet([]netip.Prefix{})
autoAllowIPs = domain.NewAllowIPsSet([]netip.Prefix{})
}
var routesToBeRemoved []netip.Prefix
for _, r := range req.Msg.Routes {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return nil, err
}
enabledRoutes.Add(prefix)
routesToBeRemoved = append(routesToBeRemoved, prefix)
allowIPs.Add(prefix)
}
m.AllowIPs = enabledRoutes.Items()
m.AllowIPs = allowIPs.Items()
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
@@ -264,19 +249,98 @@ func (s *Service) DisableMachineRoutes(ctx context.Context, req *connect.Request
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
enabledRoutes := domain.NewAllowIPsSet(m.AllowIPs)
allowIPs := domain.NewAllowIPsSet(m.AllowIPs)
autoAllowIPs := domain.NewAllowIPsSet(m.AutoAllowIPs)
var routesToBeRemoved []netip.Prefix
for _, r := range req.Msg.Routes {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return nil, err
}
enabledRoutes.Remove(prefix)
routesToBeRemoved = append(routesToBeRemoved, prefix)
allowIPs.Remove(prefix)
autoAllowIPs.Remove(prefix)
}
m.AllowIPs = enabledRoutes.Items()
m.AllowIPs = allowIPs.Items()
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
s.pubsub.Publish(m.TailnetID, &broker.Signal{PeerUpdated: &m.ID})
return s.createMachineRoutesResponse(m)
}
func (s *Service) EnableExitNode(ctx context.Context, req *connect.Request[api.EnableExitNodeRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
principal := CurrentPrincipal(ctx)
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, err
}
if m == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
}
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(m.TailnetID) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
if !m.IsAdvertisedExitNode() {
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("machine is not a valid exit node"))
}
prefix4 := netip.MustParsePrefix("0.0.0.0/0")
prefix6 := netip.MustParsePrefix("::/0")
allowIPs := domain.NewAllowIPsSet(m.AllowIPs)
allowIPs.Add(prefix4, prefix6)
m.AllowIPs = allowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
s.pubsub.Publish(m.TailnetID, &broker.Signal{PeerUpdated: &m.ID})
return s.createMachineRoutesResponse(m)
}
func (s *Service) DisableExitNode(ctx context.Context, req *connect.Request[api.DisableExitNodeRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
principal := CurrentPrincipal(ctx)
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, err
}
if m == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
}
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(m.TailnetID) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
if !m.IsAdvertisedExitNode() {
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("machine is not a valid exit node"))
}
prefix4 := netip.MustParsePrefix("0.0.0.0/0")
prefix6 := netip.MustParsePrefix("::/0")
allowIPs := domain.NewAllowIPsSet(m.AllowIPs)
allowIPs.Remove(prefix4, prefix6)
autoAllowIPs := domain.NewAllowIPsSet(m.AutoAllowIPs)
autoAllowIPs.Remove(prefix4, prefix6)
m.AllowIPs = allowIPs.Items()
m.AutoAllowIPs = autoAllowIPs.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
+9 -1
View File
@@ -16,7 +16,15 @@ func (s *Service) CreateTailnet(ctx context.Context, req *connect.Request[api.Cr
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, created, err := s.repository.GetOrCreateTailnet(ctx, req.Msg.Name)
name := req.Msg.Name
iamPolicy := domain.IAMPolicy{
Subs: req.Msg.IamPolicy.Subs,
Emails: req.Msg.IamPolicy.Emails,
Filters: req.Msg.IamPolicy.Filters,
Roles: apiRolesMapToDomainRolesMap(req.Msg.IamPolicy.Roles),
}
tailnet, created, err := s.repository.GetOrCreateTailnet(ctx, name, iamPolicy)
if err != nil {
return nil, err
}
+144 -48
View File
@@ -213,10 +213,11 @@ type ACLPolicy struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Hosts map[string]string `protobuf:"bytes,1,rep,name=hosts,proto3" json:"hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Groups map[string]*structpb.ListValue `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Acls []*ACL `protobuf:"bytes,3,rep,name=acls,proto3" json:"acls,omitempty"`
Tagowners map[string]*structpb.ListValue `protobuf:"bytes,4,rep,name=tagowners,proto3" json:"tagowners,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Hosts map[string]string `protobuf:"bytes,1,rep,name=hosts,proto3" json:"hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Groups map[string]*structpb.ListValue `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Acls []*ACL `protobuf:"bytes,3,rep,name=acls,proto3" json:"acls,omitempty"`
Tagowners map[string]*structpb.ListValue `protobuf:"bytes,4,rep,name=tagowners,proto3" json:"tagowners,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Autoapprovers *AutoApprovers `protobuf:"bytes,5,opt,name=autoapprovers,proto3" json:"autoapprovers,omitempty"`
}
func (x *ACLPolicy) Reset() {
@@ -279,6 +280,13 @@ func (x *ACLPolicy) GetTagowners() map[string]*structpb.ListValue {
return nil
}
func (x *ACLPolicy) GetAutoapprovers() *AutoApprovers {
if x != nil {
return x.Autoapprovers
}
return nil
}
type ACL struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -342,6 +350,61 @@ func (x *ACL) GetDst() []string {
return nil
}
type AutoApprovers struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Routes map[string]*structpb.ListValue `protobuf:"bytes,1,rep,name=routes,proto3" json:"routes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Exitnode []string `protobuf:"bytes,2,rep,name=exitnode,proto3" json:"exitnode,omitempty"`
}
func (x *AutoApprovers) Reset() {
*x = AutoApprovers{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_acl_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AutoApprovers) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AutoApprovers) ProtoMessage() {}
func (x *AutoApprovers) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_acl_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AutoApprovers.ProtoReflect.Descriptor instead.
func (*AutoApprovers) Descriptor() ([]byte, []int) {
return file_ionscale_v1_acl_proto_rawDescGZIP(), []int{6}
}
func (x *AutoApprovers) GetRoutes() map[string]*structpb.ListValue {
if x != nil {
return x.Routes
}
return nil
}
func (x *AutoApprovers) GetExitnode() []string {
if x != nil {
return x.Exitnode
}
return nil
}
var File_ionscale_v1_acl_proto protoreflect.FileDescriptor
var file_ionscale_v1_acl_proto_rawDesc = []byte{
@@ -366,7 +429,7 @@ var file_ionscale_v1_acl_proto_rawDesc = []byte{
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x43, 0x4c, 0x50,
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x16, 0x0a,
0x14, 0x53, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd6, 0x03, 0x0a, 0x09, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x98, 0x04, 0x0a, 0x09, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c,
0x69, 0x63, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73,
@@ -381,30 +444,46 @@ var file_ionscale_v1_acl_proto_rawDesc = []byte{
0x0b, 0x32, 0x25, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x54, 0x61, 0x67, 0x6f, 0x77, 0x6e,
0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x61, 0x67, 0x6f, 0x77, 0x6e,
0x65, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x55, 0x0a,
0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x3a, 0x02, 0x38, 0x01, 0x1a, 0x58, 0x0a, 0x0e, 0x54, 0x61, 0x67, 0x6f, 0x77, 0x6e, 0x65, 0x72,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41,
0x0a, 0x03, 0x41, 0x43, 0x4c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a,
0x03, 0x73, 0x72, 0x63, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12,
0x10, 0x0a, 0x03, 0x64, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x64, 0x73,
0x74, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x6a, 0x73, 0x69, 0x65, 0x62, 0x65, 0x6e, 0x73, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x72, 0x73, 0x12, 0x40, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x61, 0x70, 0x70, 0x72, 0x6f,
0x76, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x41, 0x70, 0x70,
0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x61, 0x70, 0x70, 0x72,
0x6f, 0x76, 0x65, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a,
0x55, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x58, 0x0a, 0x0e, 0x54, 0x61, 0x67, 0x6f, 0x77, 0x6e,
0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
0x22, 0x41, 0x0a, 0x03, 0x41, 0x43, 0x4c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72,
0x63, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03,
0x64, 0x73, 0x74, 0x22, 0xc2, 0x01, 0x0a, 0x0d, 0x41, 0x75, 0x74, 0x6f, 0x41, 0x70, 0x70, 0x72,
0x6f, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3e, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72,
0x73, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x69, 0x74, 0x6e, 0x6f, 0x64,
0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x6e, 0x6f, 0x64,
0x65, 0x1a, 0x55, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65, 0x6e, 0x73, 0x2f,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e,
0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -419,7 +498,7 @@ func file_ionscale_v1_acl_proto_rawDescGZIP() []byte {
return file_ionscale_v1_acl_proto_rawDescData
}
var file_ionscale_v1_acl_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_ionscale_v1_acl_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_ionscale_v1_acl_proto_goTypes = []interface{}{
(*GetACLPolicyRequest)(nil), // 0: ionscale.v1.GetACLPolicyRequest
(*GetACLPolicyResponse)(nil), // 1: ionscale.v1.GetACLPolicyResponse
@@ -427,25 +506,30 @@ var file_ionscale_v1_acl_proto_goTypes = []interface{}{
(*SetACLPolicyResponse)(nil), // 3: ionscale.v1.SetACLPolicyResponse
(*ACLPolicy)(nil), // 4: ionscale.v1.ACLPolicy
(*ACL)(nil), // 5: ionscale.v1.ACL
nil, // 6: ionscale.v1.ACLPolicy.HostsEntry
nil, // 7: ionscale.v1.ACLPolicy.GroupsEntry
nil, // 8: ionscale.v1.ACLPolicy.TagownersEntry
(*structpb.ListValue)(nil), // 9: google.protobuf.ListValue
(*AutoApprovers)(nil), // 6: ionscale.v1.AutoApprovers
nil, // 7: ionscale.v1.ACLPolicy.HostsEntry
nil, // 8: ionscale.v1.ACLPolicy.GroupsEntry
nil, // 9: ionscale.v1.ACLPolicy.TagownersEntry
nil, // 10: ionscale.v1.AutoApprovers.RoutesEntry
(*structpb.ListValue)(nil), // 11: google.protobuf.ListValue
}
var file_ionscale_v1_acl_proto_depIdxs = []int32{
4, // 0: ionscale.v1.GetACLPolicyResponse.policy:type_name -> ionscale.v1.ACLPolicy
4, // 1: ionscale.v1.SetACLPolicyRequest.policy:type_name -> ionscale.v1.ACLPolicy
6, // 2: ionscale.v1.ACLPolicy.hosts:type_name -> ionscale.v1.ACLPolicy.HostsEntry
7, // 3: ionscale.v1.ACLPolicy.groups:type_name -> ionscale.v1.ACLPolicy.GroupsEntry
5, // 4: ionscale.v1.ACLPolicy.acls:type_name -> ionscale.v1.ACL
8, // 5: ionscale.v1.ACLPolicy.tagowners:type_name -> ionscale.v1.ACLPolicy.TagownersEntry
9, // 6: ionscale.v1.ACLPolicy.GroupsEntry.value:type_name -> google.protobuf.ListValue
9, // 7: ionscale.v1.ACLPolicy.TagownersEntry.value:type_name -> google.protobuf.ListValue
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
4, // 0: ionscale.v1.GetACLPolicyResponse.policy:type_name -> ionscale.v1.ACLPolicy
4, // 1: ionscale.v1.SetACLPolicyRequest.policy:type_name -> ionscale.v1.ACLPolicy
7, // 2: ionscale.v1.ACLPolicy.hosts:type_name -> ionscale.v1.ACLPolicy.HostsEntry
8, // 3: ionscale.v1.ACLPolicy.groups:type_name -> ionscale.v1.ACLPolicy.GroupsEntry
5, // 4: ionscale.v1.ACLPolicy.acls:type_name -> ionscale.v1.ACL
9, // 5: ionscale.v1.ACLPolicy.tagowners:type_name -> ionscale.v1.ACLPolicy.TagownersEntry
6, // 6: ionscale.v1.ACLPolicy.autoapprovers:type_name -> ionscale.v1.AutoApprovers
10, // 7: ionscale.v1.AutoApprovers.routes:type_name -> ionscale.v1.AutoApprovers.RoutesEntry
11, // 8: ionscale.v1.ACLPolicy.GroupsEntry.value:type_name -> google.protobuf.ListValue
11, // 9: ionscale.v1.ACLPolicy.TagownersEntry.value:type_name -> google.protobuf.ListValue
11, // 10: ionscale.v1.AutoApprovers.RoutesEntry.value:type_name -> google.protobuf.ListValue
11, // [11:11] is the sub-list for method output_type
11, // [11:11] is the sub-list for method input_type
11, // [11:11] is the sub-list for extension type_name
11, // [11:11] is the sub-list for extension extendee
0, // [0:11] is the sub-list for field type_name
}
func init() { file_ionscale_v1_acl_proto_init() }
@@ -527,6 +611,18 @@ func file_ionscale_v1_acl_proto_init() {
return nil
}
}
file_ionscale_v1_acl_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AutoApprovers); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -534,7 +630,7 @@ func file_ionscale_v1_acl_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ionscale_v1_acl_proto_rawDesc,
NumEnums: 0,
NumMessages: 9,
NumMessages: 11,
NumExtensions: 0,
NumServices: 0,
},
+75 -57
View File
@@ -48,7 +48,7 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31,
0x2f, 0x61, 0x63, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x72, 0x70, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x32, 0xbf, 0x13, 0x0a, 0x0f, 0x49, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53,
0x74, 0x6f, 0x32, 0xff, 0x14, 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,
@@ -204,6 +204,18 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{
0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63,
0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78,
0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x22, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e,
0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78,
0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74,
0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63,
0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 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,
@@ -240,32 +252,34 @@ var file_ionscale_v1_ionscale_proto_goTypes = []interface{}{
(*GetMachineRoutesRequest)(nil), // 25: ionscale.v1.GetMachineRoutesRequest
(*EnableMachineRoutesRequest)(nil), // 26: ionscale.v1.EnableMachineRoutesRequest
(*DisableMachineRoutesRequest)(nil), // 27: ionscale.v1.DisableMachineRoutesRequest
(*GetVersionResponse)(nil), // 28: ionscale.v1.GetVersionResponse
(*AuthenticationResponse)(nil), // 29: ionscale.v1.AuthenticationResponse
(*GetDERPMapResponse)(nil), // 30: ionscale.v1.GetDERPMapResponse
(*SetDERPMapResponse)(nil), // 31: ionscale.v1.SetDERPMapResponse
(*CreateTailnetResponse)(nil), // 32: ionscale.v1.CreateTailnetResponse
(*GetTailnetResponse)(nil), // 33: ionscale.v1.GetTailnetResponse
(*ListTailnetResponse)(nil), // 34: ionscale.v1.ListTailnetResponse
(*DeleteTailnetResponse)(nil), // 35: ionscale.v1.DeleteTailnetResponse
(*GetDNSConfigResponse)(nil), // 36: ionscale.v1.GetDNSConfigResponse
(*SetDNSConfigResponse)(nil), // 37: ionscale.v1.SetDNSConfigResponse
(*GetIAMPolicyResponse)(nil), // 38: ionscale.v1.GetIAMPolicyResponse
(*SetIAMPolicyResponse)(nil), // 39: ionscale.v1.SetIAMPolicyResponse
(*GetACLPolicyResponse)(nil), // 40: ionscale.v1.GetACLPolicyResponse
(*SetACLPolicyResponse)(nil), // 41: ionscale.v1.SetACLPolicyResponse
(*GetAuthKeyResponse)(nil), // 42: ionscale.v1.GetAuthKeyResponse
(*CreateAuthKeyResponse)(nil), // 43: ionscale.v1.CreateAuthKeyResponse
(*DeleteAuthKeyResponse)(nil), // 44: ionscale.v1.DeleteAuthKeyResponse
(*ListAuthKeysResponse)(nil), // 45: ionscale.v1.ListAuthKeysResponse
(*ListUsersResponse)(nil), // 46: ionscale.v1.ListUsersResponse
(*DeleteUserResponse)(nil), // 47: ionscale.v1.DeleteUserResponse
(*GetMachineResponse)(nil), // 48: ionscale.v1.GetMachineResponse
(*ListMachinesResponse)(nil), // 49: ionscale.v1.ListMachinesResponse
(*ExpireMachineResponse)(nil), // 50: ionscale.v1.ExpireMachineResponse
(*DeleteMachineResponse)(nil), // 51: ionscale.v1.DeleteMachineResponse
(*SetMachineKeyExpiryResponse)(nil), // 52: ionscale.v1.SetMachineKeyExpiryResponse
(*GetMachineRoutesResponse)(nil), // 53: ionscale.v1.GetMachineRoutesResponse
(*EnableExitNodeRequest)(nil), // 28: ionscale.v1.EnableExitNodeRequest
(*DisableExitNodeRequest)(nil), // 29: ionscale.v1.DisableExitNodeRequest
(*GetVersionResponse)(nil), // 30: ionscale.v1.GetVersionResponse
(*AuthenticationResponse)(nil), // 31: ionscale.v1.AuthenticationResponse
(*GetDERPMapResponse)(nil), // 32: ionscale.v1.GetDERPMapResponse
(*SetDERPMapResponse)(nil), // 33: ionscale.v1.SetDERPMapResponse
(*CreateTailnetResponse)(nil), // 34: ionscale.v1.CreateTailnetResponse
(*GetTailnetResponse)(nil), // 35: ionscale.v1.GetTailnetResponse
(*ListTailnetResponse)(nil), // 36: ionscale.v1.ListTailnetResponse
(*DeleteTailnetResponse)(nil), // 37: ionscale.v1.DeleteTailnetResponse
(*GetDNSConfigResponse)(nil), // 38: ionscale.v1.GetDNSConfigResponse
(*SetDNSConfigResponse)(nil), // 39: ionscale.v1.SetDNSConfigResponse
(*GetIAMPolicyResponse)(nil), // 40: ionscale.v1.GetIAMPolicyResponse
(*SetIAMPolicyResponse)(nil), // 41: ionscale.v1.SetIAMPolicyResponse
(*GetACLPolicyResponse)(nil), // 42: ionscale.v1.GetACLPolicyResponse
(*SetACLPolicyResponse)(nil), // 43: ionscale.v1.SetACLPolicyResponse
(*GetAuthKeyResponse)(nil), // 44: ionscale.v1.GetAuthKeyResponse
(*CreateAuthKeyResponse)(nil), // 45: ionscale.v1.CreateAuthKeyResponse
(*DeleteAuthKeyResponse)(nil), // 46: ionscale.v1.DeleteAuthKeyResponse
(*ListAuthKeysResponse)(nil), // 47: ionscale.v1.ListAuthKeysResponse
(*ListUsersResponse)(nil), // 48: ionscale.v1.ListUsersResponse
(*DeleteUserResponse)(nil), // 49: ionscale.v1.DeleteUserResponse
(*GetMachineResponse)(nil), // 50: ionscale.v1.GetMachineResponse
(*ListMachinesResponse)(nil), // 51: ionscale.v1.ListMachinesResponse
(*ExpireMachineResponse)(nil), // 52: ionscale.v1.ExpireMachineResponse
(*DeleteMachineResponse)(nil), // 53: ionscale.v1.DeleteMachineResponse
(*SetMachineKeyExpiryResponse)(nil), // 54: ionscale.v1.SetMachineKeyExpiryResponse
(*GetMachineRoutesResponse)(nil), // 55: ionscale.v1.GetMachineRoutesResponse
}
var file_ionscale_v1_ionscale_proto_depIdxs = []int32{
0, // 0: ionscale.v1.IonscaleService.GetVersion:input_type -> ionscale.v1.GetVersionRequest
@@ -296,36 +310,40 @@ var file_ionscale_v1_ionscale_proto_depIdxs = []int32{
25, // 25: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest
26, // 26: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest
27, // 27: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest
28, // 28: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse
29, // 29: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticationResponse
30, // 30: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse
31, // 31: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse
32, // 32: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse
33, // 33: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse
34, // 34: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetResponse
35, // 35: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse
36, // 36: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse
37, // 37: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse
38, // 38: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse
39, // 39: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse
40, // 40: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse
41, // 41: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse
42, // 42: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse
43, // 43: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse
44, // 44: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse
45, // 45: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse
46, // 46: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse
47, // 47: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse
48, // 48: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse
49, // 49: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse
50, // 50: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse
51, // 51: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse
52, // 52: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse
53, // 53: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
53, // 54: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
53, // 55: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
28, // [28:56] is the sub-list for method output_type
0, // [0:28] is the sub-list for method input_type
28, // 28: ionscale.v1.IonscaleService.EnableExitNode:input_type -> ionscale.v1.EnableExitNodeRequest
29, // 29: ionscale.v1.IonscaleService.DisableExitNode:input_type -> ionscale.v1.DisableExitNodeRequest
30, // 30: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse
31, // 31: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticationResponse
32, // 32: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse
33, // 33: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse
34, // 34: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse
35, // 35: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse
36, // 36: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetResponse
37, // 37: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse
38, // 38: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse
39, // 39: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse
40, // 40: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse
41, // 41: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse
42, // 42: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse
43, // 43: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse
44, // 44: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse
45, // 45: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse
46, // 46: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse
47, // 47: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse
48, // 48: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse
49, // 49: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse
50, // 50: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse
51, // 51: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse
52, // 52: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse
53, // 53: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse
54, // 54: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse
55, // 55: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
55, // 56: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
55, // 57: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse
55, // 58: ionscale.v1.IonscaleService.EnableExitNode:output_type -> ionscale.v1.GetMachineRoutesResponse
55, // 59: ionscale.v1.IonscaleService.DisableExitNode:output_type -> ionscale.v1.GetMachineRoutesResponse
30, // [30:60] is the sub-list for method output_type
0, // [0:30] 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
@@ -55,6 +55,8 @@ type IonscaleServiceClient interface {
GetMachineRoutes(context.Context, *connect_go.Request[v1.GetMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableMachineRoutes(context.Context, *connect_go.Request[v1.EnableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
DisableMachineRoutes(context.Context, *connect_go.Request[v1.DisableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableExitNode(context.Context, *connect_go.Request[v1.EnableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
DisableExitNode(context.Context, *connect_go.Request[v1.DisableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
}
// NewIonscaleServiceClient constructs a client for the ionscale.v1.IonscaleService service. By
@@ -207,6 +209,16 @@ func NewIonscaleServiceClient(httpClient connect_go.HTTPClient, baseURL string,
baseURL+"/ionscale.v1.IonscaleService/DisableMachineRoutes",
opts...,
),
enableExitNode: connect_go.NewClient[v1.EnableExitNodeRequest, v1.GetMachineRoutesResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/EnableExitNode",
opts...,
),
disableExitNode: connect_go.NewClient[v1.DisableExitNodeRequest, v1.GetMachineRoutesResponse](
httpClient,
baseURL+"/ionscale.v1.IonscaleService/DisableExitNode",
opts...,
),
}
}
@@ -240,6 +252,8 @@ type ionscaleServiceClient struct {
getMachineRoutes *connect_go.Client[v1.GetMachineRoutesRequest, v1.GetMachineRoutesResponse]
enableMachineRoutes *connect_go.Client[v1.EnableMachineRoutesRequest, v1.GetMachineRoutesResponse]
disableMachineRoutes *connect_go.Client[v1.DisableMachineRoutesRequest, v1.GetMachineRoutesResponse]
enableExitNode *connect_go.Client[v1.EnableExitNodeRequest, v1.GetMachineRoutesResponse]
disableExitNode *connect_go.Client[v1.DisableExitNodeRequest, v1.GetMachineRoutesResponse]
}
// GetVersion calls ionscale.v1.IonscaleService.GetVersion.
@@ -382,6 +396,16 @@ func (c *ionscaleServiceClient) DisableMachineRoutes(ctx context.Context, req *c
return c.disableMachineRoutes.CallUnary(ctx, req)
}
// EnableExitNode calls ionscale.v1.IonscaleService.EnableExitNode.
func (c *ionscaleServiceClient) EnableExitNode(ctx context.Context, req *connect_go.Request[v1.EnableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return c.enableExitNode.CallUnary(ctx, req)
}
// DisableExitNode calls ionscale.v1.IonscaleService.DisableExitNode.
func (c *ionscaleServiceClient) DisableExitNode(ctx context.Context, req *connect_go.Request[v1.DisableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return c.disableExitNode.CallUnary(ctx, req)
}
// IonscaleServiceHandler is an implementation of the ionscale.v1.IonscaleService service.
type IonscaleServiceHandler interface {
GetVersion(context.Context, *connect_go.Request[v1.GetVersionRequest]) (*connect_go.Response[v1.GetVersionResponse], error)
@@ -412,6 +436,8 @@ type IonscaleServiceHandler interface {
GetMachineRoutes(context.Context, *connect_go.Request[v1.GetMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableMachineRoutes(context.Context, *connect_go.Request[v1.EnableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
DisableMachineRoutes(context.Context, *connect_go.Request[v1.DisableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
EnableExitNode(context.Context, *connect_go.Request[v1.EnableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
DisableExitNode(context.Context, *connect_go.Request[v1.DisableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error)
}
// NewIonscaleServiceHandler builds an HTTP handler from the service implementation. It returns the
@@ -561,6 +587,16 @@ func NewIonscaleServiceHandler(svc IonscaleServiceHandler, opts ...connect_go.Ha
svc.DisableMachineRoutes,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/EnableExitNode", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/EnableExitNode",
svc.EnableExitNode,
opts...,
))
mux.Handle("/ionscale.v1.IonscaleService/DisableExitNode", connect_go.NewUnaryHandler(
"/ionscale.v1.IonscaleService/DisableExitNode",
svc.DisableExitNode,
opts...,
))
return "/ionscale.v1.IonscaleService/", mux
}
@@ -678,3 +714,11 @@ func (UnimplementedIonscaleServiceHandler) EnableMachineRoutes(context.Context,
func (UnimplementedIonscaleServiceHandler) DisableMachineRoutes(context.Context, *connect_go.Request[v1.DisableMachineRoutesRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableMachineRoutes is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) EnableExitNode(context.Context, *connect_go.Request[v1.EnableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.EnableExitNode is not implemented"))
}
func (UnimplementedIonscaleServiceHandler) DisableExitNode(context.Context, *connect_go.Request[v1.DisableExitNodeRequest]) (*connect_go.Response[v1.GetMachineRoutesResponse], error) {
return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableExitNode is not implemented"))
}
+32 -10
View File
@@ -496,6 +496,8 @@ type Machine struct {
KeyExpiryDisabled bool `protobuf:"varint,16,opt,name=key_expiry_disabled,json=keyExpiryDisabled,proto3" json:"key_expiry_disabled,omitempty"`
EnabledRoutes []string `protobuf:"bytes,17,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"`
AdvertisedRoutes []string `protobuf:"bytes,18,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"`
AdvertisedExitNode bool `protobuf:"varint,19,opt,name=advertised_exit_node,json=advertisedExitNode,proto3" json:"advertised_exit_node,omitempty"`
EnabledExitNode bool `protobuf:"varint,20,opt,name=enabled_exit_node,json=enabledExitNode,proto3" json:"enabled_exit_node,omitempty"`
}
func (x *Machine) Reset() {
@@ -656,6 +658,20 @@ func (x *Machine) GetAdvertisedRoutes() []string {
return nil
}
func (x *Machine) GetAdvertisedExitNode() bool {
if x != nil {
return x.AdvertisedExitNode
}
return false
}
func (x *Machine) GetEnabledExitNode() bool {
if x != nil {
return x.EnabledExitNode
}
return false
}
type ClientConnectivity struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -747,7 +763,7 @@ var file_ionscale_v1_machines_proto_rawDesc = []byte{
0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x07, 0x6d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x22, 0xb3, 0x05, 0x0a, 0x07, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12,
0x69, 0x6e, 0x65, 0x22, 0x91, 0x06, 0x0a, 0x07, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28,
@@ -790,15 +806,21 @@ var file_ionscale_v1_machines_proto_rawDesc = []byte{
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11,
0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69,
0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x32, 0x0a, 0x12, 0x43, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12,
0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x09, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x42, 0x3d, 0x5a,
0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65,
0x62, 0x65, 0x6e, 0x73, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b,
0x67, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76,
0x31, 0x3b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x64, 0x76,
0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x6e, 0x6f, 0x64,
0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69,
0x73, 0x65, 0x64, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x65,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65,
0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x45,
0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x22, 0x32, 0x0a, 0x12, 0x43, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09,
0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x42, 0x3d, 0x5a, 0x3b, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65,
0x6e, 0x73, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
0x67, 0x65, 0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
+173 -24
View File
@@ -72,8 +72,10 @@ type GetMachineRoutesResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
AdvertisedRoutes []string `protobuf:"bytes,1,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"`
EnabledRoutes []string `protobuf:"bytes,2,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"`
AdvertisedRoutes []string `protobuf:"bytes,1,rep,name=advertised_routes,json=advertisedRoutes,proto3" json:"advertised_routes,omitempty"`
EnabledRoutes []string `protobuf:"bytes,2,rep,name=enabled_routes,json=enabledRoutes,proto3" json:"enabled_routes,omitempty"`
AdvertisedExitNode bool `protobuf:"varint,3,opt,name=advertised_exit_node,json=advertisedExitNode,proto3" json:"advertised_exit_node,omitempty"`
EnabledExitNode bool `protobuf:"varint,4,opt,name=enabled_exit_node,json=enabledExitNode,proto3" json:"enabled_exit_node,omitempty"`
}
func (x *GetMachineRoutesResponse) Reset() {
@@ -122,6 +124,20 @@ func (x *GetMachineRoutesResponse) GetEnabledRoutes() []string {
return nil
}
func (x *GetMachineRoutesResponse) GetAdvertisedExitNode() bool {
if x != nil {
return x.AdvertisedExitNode
}
return false
}
func (x *GetMachineRoutesResponse) GetEnabledExitNode() bool {
if x != nil {
return x.EnabledExitNode
}
return false
}
type EnableMachineRoutesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -240,6 +256,100 @@ func (x *DisableMachineRoutesRequest) GetRoutes() []string {
return nil
}
type EnableExitNodeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
}
func (x *EnableExitNodeRequest) Reset() {
*x = EnableExitNodeRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_routes_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EnableExitNodeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EnableExitNodeRequest) ProtoMessage() {}
func (x *EnableExitNodeRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_routes_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EnableExitNodeRequest.ProtoReflect.Descriptor instead.
func (*EnableExitNodeRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_routes_proto_rawDescGZIP(), []int{4}
}
func (x *EnableExitNodeRequest) GetMachineId() uint64 {
if x != nil {
return x.MachineId
}
return 0
}
type DisableExitNodeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MachineId uint64 `protobuf:"varint,1,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"`
}
func (x *DisableExitNodeRequest) Reset() {
*x = DisableExitNodeRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ionscale_v1_routes_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *DisableExitNodeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DisableExitNodeRequest) ProtoMessage() {}
func (x *DisableExitNodeRequest) ProtoReflect() protoreflect.Message {
mi := &file_ionscale_v1_routes_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DisableExitNodeRequest.ProtoReflect.Descriptor instead.
func (*DisableExitNodeRequest) Descriptor() ([]byte, []int) {
return file_ionscale_v1_routes_proto_rawDescGZIP(), []int{5}
}
func (x *DisableExitNodeRequest) GetMachineId() uint64 {
if x != nil {
return x.MachineId
}
return 0
}
var File_ionscale_v1_routes_proto protoreflect.FileDescriptor
var file_ionscale_v1_routes_proto_rawDesc = []byte{
@@ -249,26 +359,39 @@ var file_ionscale_v1_routes_proto_rawDesc = []byte{
0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49,
0x64, 0x22, 0x6e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a,
0x11, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74,
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74,
0x69, 0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e,
0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65,
0x73, 0x22, 0x6d, 0x0a, 0x1a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69,
0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16,
0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63,
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
0x22, 0x54, 0x0a, 0x1b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69,
0x6e, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16,
0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x64, 0x22, 0xcc, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65,
0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b,
0x0a, 0x11, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75,
0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x64, 0x76, 0x65, 0x72,
0x74, 0x69, 0x73, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74,
0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64,
0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x12, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x64, 0x45, 0x78, 0x69, 0x74,
0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f,
0x65, 0x78, 0x69, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65,
0x22, 0x6d, 0x0a, 0x1a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a,
0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x22,
0x54, 0x0a, 0x1b, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e,
0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a,
0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0x36, 0x0a, 0x15, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45,
0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, 0x37, 0x0a,
0x16, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x69, 0x74, 0x4e, 0x6f, 0x64, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69,
0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x61, 0x63,
0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65, 0x6e, 0x73, 0x2f, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6f, 0x6e, 0x73, 0x63,
@@ -287,12 +410,14 @@ func file_ionscale_v1_routes_proto_rawDescGZIP() []byte {
return file_ionscale_v1_routes_proto_rawDescData
}
var file_ionscale_v1_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_ionscale_v1_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_ionscale_v1_routes_proto_goTypes = []interface{}{
(*GetMachineRoutesRequest)(nil), // 0: ionscale.v1.GetMachineRoutesRequest
(*GetMachineRoutesResponse)(nil), // 1: ionscale.v1.GetMachineRoutesResponse
(*EnableMachineRoutesRequest)(nil), // 2: ionscale.v1.EnableMachineRoutesRequest
(*DisableMachineRoutesRequest)(nil), // 3: ionscale.v1.DisableMachineRoutesRequest
(*EnableExitNodeRequest)(nil), // 4: ionscale.v1.EnableExitNodeRequest
(*DisableExitNodeRequest)(nil), // 5: ionscale.v1.DisableExitNodeRequest
}
var file_ionscale_v1_routes_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
@@ -356,6 +481,30 @@ func file_ionscale_v1_routes_proto_init() {
return nil
}
}
file_ionscale_v1_routes_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EnableExitNodeRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ionscale_v1_routes_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DisableExitNodeRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -363,7 +512,7 @@ func file_ionscale_v1_routes_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ionscale_v1_routes_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},
+59 -44
View File
@@ -80,7 +80,8 @@ type CreateTailnetRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
IamPolicy *IAMPolicy `protobuf:"bytes,2,opt,name=iam_policy,json=iamPolicy,proto3" json:"iam_policy,omitempty"`
}
func (x *CreateTailnetRequest) Reset() {
@@ -122,6 +123,13 @@ func (x *CreateTailnetRequest) GetName() string {
return ""
}
func (x *CreateTailnetRequest) GetIamPolicy() *IAMPolicy {
if x != nil {
return x.IamPolicy
}
return nil
}
type CreateTailnetResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -446,41 +454,45 @@ var File_ionscale_v1_tailnets_proto protoreflect.FileDescriptor
var file_ionscale_v1_tailnets_proto_rawDesc = []byte{
0x0a, 0x1a, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61,
0x69, 0x6c, 0x6e, 0x65, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x2d, 0x0a, 0x07, 0x54, 0x61, 0x69,
0x6c, 0x6e, 0x65, 0x74, 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, 0x22, 0x2a, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x22, 0x47, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61,
0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a,
0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69,
0x6c, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x23, 0x0a,
0x11, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02,
0x69, 0x64, 0x22, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52,
0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74,
0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x45,
0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61,
0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x4b, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
0x0a, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x04, 0x52, 0x09, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05,
0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72,
0x63, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65,
0x6e, 0x73, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
0x67, 0x65, 0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x61, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x22, 0x2d, 0x0a, 0x07, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 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, 0x22,
0x61, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0a, 0x69,
0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x16, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x41,
0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x09, 0x69, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69,
0x63, 0x79, 0x22, 0x47, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e,
0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x23, 0x0a, 0x11, 0x47,
0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64,
0x22, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x74,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61,
0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x45, 0x0a, 0x13,
0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x22, 0x4b, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69,
0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
0x09, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f,
0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65,
0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65, 0x6e, 0x73,
0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65,
0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -506,16 +518,18 @@ var file_ionscale_v1_tailnets_proto_goTypes = []interface{}{
(*ListTailnetResponse)(nil), // 6: ionscale.v1.ListTailnetResponse
(*DeleteTailnetRequest)(nil), // 7: ionscale.v1.DeleteTailnetRequest
(*DeleteTailnetResponse)(nil), // 8: ionscale.v1.DeleteTailnetResponse
(*IAMPolicy)(nil), // 9: ionscale.v1.IAMPolicy
}
var file_ionscale_v1_tailnets_proto_depIdxs = []int32{
0, // 0: ionscale.v1.CreateTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
0, // 1: ionscale.v1.GetTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
0, // 2: ionscale.v1.ListTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
9, // 0: ionscale.v1.CreateTailnetRequest.iam_policy:type_name -> ionscale.v1.IAMPolicy
0, // 1: ionscale.v1.CreateTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
0, // 2: ionscale.v1.GetTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
0, // 3: ionscale.v1.ListTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_ionscale_v1_tailnets_proto_init() }
@@ -523,6 +537,7 @@ func file_ionscale_v1_tailnets_proto_init() {
if File_ionscale_v1_tailnets_proto != nil {
return
}
file_ionscale_v1_iam_proto_init()
if !protoimpl.UnsafeEnabled {
file_ionscale_v1_tailnets_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Tailnet); i {
+6
View File
@@ -28,10 +28,16 @@ message ACLPolicy {
map<string, google.protobuf.ListValue> groups = 2;
repeated ACL acls = 3;
map<string, google.protobuf.ListValue> tagowners = 4;
AutoApprovers autoapprovers = 5;
}
message ACL {
string action = 1;
repeated string src = 2;
repeated string dst = 3;
}
message AutoApprovers {
map<string, google.protobuf.ListValue> routes = 1;
repeated string exitnode = 2;
}
+2
View File
@@ -56,4 +56,6 @@ service IonscaleService {
rpc GetMachineRoutes (GetMachineRoutesRequest) returns (GetMachineRoutesResponse) {}
rpc EnableMachineRoutes (EnableMachineRoutesRequest) returns (GetMachineRoutesResponse) {}
rpc DisableMachineRoutes (DisableMachineRoutesRequest) returns (GetMachineRoutesResponse) {}
rpc EnableExitNode (EnableExitNodeRequest) returns (GetMachineRoutesResponse) {}
rpc DisableExitNode (DisableExitNodeRequest) returns (GetMachineRoutesResponse) {}
}
+2
View File
@@ -62,6 +62,8 @@ message Machine {
bool key_expiry_disabled = 16;
repeated string enabled_routes = 17;
repeated string advertised_routes = 18;
bool advertised_exit_node = 19;
bool enabled_exit_node = 20;
}
message ClientConnectivity {
+10
View File
@@ -10,6 +10,8 @@ message GetMachineRoutesRequest {
message GetMachineRoutesResponse {
repeated string advertised_routes = 1;
repeated string enabled_routes = 2;
bool advertised_exit_node = 3;
bool enabled_exit_node = 4;
}
message EnableMachineRoutesRequest {
@@ -22,3 +24,11 @@ message DisableMachineRoutesRequest {
uint64 machine_id = 1;
repeated string routes = 2;
}
message EnableExitNodeRequest {
uint64 machine_id = 1;
}
message DisableExitNodeRequest {
uint64 machine_id = 1;
}
+3
View File
@@ -3,6 +3,8 @@ syntax = "proto3";
package ionscale.v1;
option go_package = "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1;ionscalev1";
import "ionscale/v1/iam.proto";
message Tailnet {
uint64 id = 1;
string name = 2;
@@ -10,6 +12,7 @@ message Tailnet {
message CreateTailnetRequest {
string name = 1;
IAMPolicy iam_policy = 2;
}
message CreateTailnetResponse {