From ddc65d2df9fa12ca3a06fc632e4a883b2dd83230 Mon Sep 17 00:00:00 2001 From: Johan Siebens Date: Thu, 6 Oct 2022 20:49:05 +0200 Subject: [PATCH] feat: add support for ssh acl policies --- internal/cmd/tailnet.go | 84 ++++ .../m202210080700_ssh_action_request.go | 34 ++ internal/database/migration/migrations.go | 1 + internal/domain/acl.go | 40 +- internal/domain/acl_ssh_policy.go | 150 ++++++++ internal/domain/acl_ssh_policy_test.go | 364 ++++++++++++++++++ internal/domain/acl_test.go | 10 - internal/domain/repository.go | 4 + internal/domain/ssh_action_request.go | 46 +++ internal/domain/tailnet.go | 1 + internal/handlers/authentication.go | 57 ++- internal/handlers/poll_net_map.go | 11 +- internal/handlers/ssh_action.go | 113 ++++++ internal/mapping/mapping.go | 4 + internal/server/server.go | 5 +- internal/service/tailnet.go | 52 +++ internal/templates/notmachineowner.html | 63 +++ pkg/gen/ionscale/v1/acl.pb.go | 206 +++++++--- pkg/gen/ionscale/v1/ionscale.pb.go | 272 +++++++------ .../v1/ionscalev1connect/ionscale.connect.go | 44 +++ pkg/gen/ionscale/v1/tailnets.pb.go | 250 +++++++++++- proto/ionscale/v1/acl.proto | 8 + proto/ionscale/v1/ionscale.proto | 2 + proto/ionscale/v1/tailnets.proto | 15 + 24 files changed, 1627 insertions(+), 209 deletions(-) create mode 100644 internal/database/migration/m202210080700_ssh_action_request.go create mode 100644 internal/domain/acl_ssh_policy.go create mode 100644 internal/domain/acl_ssh_policy_test.go create mode 100644 internal/domain/ssh_action_request.go create mode 100644 internal/handlers/ssh_action.go create mode 100644 internal/templates/notmachineowner.html diff --git a/internal/cmd/tailnet.go b/internal/cmd/tailnet.go index d9830e1..9b6221a 100644 --- a/internal/cmd/tailnet.go +++ b/internal/cmd/tailnet.go @@ -37,6 +37,8 @@ func tailnetCommand() *coral.Command { command.AddCommand(disableServiceCollectionCommand()) command.AddCommand(enableFileSharingCommand()) command.AddCommand(disableFileSharingCommand()) + command.AddCommand(enableSSHCommand()) + command.AddCommand(disableSSHCommand()) command.AddCommand(getDERPMap()) command.AddCommand(setDERPMap()) command.AddCommand(resetDERPMap()) @@ -524,3 +526,85 @@ func disableServiceCollectionCommand() *coral.Command { return command } + +func enableSSHCommand() *coral.Command { + command := &coral.Command{ + Use: "enable-ssh", + Short: "Enable ssh access using tailnet and ACLs.", + SilenceUsage: true, + } + + var tailnetID uint64 + var tailnetName string + var target = Target{} + + target.prepareCommand(command) + command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.") + command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.") + + command.PreRunE = checkRequiredTailnetAndTailnetIdFlags + command.RunE = func(command *coral.Command, args []string) error { + client, err := target.createGRPCClient() + if err != nil { + return err + } + + tailnet, err := findTailnet(client, tailnetName, tailnetID) + if err != nil { + return err + } + + req := api.EnableSSHRequest{ + TailnetId: tailnet.Id, + } + + if _, err := client.EnabledSSH(context.Background(), connect.NewRequest(&req)); err != nil { + return err + } + + return nil + } + + return command +} + +func disableSSHCommand() *coral.Command { + command := &coral.Command{ + Use: "disable-ssh", + Short: "Disable ssh access using tailnet and ACLs.", + SilenceUsage: true, + } + + var tailnetID uint64 + var tailnetName string + var target = Target{} + + target.prepareCommand(command) + command.Flags().StringVar(&tailnetName, "tailnet", "", "Tailnet name. Mutually exclusive with --tailnet-id.") + command.Flags().Uint64Var(&tailnetID, "tailnet-id", 0, "Tailnet ID. Mutually exclusive with --tailnet.") + + command.PreRunE = checkRequiredTailnetAndTailnetIdFlags + command.RunE = func(command *coral.Command, args []string) error { + client, err := target.createGRPCClient() + if err != nil { + return err + } + + tailnet, err := findTailnet(client, tailnetName, tailnetID) + if err != nil { + return err + } + + req := api.DisableSSHRequest{ + TailnetId: tailnet.Id, + } + + if _, err := client.DisableSSH(context.Background(), connect.NewRequest(&req)); err != nil { + return err + } + + return nil + } + + return command +} diff --git a/internal/database/migration/m202210080700_ssh_action_request.go b/internal/database/migration/m202210080700_ssh_action_request.go new file mode 100644 index 0000000..d9e8a04 --- /dev/null +++ b/internal/database/migration/m202210080700_ssh_action_request.go @@ -0,0 +1,34 @@ +package migration + +import ( + "github.com/go-gormigrate/gormigrate/v2" + "gorm.io/gorm" + "time" +) + +func m202210080700_ssh_action_request() *gormigrate.Migration { + return &gormigrate.Migration{ + ID: "202210080700", + Migrate: func(db *gorm.DB) error { + type Tailnet struct { + Name string `gorm:"uniqueIndex"` + Alias *string `gorm:"uniqueIndex"` + SSHEnabled bool + } + + type SSHActionRequest struct { + Key string `gorm:"primary_key"` + Action string + SrcMachineID uint64 + DstMachineID uint64 + CreatedAt time.Time + } + + return db.AutoMigrate( + &Tailnet{}, + &SSHActionRequest{}, + ) + }, + Rollback: nil, + } +} diff --git a/internal/database/migration/migrations.go b/internal/database/migration/migrations.go index 66d9342..b1d2a12 100644 --- a/internal/database/migration/migrations.go +++ b/internal/database/migration/migrations.go @@ -12,6 +12,7 @@ func Migrations() []*gormigrate.Migration { m202229251530_add_alias_column_constraint(), m202210040828_add_derpmap_colum(), m202210070814_add_filesharing_and_servicecollection_columns(), + m202210080700_ssh_action_request(), } return migrations } diff --git a/internal/domain/acl.go b/internal/domain/acl.go index 162f16d..6916f4f 100644 --- a/internal/domain/acl.go +++ b/internal/domain/acl.go @@ -31,6 +31,7 @@ type ACLPolicy struct { ACLs []ACL `json:"acls"` TagOwners map[string][]string `json:"tagowners"` AutoApprovers AutoApprovers `json:"autoApprovers"` + SSHRules []SSHRule `json:"ssh"` } type ACL struct { @@ -39,6 +40,13 @@ type ACL struct { Dst []string `json:"dst"` } +type SSHRule struct { + Action string `json:"action"` + Src []string `json:"src"` + Dst []string `json:"dst"` + Users []string `json:"users"` +} + func DefaultPolicy() ACLPolicy { return ACLPolicy{ ACLs: []ACL{ @@ -116,17 +124,26 @@ func (a ACLPolicy) FindAutoApprovedIPs(routableIPs []netip.Prefix, tags []string return result } +func (a ACLPolicy) IsTagOwner(tags []string, p *User) bool { + for _, t := range tags { + if a.isTagOwner(t, p) { + return true + } + } + return false +} + func (a ACLPolicy) CheckTagOwners(tags []string, p *User) error { var result *multierror.Error for _, t := range tags { - if ok := a.IsTagOwner(t, p); !ok { + if ok := a.isTagOwner(t, p); !ok { result = multierror.Append(result, fmt.Errorf("tag [%s] is invalid or not permitted", t)) } } return result.ErrorOrNil() } -func (a ACLPolicy) IsTagOwner(tag string, p *User) bool { +func (a ACLPolicy) isTagOwner(tag string, p *User) bool { if p.UserType == UserTypeService { return true } @@ -387,6 +404,25 @@ func (a ACLPolicy) expandValuePortToPortRange(s string) ([]tailcfg.PortRange, er return ports, nil } +func (a ACLPolicy) isGroupMember(group string, m *Machine) bool { + if m.HasTags() { + return false + } + + users, ok := a.Groups[group] + if !ok { + return false + } + + for _, u := range users { + if m.HasUser(u) { + return true + } + } + + return false +} + func (i *ACLPolicy) Scan(destination interface{}) error { switch value := destination.(type) { case []byte: diff --git a/internal/domain/acl_ssh_policy.go b/internal/domain/acl_ssh_policy.go new file mode 100644 index 0000000..8bf2854 --- /dev/null +++ b/internal/domain/acl_ssh_policy.go @@ -0,0 +1,150 @@ +package domain + +import ( + "strings" + "tailscale.com/tailcfg" +) + +func (a ACLPolicy) BuildSSHPolicy(srcs []Machine, dst *Machine) *tailcfg.SSHPolicy { + var rules []*tailcfg.SSHRule + + expandSrcAliases := func(aliases []string, u *User) []*tailcfg.SSHPrincipal { + var allSrcIPsSet = &StringSet{} + for _, alias := range aliases { + for _, src := range srcs { + srcIPs := a.expandSSHSrcAlias(&src, alias, u) + allSrcIPsSet.Add(srcIPs...) + } + } + + var result = []*tailcfg.SSHPrincipal{} + for _, i := range allSrcIPsSet.Items() { + result = append(result, &tailcfg.SSHPrincipal{NodeIP: i}) + } + + return result + } + + for _, rule := range a.SSHRules { + if rule.Action != "accept" && rule.Action != "check" { + continue + } + + var action = &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + } + + if rule.Action == "check" { + action = &tailcfg.SSHAction{ + HoldAndDelegate: "https://unused/machine/ssh/action/$SRC_NODE_ID/to/$DST_NODE_ID", + } + } + + selfUsers, otherUsers := a.expandSSHDstToSSHUsers(dst, rule) + + if len(selfUsers) != 0 { + principals := expandSrcAliases(rule.Src, &dst.User) + if len(principals) != 0 { + rules = append(rules, &tailcfg.SSHRule{ + Principals: principals, + SSHUsers: selfUsers, + Action: action, + }) + } + } + + if len(otherUsers) != 0 { + principals := expandSrcAliases(rule.Src, nil) + if len(principals) != 0 { + rules = append(rules, &tailcfg.SSHRule{ + Principals: principals, + SSHUsers: otherUsers, + Action: action, + }) + } + } + } + + return &tailcfg.SSHPolicy{Rules: rules} +} + +func (a ACLPolicy) expandSSHSrcAlias(m *Machine, alias string, dstUser *User) []string { + if dstUser != nil { + if !m.HasUser(dstUser.Name) || m.HasTags() { + return []string{} + } + + if alias == AutoGroupMembers { + return m.IPs() + } + + if strings.Contains(alias, "@") && m.HasUser(alias) { + return m.IPs() + } + + if strings.HasPrefix(alias, "group:") && a.isGroupMember(alias, m) { + return m.IPs() + } + + return []string{} + } + + if alias == AutoGroupMembers && !m.HasTags() { + return m.IPs() + } + + if strings.Contains(alias, "@") && !m.HasTags() && m.HasUser(alias) { + return m.IPs() + } + + if strings.HasPrefix(alias, "group:") && !m.HasTags() && a.isGroupMember(alias, m) { + return m.IPs() + } + + if strings.HasPrefix(alias, "tag:") && m.HasTag(alias) { + return m.IPs() + } + + return []string{} +} + +func (a ACLPolicy) expandSSHDstToSSHUsers(m *Machine, rule SSHRule) (map[string]string, map[string]string) { + users := buildSSHUsers(rule.Users) + + var selfUsers map[string]string + var otherUsers map[string]string + + for _, d := range rule.Dst { + if strings.HasPrefix(d, "tag:") && m.HasTag(d) { + otherUsers = users + } + + if m.HasUser(d) || d == AutoGroupSelf { + selfUsers = users + } + } + + return selfUsers, otherUsers +} + +func buildSSHUsers(users []string) map[string]string { + var autogroupNonRoot = false + m := make(map[string]string) + for _, u := range users { + if u == "autogroup:nonroot" { + m["*"] = "=" + autogroupNonRoot = true + } else { + m[u] = u + } + } + + // disable root when autogroup:nonroot is used and root is not explicitly enabled + if _, exists := m["root"]; !exists && autogroupNonRoot { + m["root"] = "" + } + + return m +} diff --git a/internal/domain/acl_ssh_policy_test.go b/internal/domain/acl_ssh_policy_test.go new file mode 100644 index 0000000..43bb163 --- /dev/null +++ b/internal/domain/acl_ssh_policy_test.go @@ -0,0 +1,364 @@ +package domain + +import ( + "encoding/json" + "fmt" + "github.com/stretchr/testify/assert" + "tailscale.com/tailcfg" + "testing" +) + +func TestACLPolicy_BuildSSHPolicy_(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("jane@example.com") + + policy := ACLPolicy{ + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"autogroup:members"}, + Dst: []string{"autogroup:self"}, + Users: []string{"autogroup:nonroot"}, + }, + }, + } + + dst := createMachine("john@example.com") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst) + expectedRules := []*tailcfg.SSHRule{ + { + Principals: []*tailcfg.SSHPrincipal{ + {NodeIP: p1.IPv4.String()}, + {NodeIP: p1.IPv6.String()}, + }, + SSHUsers: map[string]string{ + "*": "=", + "root": "", + }, + Action: &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + }, + }, + } + + assert.Equal(t, expectedRules, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithGroup(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("jane@example.com") + + policy := ACLPolicy{ + Groups: map[string][]string{ + "group:sre": { + "john@example.com", + }, + }, + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"group:sre"}, + Dst: []string{"tag:web"}, + Users: []string{"autogroup:nonroot", "root"}, + }, + }, + } + + dst := createMachine("john@example.com", "tag:web") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst) + expectedRules := []*tailcfg.SSHRule{ + { + Principals: []*tailcfg.SSHPrincipal{ + {NodeIP: p1.IPv4.String()}, + {NodeIP: p1.IPv6.String()}, + }, + SSHUsers: map[string]string{ + "*": "=", + "root": "root", + }, + Action: &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + }, + }, + } + + assert.Equal(t, expectedRules, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithMatchingUsers(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("jane@example.com") + + policy := ACLPolicy{ + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"john@example.com"}, + Dst: []string{"john@example.com"}, + Users: []string{"autogroup:nonroot", "root"}, + }, + }, + } + + dst := createMachine("john@example.com") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst) + expectedRules := []*tailcfg.SSHRule{ + { + Principals: sshPrincipalsFromMachines(*p1), + SSHUsers: map[string]string{ + "*": "=", + "root": "root", + }, + Action: &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + }, + }, + } + + assert.Equal(t, expectedRules, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithMatchingUsersInGroup(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("jane@example.com") + + policy := ACLPolicy{ + Groups: map[string][]string{ + "group:sre": {"jane@example.com", "john@example.com"}, + }, + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"group:sre"}, + Dst: []string{"john@example.com"}, + Users: []string{"autogroup:nonroot", "root"}, + }, + }, + } + + dst := createMachine("john@example.com") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst) + expectedRules := []*tailcfg.SSHRule{ + { + Principals: sshPrincipalsFromMachines(*p1), + SSHUsers: map[string]string{ + "*": "=", + "root": "root", + }, + Action: &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + }, + }, + } + + assert.Equal(t, expectedRules, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithNoMatchingUsers(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("jane@example.com") + + policy := ACLPolicy{ + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"jane@example.com"}, + Dst: []string{"john@example.com"}, + Users: []string{"autogroup:nonroot", "root"}, + }, + }, + } + + dst := createMachine("john@example.com") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst) + + assert.Nil(t, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithTags(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("nick@example.com") + p3 := createMachine("nick@example.com", "tag:web") + + policy := ACLPolicy{ + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"john@example.com", "tag:web"}, + Dst: []string{"tag:web"}, + Users: []string{"ubuntu"}, + }, + }, + } + + dst := createMachine("john@example.com", "tag:web") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2, *p3}, dst) + expectedRules := []*tailcfg.SSHRule{ + { + Principals: sshPrincipalsFromMachines(*p1, *p3), + SSHUsers: map[string]string{ + "ubuntu": "ubuntu", + }, + Action: &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + }, + }, + } + + assert.Equal(t, expectedRules, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithTagsInDstAndAutogroupMemberInSrc(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("nick@example.com") + p3 := createMachine("nick@example.com", "tag:web") + + policy := ACLPolicy{ + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"autogroup:members"}, + Dst: []string{"tag:web"}, + Users: []string{"ubuntu"}, + }, + }, + } + + dst := createMachine("john@example.com", "tag:web") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2, *p3}, dst) + expectedRules := []*tailcfg.SSHRule{ + { + Principals: sshPrincipalsFromMachines(*p1, *p2), + SSHUsers: map[string]string{ + "ubuntu": "ubuntu", + }, + Action: &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + }, + }, + } + + assert.Equal(t, expectedRules, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithUserInDstAndNonMatchingSrc(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("jane@example.com") + + policy := ACLPolicy{ + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"jane@example.com"}, + Dst: []string{"john@example.com"}, + Users: []string{"autogroup:nonroot"}, + }, + }, + } + + dst := createMachine("john@example.com") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst) + + assert.Nil(t, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithUserInDstAndAutogroupMembersSrc(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("jane@example.com") + + policy := ACLPolicy{ + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"autogroup:members"}, + Dst: []string{"john@example.com"}, + Users: []string{"autogroup:nonroot"}, + }, + }, + } + + dst := createMachine("john@example.com") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst) + expectedRules := []*tailcfg.SSHRule{ + { + Principals: sshPrincipalsFromMachines(*p1), + SSHUsers: map[string]string{ + "*": "=", + "root": "", + }, + Action: &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + }, + }, + } + + assert.Equal(t, expectedRules, actualRules.Rules) +} + +func TestACLPolicy_BuildSSHPolicy_WithAutogroupSelfAndTagSrc(t *testing.T) { + p1 := createMachine("john@example.com") + p2 := createMachine("jane@example.com", "tag:web") + + policy := ACLPolicy{ + SSHRules: []SSHRule{ + { + Action: "accept", + Src: []string{"tag:web"}, + Dst: []string{"autogroup:self"}, + Users: []string{"autogroup:nonroot"}, + }, + }, + } + + dst := createMachine("john@example.com") + + actualRules := policy.BuildSSHPolicy([]Machine{*p1, *p2}, dst) + + assert.Nil(t, actualRules.Rules) +} + +func printRules(rules []*tailcfg.SSHRule) { + indent, err := json.MarshalIndent(rules, "", " ") + if err != nil { + panic(err) + } + fmt.Println(string(indent)) +} + +func sshPrincipalsFromMachines(machines ...Machine) []*tailcfg.SSHPrincipal { + x := StringSet{} + for _, m := range machines { + x.Add(m.IPv4.String(), m.IPv6.String()) + } + + var result = []*tailcfg.SSHPrincipal{} + + for _, i := range x.Items() { + result = append(result, &tailcfg.SSHPrincipal{NodeIP: i}) + } + + return result +} diff --git a/internal/domain/acl_test.go b/internal/domain/acl_test.go index e2c338b..910feda 100644 --- a/internal/domain/acl_test.go +++ b/internal/domain/acl_test.go @@ -1,8 +1,6 @@ package domain import ( - "encoding/json" - "fmt" "github.com/jsiebens/ionscale/internal/addr" "github.com/stretchr/testify/assert" "net/netip" @@ -11,14 +9,6 @@ import ( "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") diff --git a/internal/domain/repository.go b/internal/domain/repository.go index e727eba..d01569e 100644 --- a/internal/domain/repository.go +++ b/internal/domain/repository.go @@ -78,6 +78,10 @@ type Repository interface { GetAuthenticationRequest(ctx context.Context, key string) (*AuthenticationRequest, error) DeleteAuthenticationRequest(ctx context.Context, key string) error + SaveSSHActionRequest(ctx context.Context, session *SSHActionRequest) error + GetSSHActionRequest(ctx context.Context, key string) (*SSHActionRequest, error) + DeleteSSHActionRequest(ctx context.Context, key string) error + Transaction(func(rp Repository) error) error } diff --git a/internal/domain/ssh_action_request.go b/internal/domain/ssh_action_request.go new file mode 100644 index 0000000..7b2e0c5 --- /dev/null +++ b/internal/domain/ssh_action_request.go @@ -0,0 +1,46 @@ +package domain + +import ( + "context" + "errors" + "gorm.io/gorm" + "time" +) + +type SSHActionRequest struct { + Key string `gorm:"primary_key"` + Action string + SrcMachineID uint64 + DstMachineID uint64 + CreatedAt time.Time +} + +func (r *repository) SaveSSHActionRequest(ctx context.Context, session *SSHActionRequest) error { + tx := r.withContext(ctx).Save(session) + + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (r *repository) GetSSHActionRequest(ctx context.Context, key string) (*SSHActionRequest, error) { + var m SSHActionRequest + tx := r.withContext(ctx).First(&m, "key = ?", key) + + if errors.Is(tx.Error, gorm.ErrRecordNotFound) { + return nil, nil + } + + if tx.Error != nil { + return nil, tx.Error + } + + return &m, nil +} + +func (r *repository) DeleteSSHActionRequest(ctx context.Context, key string) error { + tx := r.withContext(ctx).Delete(&SSHActionRequest{Key: key}) + return tx.Error +} diff --git a/internal/domain/tailnet.go b/internal/domain/tailnet.go index 31da705..3b3dcf7 100644 --- a/internal/domain/tailnet.go +++ b/internal/domain/tailnet.go @@ -20,6 +20,7 @@ type Tailnet struct { DERPMap DERPMap ServiceCollectionEnabled bool FileSharingEnabled bool + SSHEnabled bool } func (t Tailnet) GetDERPMap(ctx context.Context, fallack DefaultDERPMap) (*DERPMap, error) { diff --git a/internal/handlers/authentication.go b/internal/handlers/authentication.go index 5ecad5a..b45fce3 100644 --- a/internal/handlers/authentication.go +++ b/internal/handlers/authentication.go @@ -58,17 +58,26 @@ type oauthState struct { func (h *AuthenticationHandlers) StartCliAuth(c echo.Context) error { ctx := c.Request().Context() + flow := c.Param("flow") key := c.Param("key") - if s, err := h.repository.GetAuthenticationRequest(ctx, key); err != nil || s == nil { - return c.Redirect(http.StatusFound, "/a/error") + if flow == "c" { + if s, err := h.repository.GetAuthenticationRequest(ctx, key); err != nil || s == nil { + return c.Redirect(http.StatusFound, "/a/error") + } + } + + if flow == "s" { + if s, err := h.repository.GetSSHActionRequest(ctx, key); err != nil || s == nil { + return c.Redirect(http.StatusFound, "/a/error") + } } if h.authProvider == nil { return c.Redirect(http.StatusFound, "/a/error") } - state, err := h.createState("c", key) + state, err := h.createState(flow, key) if err != nil { return err } @@ -134,12 +143,48 @@ func (h *AuthenticationHandlers) Callback(c echo.Context) error { return err } - tailnets, err := h.listAvailableTailnets(ctx, user) + account, _, err := h.repository.GetOrCreateAccount(ctx, user.ID, user.Name) if err != nil { return err } - account, _, err := h.repository.GetOrCreateAccount(ctx, user.ID, user.Name) + if state.Flow == "s" { + sshActionReq, err := h.repository.GetSSHActionRequest(ctx, state.Key) + if err != nil || sshActionReq == nil { + return c.Redirect(http.StatusFound, "/a/error?e=ua") + } + + machine, err := h.repository.GetMachine(ctx, sshActionReq.SrcMachineID) + if err != nil || sshActionReq == nil { + return c.Redirect(http.StatusFound, "/a/error") + } + + policy := machine.Tailnet.ACLPolicy + + if machine.HasTags() && policy.IsTagOwner(machine.Tags, &domain.User{Name: account.LoginName, UserType: domain.UserTypePerson}) { + sshActionReq.Action = "accept" + if err := h.repository.SaveSSHActionRequest(ctx, sshActionReq); err != nil { + return c.Redirect(http.StatusFound, "/a/error") + } + return c.Redirect(http.StatusFound, "/a/success") + } + + if machine.User.AccountID != nil && *machine.User.AccountID == account.ID { + sshActionReq.Action = "accept" + if err := h.repository.SaveSSHActionRequest(ctx, sshActionReq); err != nil { + return c.Redirect(http.StatusFound, "/a/error") + } + return c.Redirect(http.StatusFound, "/a/success") + } + + sshActionReq.Action = "reject" + if err := h.repository.SaveSSHActionRequest(ctx, sshActionReq); err != nil { + return c.Redirect(http.StatusFound, "/a/error") + } + return c.Redirect(http.StatusFound, "/a/error?e=nmo") + } + + tailnets, err := h.listAvailableTailnets(ctx, user) if err != nil { return err } @@ -248,6 +293,8 @@ func (h *AuthenticationHandlers) Error(c echo.Context) error { return c.Render(http.StatusForbidden, "unauthorized.html", nil) case "nto": return c.Render(http.StatusForbidden, "notagowner.html", nil) + case "nmo": + return c.Render(http.StatusForbidden, "notmachineowner.html", nil) } return c.Render(http.StatusOK, "error.html", nil) } diff --git a/internal/handlers/poll_net_map.go b/internal/handlers/poll_net_map.go index 145f244..8ba6e91 100644 --- a/internal/handlers/poll_net_map.go +++ b/internal/handlers/poll_net_map.go @@ -226,6 +226,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin return nil, nil, "", err } + hostinfo := tailcfg.Hostinfo(m.HostInfo) node, user, err := mapping.ToNode(m, tailnet, false) if err != nil { return nil, nil, "", err @@ -277,7 +278,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin return nil, nil, "", err } - rules := policies.BuildFilterRules(candidatePeers, m) + filterRules := policies.BuildFilterRules(candidatePeers, m) controlTime := time.Now().UTC() var mapResponse *tailcfg.MapResponse @@ -287,7 +288,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin KeepAlive: false, Node: node, DNSConfig: mapping.ToDNSConfig(m, validPeers, &m.Tailnet, &dnsConfig), - PacketFilter: rules, + PacketFilter: filterRules, DERPMap: &derpMap.DERPMap, Domain: domain.SanitizeTailnetName(m.Tailnet.Name), Peers: changedPeers, @@ -302,7 +303,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin mapResponse = &tailcfg.MapResponse{ Node: node, DNSConfig: mapping.ToDNSConfig(m, validPeers, &m.Tailnet, &dnsConfig), - PacketFilter: rules, + PacketFilter: filterRules, Domain: domain.SanitizeTailnetName(m.Tailnet.Name), PeersChanged: changedPeers, PeersRemoved: removedPeers, @@ -316,6 +317,10 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin } } + if tailnet.SSHEnabled && hostinfo.TailscaleSSHEnabled() { + mapResponse.SSHPolicy = policies.BuildSSHPolicy(candidatePeers, m) + } + if request.OmitPeers { mapResponse.PeersChanged = nil mapResponse.PeersRemoved = nil diff --git a/internal/handlers/ssh_action.go b/internal/handlers/ssh_action.go new file mode 100644 index 0000000..caa94bf --- /dev/null +++ b/internal/handlers/ssh_action.go @@ -0,0 +1,113 @@ +package handlers + +import ( + "fmt" + "github.com/jsiebens/ionscale/internal/bind" + "github.com/jsiebens/ionscale/internal/config" + "github.com/jsiebens/ionscale/internal/domain" + "github.com/jsiebens/ionscale/internal/util" + "github.com/labstack/echo/v4" + "net/http" + "tailscale.com/tailcfg" + "time" +) + +func NewSSHActionHandlers(createBinder bind.Factory, config *config.Config, repository domain.Repository) *SSHActionHandlers { + return &SSHActionHandlers{ + createBinder: createBinder, + repository: repository, + config: config, + } +} + +type SSHActionHandlers struct { + createBinder bind.Factory + repository domain.Repository + config *config.Config +} + +type sshActionRequestData struct { + SrcMachineID uint64 `param:"src_machine_id"` + DstMachineID uint64 `param:"dst_machine_id"` +} + +func (h *SSHActionHandlers) StartAuth(c echo.Context) error { + ctx := c.Request().Context() + + binder, err := h.createBinder(c) + if err != nil { + return err + } + + data := new(sshActionRequestData) + if err = c.Bind(data); err != nil { + return c.String(http.StatusBadRequest, "bad request") + } + + key := util.RandStringBytes(8) + request := &domain.SSHActionRequest{ + Key: key, + SrcMachineID: data.SrcMachineID, + DstMachineID: data.DstMachineID, + CreatedAt: time.Now().UTC(), + } + + authUrl := h.config.CreateUrl("/a/s/%s", key) + + if err := h.repository.SaveSSHActionRequest(ctx, request); err != nil { + return err + } + + resp := &tailcfg.SSHAction{ + Message: fmt.Sprintf("# Tailscale SSH requires an additional check.\n# To authenticate, visit: %s\n", authUrl), + HoldAndDelegate: fmt.Sprintf("https://unused/machine/ssh/action/check/%s", key), + } + + return binder.WriteResponse(c, http.StatusOK, resp) +} + +func (h *SSHActionHandlers) CheckAuth(c echo.Context) error { + // Listen to connection close + ctx := c.Request().Context() + notify := ctx.Done() + + binder, err := h.createBinder(c) + if err != nil { + return err + } + + tick := time.NewTicker(2 * time.Second) + + defer func() { tick.Stop() }() + + key := c.Param("key") + + for { + select { + case <-tick.C: + m, err := h.repository.GetSSHActionRequest(ctx, key) + + if err != nil || m == nil { + return binder.WriteResponse(c, http.StatusOK, &tailcfg.SSHAction{Reject: true}) + } + + if m.Action == "accept" { + action := &tailcfg.SSHAction{ + Accept: true, + AllowAgentForwarding: true, + AllowLocalPortForwarding: true, + } + _ = h.repository.DeleteSSHActionRequest(ctx, key) + return binder.WriteResponse(c, http.StatusOK, action) + } + + if m.Action == "reject" { + action := &tailcfg.SSHAction{Reject: true} + _ = h.repository.DeleteSSHActionRequest(ctx, key) + return binder.WriteResponse(c, http.StatusOK, action) + } + case <-notify: + return nil + } + } +} diff --git a/internal/mapping/mapping.go b/internal/mapping/mapping.go index 5454114..d249b13 100644 --- a/internal/mapping/mapping.go +++ b/internal/mapping/mapping.go @@ -121,6 +121,10 @@ func ToNode(m *domain.Machine, tailnet *domain.Tailnet, peer bool) (*tailcfg.Nod if tailnet.FileSharingEnabled { capabilities = append(capabilities, tailcfg.CapabilityFileSharing) } + + if tailnet.SSHEnabled { + capabilities = append(capabilities, tailcfg.CapabilitySSH) + } } nKey, err := util.ParseNodePublicKey(m.NodeKey) diff --git a/internal/server/server.go b/internal/server/server.go index 4fa4ac9..c8140f8 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -97,6 +97,7 @@ func Start(c *config.Config) error { pollNetMapHandler := handlers.NewPollNetMapHandler(bind.DefaultBinder(p), brokers, repository, offlineTimers) dnsHandlers := handlers.NewDNSHandlers(bind.DefaultBinder(p), dnsProvider) idTokenHandlers := handlers.NewIDTokenHandlers(bind.DefaultBinder(p), c, repository) + sshActionHandlers := handlers.NewSSHActionHandlers(bind.DefaultBinder(p), c, repository) e := echo.New() e.Use(EchoLogger(logger)) @@ -105,6 +106,8 @@ func Start(c *config.Config) error { e.POST("/machine/map", pollNetMapHandler.PollNetMap) e.POST("/machine/set-dns", dnsHandlers.SetDNS) e.POST("/machine/id-token", idTokenHandlers.FetchToken) + e.GET("/machine/ssh/action/:src_machine_id/to/:dst_machine_id", sshActionHandlers.StartAuth) + e.GET("/machine/ssh/action/check/:key", sshActionHandlers.CheckAuth) return e } @@ -161,7 +164,7 @@ func Start(c *config.Config) error { })) auth.GET("/:key", authenticationHandlers.StartAuth) auth.POST("/:key", authenticationHandlers.ProcessAuth) - auth.GET("/c/:key", authenticationHandlers.StartCliAuth) + auth.GET("/:flow/:key", authenticationHandlers.StartCliAuth) auth.GET("/callback", authenticationHandlers.Callback) auth.POST("/callback", authenticationHandlers.EndOAuth) auth.GET("/success", authenticationHandlers.Success) diff --git a/internal/service/tailnet.go b/internal/service/tailnet.go index 56e97e1..1cfc26d 100644 --- a/internal/service/tailnet.go +++ b/internal/service/tailnet.go @@ -334,3 +334,55 @@ func (s *Service) DisableServiceCollection(ctx context.Context, req *connect.Req return connect.NewResponse(&api.DisableServiceCollectionResponse{}), nil } + +func (s *Service) EnabledSSH(ctx context.Context, req *connect.Request[api.EnableSSHRequest]) (*connect.Response[api.EnableSSHResponse], error) { + principal := CurrentPrincipal(ctx) + if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) { + return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied")) + } + + tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId) + if err != nil { + return nil, err + } + if tailnet == nil { + return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found")) + } + + if !tailnet.SSHEnabled { + tailnet.SSHEnabled = true + if err := s.repository.SaveTailnet(ctx, tailnet); err != nil { + return nil, err + } + + s.pubsub.Publish(tailnet.ID, &broker.Signal{}) + } + + return connect.NewResponse(&api.EnableSSHResponse{}), nil +} + +func (s *Service) DisableSSH(ctx context.Context, req *connect.Request[api.DisableSSHRequest]) (*connect.Response[api.DisableSSHResponse], error) { + principal := CurrentPrincipal(ctx) + if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) { + return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied")) + } + + tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId) + if err != nil { + return nil, err + } + if tailnet == nil { + return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found")) + } + + if tailnet.SSHEnabled { + tailnet.SSHEnabled = false + if err := s.repository.SaveTailnet(ctx, tailnet); err != nil { + return nil, err + } + + s.pubsub.Publish(tailnet.ID, &broker.Signal{}) + } + + return connect.NewResponse(&api.DisableSSHResponse{}), nil +} diff --git a/internal/templates/notmachineowner.html b/internal/templates/notmachineowner.html new file mode 100644 index 0000000..c91691f --- /dev/null +++ b/internal/templates/notmachineowner.html @@ -0,0 +1,63 @@ + + + + + + + ionscale + + +
+
+

Authentication successful

+ but you're not a valid owner of the machine +
+
+ + \ No newline at end of file diff --git a/pkg/gen/ionscale/v1/acl.pb.go b/pkg/gen/ionscale/v1/acl.pb.go index bd2e81d..c52f3c6 100644 --- a/pkg/gen/ionscale/v1/acl.pb.go +++ b/pkg/gen/ionscale/v1/acl.pb.go @@ -218,6 +218,7 @@ type ACLPolicy struct { Acls []*ACL `protobuf:"bytes,3,rep,name=acls,proto3" json:"acls,omitempty"` Tagowners map[string]*structpb.ListValue `protobuf:"bytes,4,rep,name=tagowners,proto3" json:"tagowners,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Autoapprovers *AutoApprovers `protobuf:"bytes,5,opt,name=autoapprovers,proto3" json:"autoapprovers,omitempty"` + Ssh []*SSHRule `protobuf:"bytes,6,rep,name=ssh,proto3" json:"ssh,omitempty"` } func (x *ACLPolicy) Reset() { @@ -287,6 +288,13 @@ func (x *ACLPolicy) GetAutoapprovers() *AutoApprovers { return nil } +func (x *ACLPolicy) GetSsh() []*SSHRule { + if x != nil { + return x.Ssh + } + return nil +} + type ACL struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -405,6 +413,77 @@ func (x *AutoApprovers) GetExitnode() []string { return nil } +type SSHRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Action string `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"` + Src []string `protobuf:"bytes,2,rep,name=src,proto3" json:"src,omitempty"` + Dst []string `protobuf:"bytes,3,rep,name=dst,proto3" json:"dst,omitempty"` + Users []string `protobuf:"bytes,4,rep,name=users,proto3" json:"users,omitempty"` +} + +func (x *SSHRule) Reset() { + *x = SSHRule{} + if protoimpl.UnsafeEnabled { + mi := &file_ionscale_v1_acl_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SSHRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SSHRule) ProtoMessage() {} + +func (x *SSHRule) ProtoReflect() protoreflect.Message { + mi := &file_ionscale_v1_acl_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SSHRule.ProtoReflect.Descriptor instead. +func (*SSHRule) Descriptor() ([]byte, []int) { + return file_ionscale_v1_acl_proto_rawDescGZIP(), []int{7} +} + +func (x *SSHRule) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *SSHRule) GetSrc() []string { + if x != nil { + return x.Src + } + return nil +} + +func (x *SSHRule) GetDst() []string { + if x != nil { + return x.Dst + } + return nil +} + +func (x *SSHRule) GetUsers() []string { + if x != nil { + return x.Users + } + return nil +} + var File_ionscale_v1_acl_proto protoreflect.FileDescriptor var file_ionscale_v1_acl_proto_rawDesc = []byte{ @@ -429,7 +508,7 @@ var file_ionscale_v1_acl_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x16, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x98, 0x04, 0x0a, 0x09, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc0, 0x04, 0x0a, 0x09, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x43, 0x4c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, @@ -448,42 +527,51 @@ var file_ionscale_v1_acl_proto_rawDesc = []byte{ 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, + 0x6f, 0x76, 0x65, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x03, 0x73, 0x73, 0x68, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x53, 0x48, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x03, 0x73, 0x73, 0x68, 0x1a, 0x38, 0x0a, + 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x55, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x58, + 0x0a, 0x0e, 0x54, 0x61, 0x67, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 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, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41, 0x0a, 0x03, 0x41, 0x43, 0x4c, 0x12, + 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x73, 0x74, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x64, 0x73, 0x74, 0x22, 0xc2, 0x01, 0x0a, 0x0d, + 0x41, 0x75, 0x74, 0x6f, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3e, 0x0a, + 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, + 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1a, 0x0a, + 0x08, 0x65, 0x78, 0x69, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x08, 0x65, 0x78, 0x69, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x1a, 0x55, 0x0a, 0x0b, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x5b, 0x0a, 0x07, 0x53, 0x53, 0x48, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x72, 0x63, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x03, 0x73, 0x72, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x03, 0x64, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x42, 0x3d, 0x5a, + 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, + 0x62, 0x65, 0x6e, 0x73, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, + 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, + 0x31, 0x3b, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -498,7 +586,7 @@ func file_ionscale_v1_acl_proto_rawDescGZIP() []byte { return file_ionscale_v1_acl_proto_rawDescData } -var file_ionscale_v1_acl_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_ionscale_v1_acl_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_ionscale_v1_acl_proto_goTypes = []interface{}{ (*GetACLPolicyRequest)(nil), // 0: ionscale.v1.GetACLPolicyRequest (*GetACLPolicyResponse)(nil), // 1: ionscale.v1.GetACLPolicyResponse @@ -507,29 +595,31 @@ var file_ionscale_v1_acl_proto_goTypes = []interface{}{ (*ACLPolicy)(nil), // 4: ionscale.v1.ACLPolicy (*ACL)(nil), // 5: ionscale.v1.ACL (*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 + (*SSHRule)(nil), // 7: ionscale.v1.SSHRule + nil, // 8: ionscale.v1.ACLPolicy.HostsEntry + nil, // 9: ionscale.v1.ACLPolicy.GroupsEntry + nil, // 10: ionscale.v1.ACLPolicy.TagownersEntry + nil, // 11: ionscale.v1.AutoApprovers.RoutesEntry + (*structpb.ListValue)(nil), // 12: google.protobuf.ListValue } var file_ionscale_v1_acl_proto_depIdxs = []int32{ 4, // 0: ionscale.v1.GetACLPolicyResponse.policy:type_name -> ionscale.v1.ACLPolicy 4, // 1: ionscale.v1.SetACLPolicyRequest.policy:type_name -> ionscale.v1.ACLPolicy - 7, // 2: ionscale.v1.ACLPolicy.hosts:type_name -> ionscale.v1.ACLPolicy.HostsEntry - 8, // 3: ionscale.v1.ACLPolicy.groups:type_name -> ionscale.v1.ACLPolicy.GroupsEntry + 8, // 2: ionscale.v1.ACLPolicy.hosts:type_name -> ionscale.v1.ACLPolicy.HostsEntry + 9, // 3: ionscale.v1.ACLPolicy.groups:type_name -> ionscale.v1.ACLPolicy.GroupsEntry 5, // 4: ionscale.v1.ACLPolicy.acls:type_name -> ionscale.v1.ACL - 9, // 5: ionscale.v1.ACLPolicy.tagowners:type_name -> ionscale.v1.ACLPolicy.TagownersEntry + 10, // 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 + 7, // 7: ionscale.v1.ACLPolicy.ssh:type_name -> ionscale.v1.SSHRule + 11, // 8: ionscale.v1.AutoApprovers.routes:type_name -> ionscale.v1.AutoApprovers.RoutesEntry + 12, // 9: ionscale.v1.ACLPolicy.GroupsEntry.value:type_name -> google.protobuf.ListValue + 12, // 10: ionscale.v1.ACLPolicy.TagownersEntry.value:type_name -> google.protobuf.ListValue + 12, // 11: ionscale.v1.AutoApprovers.RoutesEntry.value:type_name -> google.protobuf.ListValue + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_ionscale_v1_acl_proto_init() } @@ -623,6 +713,18 @@ func file_ionscale_v1_acl_proto_init() { return nil } } + file_ionscale_v1_acl_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SSHRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -630,7 +732,7 @@ func file_ionscale_v1_acl_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ionscale_v1_acl_proto_rawDesc, NumEnums: 0, - NumMessages: 11, + NumMessages: 12, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/gen/ionscale/v1/ionscale.pb.go b/pkg/gen/ionscale/v1/ionscale.pb.go index b052a78..beecc29 100644 --- a/pkg/gen/ionscale/v1/ionscale.pb.go +++ b/pkg/gen/ionscale/v1/ionscale.pb.go @@ -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, 0xc5, 0x1d, 0x0a, 0x0f, 0x49, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, + 0x74, 0x6f, 0x32, 0xe5, 0x1e, 0x0a, 0x0f, 0x49, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, @@ -145,6 +145,16 @@ var file_ionscale_v1_ionscale_proto_rawDesc = []byte{ 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0a, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x53, 0x53, + 0x48, 0x12, 0x1d, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, + 0x12, 0x1e, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1f, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, @@ -309,66 +319,70 @@ var file_ionscale_v1_ionscale_proto_goTypes = []interface{}{ (*DisableFileSharingRequest)(nil), // 13: ionscale.v1.DisableFileSharingRequest (*EnableServiceCollectionRequest)(nil), // 14: ionscale.v1.EnableServiceCollectionRequest (*DisableServiceCollectionRequest)(nil), // 15: ionscale.v1.DisableServiceCollectionRequest - (*GetDNSConfigRequest)(nil), // 16: ionscale.v1.GetDNSConfigRequest - (*SetDNSConfigRequest)(nil), // 17: ionscale.v1.SetDNSConfigRequest - (*GetIAMPolicyRequest)(nil), // 18: ionscale.v1.GetIAMPolicyRequest - (*SetIAMPolicyRequest)(nil), // 19: ionscale.v1.SetIAMPolicyRequest - (*GetACLPolicyRequest)(nil), // 20: ionscale.v1.GetACLPolicyRequest - (*SetACLPolicyRequest)(nil), // 21: ionscale.v1.SetACLPolicyRequest - (*GetAuthKeyRequest)(nil), // 22: ionscale.v1.GetAuthKeyRequest - (*CreateAuthKeyRequest)(nil), // 23: ionscale.v1.CreateAuthKeyRequest - (*DeleteAuthKeyRequest)(nil), // 24: ionscale.v1.DeleteAuthKeyRequest - (*ListAuthKeysRequest)(nil), // 25: ionscale.v1.ListAuthKeysRequest - (*ListUsersRequest)(nil), // 26: ionscale.v1.ListUsersRequest - (*DeleteUserRequest)(nil), // 27: ionscale.v1.DeleteUserRequest - (*GetMachineRequest)(nil), // 28: ionscale.v1.GetMachineRequest - (*ListMachinesRequest)(nil), // 29: ionscale.v1.ListMachinesRequest - (*ExpireMachineRequest)(nil), // 30: ionscale.v1.ExpireMachineRequest - (*DeleteMachineRequest)(nil), // 31: ionscale.v1.DeleteMachineRequest - (*SetMachineKeyExpiryRequest)(nil), // 32: ionscale.v1.SetMachineKeyExpiryRequest - (*GetMachineRoutesRequest)(nil), // 33: ionscale.v1.GetMachineRoutesRequest - (*EnableMachineRoutesRequest)(nil), // 34: ionscale.v1.EnableMachineRoutesRequest - (*DisableMachineRoutesRequest)(nil), // 35: ionscale.v1.DisableMachineRoutesRequest - (*EnableExitNodeRequest)(nil), // 36: ionscale.v1.EnableExitNodeRequest - (*DisableExitNodeRequest)(nil), // 37: ionscale.v1.DisableExitNodeRequest - (*EnableHttpsCertificatesRequest)(nil), // 38: ionscale.v1.EnableHttpsCertificatesRequest - (*DisableHttpsCertificatesRequest)(nil), // 39: ionscale.v1.DisableHttpsCertificatesRequest - (*GetVersionResponse)(nil), // 40: ionscale.v1.GetVersionResponse - (*AuthenticationResponse)(nil), // 41: ionscale.v1.AuthenticationResponse - (*GetDefaultDERPMapResponse)(nil), // 42: ionscale.v1.GetDefaultDERPMapResponse - (*SetDefaultDERPMapResponse)(nil), // 43: ionscale.v1.SetDefaultDERPMapResponse - (*ResetDefaultDERPMapResponse)(nil), // 44: ionscale.v1.ResetDefaultDERPMapResponse - (*CreateTailnetResponse)(nil), // 45: ionscale.v1.CreateTailnetResponse - (*GetTailnetResponse)(nil), // 46: ionscale.v1.GetTailnetResponse - (*ListTailnetResponse)(nil), // 47: ionscale.v1.ListTailnetResponse - (*DeleteTailnetResponse)(nil), // 48: ionscale.v1.DeleteTailnetResponse - (*GetDERPMapResponse)(nil), // 49: ionscale.v1.GetDERPMapResponse - (*SetDERPMapResponse)(nil), // 50: ionscale.v1.SetDERPMapResponse - (*ResetDERPMapResponse)(nil), // 51: ionscale.v1.ResetDERPMapResponse - (*EnableFileSharingResponse)(nil), // 52: ionscale.v1.EnableFileSharingResponse - (*DisableFileSharingResponse)(nil), // 53: ionscale.v1.DisableFileSharingResponse - (*EnableServiceCollectionResponse)(nil), // 54: ionscale.v1.EnableServiceCollectionResponse - (*DisableServiceCollectionResponse)(nil), // 55: ionscale.v1.DisableServiceCollectionResponse - (*GetDNSConfigResponse)(nil), // 56: ionscale.v1.GetDNSConfigResponse - (*SetDNSConfigResponse)(nil), // 57: ionscale.v1.SetDNSConfigResponse - (*GetIAMPolicyResponse)(nil), // 58: ionscale.v1.GetIAMPolicyResponse - (*SetIAMPolicyResponse)(nil), // 59: ionscale.v1.SetIAMPolicyResponse - (*GetACLPolicyResponse)(nil), // 60: ionscale.v1.GetACLPolicyResponse - (*SetACLPolicyResponse)(nil), // 61: ionscale.v1.SetACLPolicyResponse - (*GetAuthKeyResponse)(nil), // 62: ionscale.v1.GetAuthKeyResponse - (*CreateAuthKeyResponse)(nil), // 63: ionscale.v1.CreateAuthKeyResponse - (*DeleteAuthKeyResponse)(nil), // 64: ionscale.v1.DeleteAuthKeyResponse - (*ListAuthKeysResponse)(nil), // 65: ionscale.v1.ListAuthKeysResponse - (*ListUsersResponse)(nil), // 66: ionscale.v1.ListUsersResponse - (*DeleteUserResponse)(nil), // 67: ionscale.v1.DeleteUserResponse - (*GetMachineResponse)(nil), // 68: ionscale.v1.GetMachineResponse - (*ListMachinesResponse)(nil), // 69: ionscale.v1.ListMachinesResponse - (*ExpireMachineResponse)(nil), // 70: ionscale.v1.ExpireMachineResponse - (*DeleteMachineResponse)(nil), // 71: ionscale.v1.DeleteMachineResponse - (*SetMachineKeyExpiryResponse)(nil), // 72: ionscale.v1.SetMachineKeyExpiryResponse - (*GetMachineRoutesResponse)(nil), // 73: ionscale.v1.GetMachineRoutesResponse - (*EnableHttpsCertificatesResponse)(nil), // 74: ionscale.v1.EnableHttpsCertificatesResponse - (*DisableHttpsCertificatesResponse)(nil), // 75: ionscale.v1.DisableHttpsCertificatesResponse + (*EnableSSHRequest)(nil), // 16: ionscale.v1.EnableSSHRequest + (*DisableSSHRequest)(nil), // 17: ionscale.v1.DisableSSHRequest + (*GetDNSConfigRequest)(nil), // 18: ionscale.v1.GetDNSConfigRequest + (*SetDNSConfigRequest)(nil), // 19: ionscale.v1.SetDNSConfigRequest + (*GetIAMPolicyRequest)(nil), // 20: ionscale.v1.GetIAMPolicyRequest + (*SetIAMPolicyRequest)(nil), // 21: ionscale.v1.SetIAMPolicyRequest + (*GetACLPolicyRequest)(nil), // 22: ionscale.v1.GetACLPolicyRequest + (*SetACLPolicyRequest)(nil), // 23: ionscale.v1.SetACLPolicyRequest + (*GetAuthKeyRequest)(nil), // 24: ionscale.v1.GetAuthKeyRequest + (*CreateAuthKeyRequest)(nil), // 25: ionscale.v1.CreateAuthKeyRequest + (*DeleteAuthKeyRequest)(nil), // 26: ionscale.v1.DeleteAuthKeyRequest + (*ListAuthKeysRequest)(nil), // 27: ionscale.v1.ListAuthKeysRequest + (*ListUsersRequest)(nil), // 28: ionscale.v1.ListUsersRequest + (*DeleteUserRequest)(nil), // 29: ionscale.v1.DeleteUserRequest + (*GetMachineRequest)(nil), // 30: ionscale.v1.GetMachineRequest + (*ListMachinesRequest)(nil), // 31: ionscale.v1.ListMachinesRequest + (*ExpireMachineRequest)(nil), // 32: ionscale.v1.ExpireMachineRequest + (*DeleteMachineRequest)(nil), // 33: ionscale.v1.DeleteMachineRequest + (*SetMachineKeyExpiryRequest)(nil), // 34: ionscale.v1.SetMachineKeyExpiryRequest + (*GetMachineRoutesRequest)(nil), // 35: ionscale.v1.GetMachineRoutesRequest + (*EnableMachineRoutesRequest)(nil), // 36: ionscale.v1.EnableMachineRoutesRequest + (*DisableMachineRoutesRequest)(nil), // 37: ionscale.v1.DisableMachineRoutesRequest + (*EnableExitNodeRequest)(nil), // 38: ionscale.v1.EnableExitNodeRequest + (*DisableExitNodeRequest)(nil), // 39: ionscale.v1.DisableExitNodeRequest + (*EnableHttpsCertificatesRequest)(nil), // 40: ionscale.v1.EnableHttpsCertificatesRequest + (*DisableHttpsCertificatesRequest)(nil), // 41: ionscale.v1.DisableHttpsCertificatesRequest + (*GetVersionResponse)(nil), // 42: ionscale.v1.GetVersionResponse + (*AuthenticationResponse)(nil), // 43: ionscale.v1.AuthenticationResponse + (*GetDefaultDERPMapResponse)(nil), // 44: ionscale.v1.GetDefaultDERPMapResponse + (*SetDefaultDERPMapResponse)(nil), // 45: ionscale.v1.SetDefaultDERPMapResponse + (*ResetDefaultDERPMapResponse)(nil), // 46: ionscale.v1.ResetDefaultDERPMapResponse + (*CreateTailnetResponse)(nil), // 47: ionscale.v1.CreateTailnetResponse + (*GetTailnetResponse)(nil), // 48: ionscale.v1.GetTailnetResponse + (*ListTailnetResponse)(nil), // 49: ionscale.v1.ListTailnetResponse + (*DeleteTailnetResponse)(nil), // 50: ionscale.v1.DeleteTailnetResponse + (*GetDERPMapResponse)(nil), // 51: ionscale.v1.GetDERPMapResponse + (*SetDERPMapResponse)(nil), // 52: ionscale.v1.SetDERPMapResponse + (*ResetDERPMapResponse)(nil), // 53: ionscale.v1.ResetDERPMapResponse + (*EnableFileSharingResponse)(nil), // 54: ionscale.v1.EnableFileSharingResponse + (*DisableFileSharingResponse)(nil), // 55: ionscale.v1.DisableFileSharingResponse + (*EnableServiceCollectionResponse)(nil), // 56: ionscale.v1.EnableServiceCollectionResponse + (*DisableServiceCollectionResponse)(nil), // 57: ionscale.v1.DisableServiceCollectionResponse + (*EnableSSHResponse)(nil), // 58: ionscale.v1.EnableSSHResponse + (*DisableSSHResponse)(nil), // 59: ionscale.v1.DisableSSHResponse + (*GetDNSConfigResponse)(nil), // 60: ionscale.v1.GetDNSConfigResponse + (*SetDNSConfigResponse)(nil), // 61: ionscale.v1.SetDNSConfigResponse + (*GetIAMPolicyResponse)(nil), // 62: ionscale.v1.GetIAMPolicyResponse + (*SetIAMPolicyResponse)(nil), // 63: ionscale.v1.SetIAMPolicyResponse + (*GetACLPolicyResponse)(nil), // 64: ionscale.v1.GetACLPolicyResponse + (*SetACLPolicyResponse)(nil), // 65: ionscale.v1.SetACLPolicyResponse + (*GetAuthKeyResponse)(nil), // 66: ionscale.v1.GetAuthKeyResponse + (*CreateAuthKeyResponse)(nil), // 67: ionscale.v1.CreateAuthKeyResponse + (*DeleteAuthKeyResponse)(nil), // 68: ionscale.v1.DeleteAuthKeyResponse + (*ListAuthKeysResponse)(nil), // 69: ionscale.v1.ListAuthKeysResponse + (*ListUsersResponse)(nil), // 70: ionscale.v1.ListUsersResponse + (*DeleteUserResponse)(nil), // 71: ionscale.v1.DeleteUserResponse + (*GetMachineResponse)(nil), // 72: ionscale.v1.GetMachineResponse + (*ListMachinesResponse)(nil), // 73: ionscale.v1.ListMachinesResponse + (*ExpireMachineResponse)(nil), // 74: ionscale.v1.ExpireMachineResponse + (*DeleteMachineResponse)(nil), // 75: ionscale.v1.DeleteMachineResponse + (*SetMachineKeyExpiryResponse)(nil), // 76: ionscale.v1.SetMachineKeyExpiryResponse + (*GetMachineRoutesResponse)(nil), // 77: ionscale.v1.GetMachineRoutesResponse + (*EnableHttpsCertificatesResponse)(nil), // 78: ionscale.v1.EnableHttpsCertificatesResponse + (*DisableHttpsCertificatesResponse)(nil), // 79: ionscale.v1.DisableHttpsCertificatesResponse } var file_ionscale_v1_ionscale_proto_depIdxs = []int32{ 0, // 0: ionscale.v1.IonscaleService.GetVersion:input_type -> ionscale.v1.GetVersionRequest @@ -387,72 +401,76 @@ var file_ionscale_v1_ionscale_proto_depIdxs = []int32{ 13, // 13: ionscale.v1.IonscaleService.DisableFileSharing:input_type -> ionscale.v1.DisableFileSharingRequest 14, // 14: ionscale.v1.IonscaleService.EnabledServiceCollection:input_type -> ionscale.v1.EnableServiceCollectionRequest 15, // 15: ionscale.v1.IonscaleService.DisableServiceCollection:input_type -> ionscale.v1.DisableServiceCollectionRequest - 16, // 16: ionscale.v1.IonscaleService.GetDNSConfig:input_type -> ionscale.v1.GetDNSConfigRequest - 17, // 17: ionscale.v1.IonscaleService.SetDNSConfig:input_type -> ionscale.v1.SetDNSConfigRequest - 18, // 18: ionscale.v1.IonscaleService.GetIAMPolicy:input_type -> ionscale.v1.GetIAMPolicyRequest - 19, // 19: ionscale.v1.IonscaleService.SetIAMPolicy:input_type -> ionscale.v1.SetIAMPolicyRequest - 20, // 20: ionscale.v1.IonscaleService.GetACLPolicy:input_type -> ionscale.v1.GetACLPolicyRequest - 21, // 21: ionscale.v1.IonscaleService.SetACLPolicy:input_type -> ionscale.v1.SetACLPolicyRequest - 22, // 22: ionscale.v1.IonscaleService.GetAuthKey:input_type -> ionscale.v1.GetAuthKeyRequest - 23, // 23: ionscale.v1.IonscaleService.CreateAuthKey:input_type -> ionscale.v1.CreateAuthKeyRequest - 24, // 24: ionscale.v1.IonscaleService.DeleteAuthKey:input_type -> ionscale.v1.DeleteAuthKeyRequest - 25, // 25: ionscale.v1.IonscaleService.ListAuthKeys:input_type -> ionscale.v1.ListAuthKeysRequest - 26, // 26: ionscale.v1.IonscaleService.ListUsers:input_type -> ionscale.v1.ListUsersRequest - 27, // 27: ionscale.v1.IonscaleService.DeleteUser:input_type -> ionscale.v1.DeleteUserRequest - 28, // 28: ionscale.v1.IonscaleService.GetMachine:input_type -> ionscale.v1.GetMachineRequest - 29, // 29: ionscale.v1.IonscaleService.ListMachines:input_type -> ionscale.v1.ListMachinesRequest - 30, // 30: ionscale.v1.IonscaleService.ExpireMachine:input_type -> ionscale.v1.ExpireMachineRequest - 31, // 31: ionscale.v1.IonscaleService.DeleteMachine:input_type -> ionscale.v1.DeleteMachineRequest - 32, // 32: ionscale.v1.IonscaleService.SetMachineKeyExpiry:input_type -> ionscale.v1.SetMachineKeyExpiryRequest - 33, // 33: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest - 34, // 34: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest - 35, // 35: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest - 36, // 36: ionscale.v1.IonscaleService.EnableExitNode:input_type -> ionscale.v1.EnableExitNodeRequest - 37, // 37: ionscale.v1.IonscaleService.DisableExitNode:input_type -> ionscale.v1.DisableExitNodeRequest - 38, // 38: ionscale.v1.IonscaleService.EnableHttpsCertificates:input_type -> ionscale.v1.EnableHttpsCertificatesRequest - 39, // 39: ionscale.v1.IonscaleService.DisableHttpsCertificates:input_type -> ionscale.v1.DisableHttpsCertificatesRequest - 40, // 40: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse - 41, // 41: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticationResponse - 42, // 42: ionscale.v1.IonscaleService.GetDefaultDERPMap:output_type -> ionscale.v1.GetDefaultDERPMapResponse - 43, // 43: ionscale.v1.IonscaleService.SetDefaultDERPMap:output_type -> ionscale.v1.SetDefaultDERPMapResponse - 44, // 44: ionscale.v1.IonscaleService.ResetDefaultDERPMap:output_type -> ionscale.v1.ResetDefaultDERPMapResponse - 45, // 45: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse - 46, // 46: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse - 47, // 47: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetResponse - 48, // 48: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse - 49, // 49: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse - 50, // 50: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse - 51, // 51: ionscale.v1.IonscaleService.ResetDERPMap:output_type -> ionscale.v1.ResetDERPMapResponse - 52, // 52: ionscale.v1.IonscaleService.EnabledFileSharing:output_type -> ionscale.v1.EnableFileSharingResponse - 53, // 53: ionscale.v1.IonscaleService.DisableFileSharing:output_type -> ionscale.v1.DisableFileSharingResponse - 54, // 54: ionscale.v1.IonscaleService.EnabledServiceCollection:output_type -> ionscale.v1.EnableServiceCollectionResponse - 55, // 55: ionscale.v1.IonscaleService.DisableServiceCollection:output_type -> ionscale.v1.DisableServiceCollectionResponse - 56, // 56: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse - 57, // 57: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse - 58, // 58: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse - 59, // 59: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse - 60, // 60: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse - 61, // 61: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse - 62, // 62: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse - 63, // 63: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse - 64, // 64: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse - 65, // 65: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse - 66, // 66: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse - 67, // 67: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse - 68, // 68: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse - 69, // 69: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse - 70, // 70: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse - 71, // 71: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse - 72, // 72: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse - 73, // 73: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse - 73, // 74: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse - 73, // 75: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse - 73, // 76: ionscale.v1.IonscaleService.EnableExitNode:output_type -> ionscale.v1.GetMachineRoutesResponse - 73, // 77: ionscale.v1.IonscaleService.DisableExitNode:output_type -> ionscale.v1.GetMachineRoutesResponse - 74, // 78: ionscale.v1.IonscaleService.EnableHttpsCertificates:output_type -> ionscale.v1.EnableHttpsCertificatesResponse - 75, // 79: ionscale.v1.IonscaleService.DisableHttpsCertificates:output_type -> ionscale.v1.DisableHttpsCertificatesResponse - 40, // [40:80] is the sub-list for method output_type - 0, // [0:40] is the sub-list for method input_type + 16, // 16: ionscale.v1.IonscaleService.EnabledSSH:input_type -> ionscale.v1.EnableSSHRequest + 17, // 17: ionscale.v1.IonscaleService.DisableSSH:input_type -> ionscale.v1.DisableSSHRequest + 18, // 18: ionscale.v1.IonscaleService.GetDNSConfig:input_type -> ionscale.v1.GetDNSConfigRequest + 19, // 19: ionscale.v1.IonscaleService.SetDNSConfig:input_type -> ionscale.v1.SetDNSConfigRequest + 20, // 20: ionscale.v1.IonscaleService.GetIAMPolicy:input_type -> ionscale.v1.GetIAMPolicyRequest + 21, // 21: ionscale.v1.IonscaleService.SetIAMPolicy:input_type -> ionscale.v1.SetIAMPolicyRequest + 22, // 22: ionscale.v1.IonscaleService.GetACLPolicy:input_type -> ionscale.v1.GetACLPolicyRequest + 23, // 23: ionscale.v1.IonscaleService.SetACLPolicy:input_type -> ionscale.v1.SetACLPolicyRequest + 24, // 24: ionscale.v1.IonscaleService.GetAuthKey:input_type -> ionscale.v1.GetAuthKeyRequest + 25, // 25: ionscale.v1.IonscaleService.CreateAuthKey:input_type -> ionscale.v1.CreateAuthKeyRequest + 26, // 26: ionscale.v1.IonscaleService.DeleteAuthKey:input_type -> ionscale.v1.DeleteAuthKeyRequest + 27, // 27: ionscale.v1.IonscaleService.ListAuthKeys:input_type -> ionscale.v1.ListAuthKeysRequest + 28, // 28: ionscale.v1.IonscaleService.ListUsers:input_type -> ionscale.v1.ListUsersRequest + 29, // 29: ionscale.v1.IonscaleService.DeleteUser:input_type -> ionscale.v1.DeleteUserRequest + 30, // 30: ionscale.v1.IonscaleService.GetMachine:input_type -> ionscale.v1.GetMachineRequest + 31, // 31: ionscale.v1.IonscaleService.ListMachines:input_type -> ionscale.v1.ListMachinesRequest + 32, // 32: ionscale.v1.IonscaleService.ExpireMachine:input_type -> ionscale.v1.ExpireMachineRequest + 33, // 33: ionscale.v1.IonscaleService.DeleteMachine:input_type -> ionscale.v1.DeleteMachineRequest + 34, // 34: ionscale.v1.IonscaleService.SetMachineKeyExpiry:input_type -> ionscale.v1.SetMachineKeyExpiryRequest + 35, // 35: ionscale.v1.IonscaleService.GetMachineRoutes:input_type -> ionscale.v1.GetMachineRoutesRequest + 36, // 36: ionscale.v1.IonscaleService.EnableMachineRoutes:input_type -> ionscale.v1.EnableMachineRoutesRequest + 37, // 37: ionscale.v1.IonscaleService.DisableMachineRoutes:input_type -> ionscale.v1.DisableMachineRoutesRequest + 38, // 38: ionscale.v1.IonscaleService.EnableExitNode:input_type -> ionscale.v1.EnableExitNodeRequest + 39, // 39: ionscale.v1.IonscaleService.DisableExitNode:input_type -> ionscale.v1.DisableExitNodeRequest + 40, // 40: ionscale.v1.IonscaleService.EnableHttpsCertificates:input_type -> ionscale.v1.EnableHttpsCertificatesRequest + 41, // 41: ionscale.v1.IonscaleService.DisableHttpsCertificates:input_type -> ionscale.v1.DisableHttpsCertificatesRequest + 42, // 42: ionscale.v1.IonscaleService.GetVersion:output_type -> ionscale.v1.GetVersionResponse + 43, // 43: ionscale.v1.IonscaleService.Authenticate:output_type -> ionscale.v1.AuthenticationResponse + 44, // 44: ionscale.v1.IonscaleService.GetDefaultDERPMap:output_type -> ionscale.v1.GetDefaultDERPMapResponse + 45, // 45: ionscale.v1.IonscaleService.SetDefaultDERPMap:output_type -> ionscale.v1.SetDefaultDERPMapResponse + 46, // 46: ionscale.v1.IonscaleService.ResetDefaultDERPMap:output_type -> ionscale.v1.ResetDefaultDERPMapResponse + 47, // 47: ionscale.v1.IonscaleService.CreateTailnet:output_type -> ionscale.v1.CreateTailnetResponse + 48, // 48: ionscale.v1.IonscaleService.GetTailnet:output_type -> ionscale.v1.GetTailnetResponse + 49, // 49: ionscale.v1.IonscaleService.ListTailnets:output_type -> ionscale.v1.ListTailnetResponse + 50, // 50: ionscale.v1.IonscaleService.DeleteTailnet:output_type -> ionscale.v1.DeleteTailnetResponse + 51, // 51: ionscale.v1.IonscaleService.GetDERPMap:output_type -> ionscale.v1.GetDERPMapResponse + 52, // 52: ionscale.v1.IonscaleService.SetDERPMap:output_type -> ionscale.v1.SetDERPMapResponse + 53, // 53: ionscale.v1.IonscaleService.ResetDERPMap:output_type -> ionscale.v1.ResetDERPMapResponse + 54, // 54: ionscale.v1.IonscaleService.EnabledFileSharing:output_type -> ionscale.v1.EnableFileSharingResponse + 55, // 55: ionscale.v1.IonscaleService.DisableFileSharing:output_type -> ionscale.v1.DisableFileSharingResponse + 56, // 56: ionscale.v1.IonscaleService.EnabledServiceCollection:output_type -> ionscale.v1.EnableServiceCollectionResponse + 57, // 57: ionscale.v1.IonscaleService.DisableServiceCollection:output_type -> ionscale.v1.DisableServiceCollectionResponse + 58, // 58: ionscale.v1.IonscaleService.EnabledSSH:output_type -> ionscale.v1.EnableSSHResponse + 59, // 59: ionscale.v1.IonscaleService.DisableSSH:output_type -> ionscale.v1.DisableSSHResponse + 60, // 60: ionscale.v1.IonscaleService.GetDNSConfig:output_type -> ionscale.v1.GetDNSConfigResponse + 61, // 61: ionscale.v1.IonscaleService.SetDNSConfig:output_type -> ionscale.v1.SetDNSConfigResponse + 62, // 62: ionscale.v1.IonscaleService.GetIAMPolicy:output_type -> ionscale.v1.GetIAMPolicyResponse + 63, // 63: ionscale.v1.IonscaleService.SetIAMPolicy:output_type -> ionscale.v1.SetIAMPolicyResponse + 64, // 64: ionscale.v1.IonscaleService.GetACLPolicy:output_type -> ionscale.v1.GetACLPolicyResponse + 65, // 65: ionscale.v1.IonscaleService.SetACLPolicy:output_type -> ionscale.v1.SetACLPolicyResponse + 66, // 66: ionscale.v1.IonscaleService.GetAuthKey:output_type -> ionscale.v1.GetAuthKeyResponse + 67, // 67: ionscale.v1.IonscaleService.CreateAuthKey:output_type -> ionscale.v1.CreateAuthKeyResponse + 68, // 68: ionscale.v1.IonscaleService.DeleteAuthKey:output_type -> ionscale.v1.DeleteAuthKeyResponse + 69, // 69: ionscale.v1.IonscaleService.ListAuthKeys:output_type -> ionscale.v1.ListAuthKeysResponse + 70, // 70: ionscale.v1.IonscaleService.ListUsers:output_type -> ionscale.v1.ListUsersResponse + 71, // 71: ionscale.v1.IonscaleService.DeleteUser:output_type -> ionscale.v1.DeleteUserResponse + 72, // 72: ionscale.v1.IonscaleService.GetMachine:output_type -> ionscale.v1.GetMachineResponse + 73, // 73: ionscale.v1.IonscaleService.ListMachines:output_type -> ionscale.v1.ListMachinesResponse + 74, // 74: ionscale.v1.IonscaleService.ExpireMachine:output_type -> ionscale.v1.ExpireMachineResponse + 75, // 75: ionscale.v1.IonscaleService.DeleteMachine:output_type -> ionscale.v1.DeleteMachineResponse + 76, // 76: ionscale.v1.IonscaleService.SetMachineKeyExpiry:output_type -> ionscale.v1.SetMachineKeyExpiryResponse + 77, // 77: ionscale.v1.IonscaleService.GetMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse + 77, // 78: ionscale.v1.IonscaleService.EnableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse + 77, // 79: ionscale.v1.IonscaleService.DisableMachineRoutes:output_type -> ionscale.v1.GetMachineRoutesResponse + 77, // 80: ionscale.v1.IonscaleService.EnableExitNode:output_type -> ionscale.v1.GetMachineRoutesResponse + 77, // 81: ionscale.v1.IonscaleService.DisableExitNode:output_type -> ionscale.v1.GetMachineRoutesResponse + 78, // 82: ionscale.v1.IonscaleService.EnableHttpsCertificates:output_type -> ionscale.v1.EnableHttpsCertificatesResponse + 79, // 83: ionscale.v1.IonscaleService.DisableHttpsCertificates:output_type -> ionscale.v1.DisableHttpsCertificatesResponse + 42, // [42:84] is the sub-list for method output_type + 0, // [0:42] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/pkg/gen/ionscale/v1/ionscalev1connect/ionscale.connect.go b/pkg/gen/ionscale/v1/ionscalev1connect/ionscale.connect.go index aceb063..d680741 100644 --- a/pkg/gen/ionscale/v1/ionscalev1connect/ionscale.connect.go +++ b/pkg/gen/ionscale/v1/ionscalev1connect/ionscale.connect.go @@ -43,6 +43,8 @@ type IonscaleServiceClient interface { DisableFileSharing(context.Context, *connect_go.Request[v1.DisableFileSharingRequest]) (*connect_go.Response[v1.DisableFileSharingResponse], error) EnabledServiceCollection(context.Context, *connect_go.Request[v1.EnableServiceCollectionRequest]) (*connect_go.Response[v1.EnableServiceCollectionResponse], error) DisableServiceCollection(context.Context, *connect_go.Request[v1.DisableServiceCollectionRequest]) (*connect_go.Response[v1.DisableServiceCollectionResponse], error) + EnabledSSH(context.Context, *connect_go.Request[v1.EnableSSHRequest]) (*connect_go.Response[v1.EnableSSHResponse], error) + DisableSSH(context.Context, *connect_go.Request[v1.DisableSSHRequest]) (*connect_go.Response[v1.DisableSSHResponse], error) GetDNSConfig(context.Context, *connect_go.Request[v1.GetDNSConfigRequest]) (*connect_go.Response[v1.GetDNSConfigResponse], error) SetDNSConfig(context.Context, *connect_go.Request[v1.SetDNSConfigRequest]) (*connect_go.Response[v1.SetDNSConfigResponse], error) GetIAMPolicy(context.Context, *connect_go.Request[v1.GetIAMPolicyRequest]) (*connect_go.Response[v1.GetIAMPolicyResponse], error) @@ -159,6 +161,16 @@ func NewIonscaleServiceClient(httpClient connect_go.HTTPClient, baseURL string, baseURL+"/ionscale.v1.IonscaleService/DisableServiceCollection", opts..., ), + enabledSSH: connect_go.NewClient[v1.EnableSSHRequest, v1.EnableSSHResponse]( + httpClient, + baseURL+"/ionscale.v1.IonscaleService/EnabledSSH", + opts..., + ), + disableSSH: connect_go.NewClient[v1.DisableSSHRequest, v1.DisableSSHResponse]( + httpClient, + baseURL+"/ionscale.v1.IonscaleService/DisableSSH", + opts..., + ), getDNSConfig: connect_go.NewClient[v1.GetDNSConfigRequest, v1.GetDNSConfigResponse]( httpClient, baseURL+"/ionscale.v1.IonscaleService/GetDNSConfig", @@ -300,6 +312,8 @@ type ionscaleServiceClient struct { disableFileSharing *connect_go.Client[v1.DisableFileSharingRequest, v1.DisableFileSharingResponse] enabledServiceCollection *connect_go.Client[v1.EnableServiceCollectionRequest, v1.EnableServiceCollectionResponse] disableServiceCollection *connect_go.Client[v1.DisableServiceCollectionRequest, v1.DisableServiceCollectionResponse] + enabledSSH *connect_go.Client[v1.EnableSSHRequest, v1.EnableSSHResponse] + disableSSH *connect_go.Client[v1.DisableSSHRequest, v1.DisableSSHResponse] getDNSConfig *connect_go.Client[v1.GetDNSConfigRequest, v1.GetDNSConfigResponse] setDNSConfig *connect_go.Client[v1.SetDNSConfigRequest, v1.SetDNSConfigResponse] getIAMPolicy *connect_go.Client[v1.GetIAMPolicyRequest, v1.GetIAMPolicyResponse] @@ -406,6 +420,16 @@ func (c *ionscaleServiceClient) DisableServiceCollection(ctx context.Context, re return c.disableServiceCollection.CallUnary(ctx, req) } +// EnabledSSH calls ionscale.v1.IonscaleService.EnabledSSH. +func (c *ionscaleServiceClient) EnabledSSH(ctx context.Context, req *connect_go.Request[v1.EnableSSHRequest]) (*connect_go.Response[v1.EnableSSHResponse], error) { + return c.enabledSSH.CallUnary(ctx, req) +} + +// DisableSSH calls ionscale.v1.IonscaleService.DisableSSH. +func (c *ionscaleServiceClient) DisableSSH(ctx context.Context, req *connect_go.Request[v1.DisableSSHRequest]) (*connect_go.Response[v1.DisableSSHResponse], error) { + return c.disableSSH.CallUnary(ctx, req) +} + // GetDNSConfig calls ionscale.v1.IonscaleService.GetDNSConfig. func (c *ionscaleServiceClient) GetDNSConfig(ctx context.Context, req *connect_go.Request[v1.GetDNSConfigRequest]) (*connect_go.Response[v1.GetDNSConfigResponse], error) { return c.getDNSConfig.CallUnary(ctx, req) @@ -544,6 +568,8 @@ type IonscaleServiceHandler interface { DisableFileSharing(context.Context, *connect_go.Request[v1.DisableFileSharingRequest]) (*connect_go.Response[v1.DisableFileSharingResponse], error) EnabledServiceCollection(context.Context, *connect_go.Request[v1.EnableServiceCollectionRequest]) (*connect_go.Response[v1.EnableServiceCollectionResponse], error) DisableServiceCollection(context.Context, *connect_go.Request[v1.DisableServiceCollectionRequest]) (*connect_go.Response[v1.DisableServiceCollectionResponse], error) + EnabledSSH(context.Context, *connect_go.Request[v1.EnableSSHRequest]) (*connect_go.Response[v1.EnableSSHResponse], error) + DisableSSH(context.Context, *connect_go.Request[v1.DisableSSHRequest]) (*connect_go.Response[v1.DisableSSHResponse], error) GetDNSConfig(context.Context, *connect_go.Request[v1.GetDNSConfigRequest]) (*connect_go.Response[v1.GetDNSConfigResponse], error) SetDNSConfig(context.Context, *connect_go.Request[v1.SetDNSConfigRequest]) (*connect_go.Response[v1.SetDNSConfigResponse], error) GetIAMPolicy(context.Context, *connect_go.Request[v1.GetIAMPolicyRequest]) (*connect_go.Response[v1.GetIAMPolicyResponse], error) @@ -657,6 +683,16 @@ func NewIonscaleServiceHandler(svc IonscaleServiceHandler, opts ...connect_go.Ha svc.DisableServiceCollection, opts..., )) + mux.Handle("/ionscale.v1.IonscaleService/EnabledSSH", connect_go.NewUnaryHandler( + "/ionscale.v1.IonscaleService/EnabledSSH", + svc.EnabledSSH, + opts..., + )) + mux.Handle("/ionscale.v1.IonscaleService/DisableSSH", connect_go.NewUnaryHandler( + "/ionscale.v1.IonscaleService/DisableSSH", + svc.DisableSSH, + opts..., + )) mux.Handle("/ionscale.v1.IonscaleService/GetDNSConfig", connect_go.NewUnaryHandler( "/ionscale.v1.IonscaleService/GetDNSConfig", svc.GetDNSConfig, @@ -847,6 +883,14 @@ func (UnimplementedIonscaleServiceHandler) DisableServiceCollection(context.Cont return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableServiceCollection is not implemented")) } +func (UnimplementedIonscaleServiceHandler) EnabledSSH(context.Context, *connect_go.Request[v1.EnableSSHRequest]) (*connect_go.Response[v1.EnableSSHResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.EnabledSSH is not implemented")) +} + +func (UnimplementedIonscaleServiceHandler) DisableSSH(context.Context, *connect_go.Request[v1.DisableSSHRequest]) (*connect_go.Response[v1.DisableSSHResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.DisableSSH is not implemented")) +} + func (UnimplementedIonscaleServiceHandler) GetDNSConfig(context.Context, *connect_go.Request[v1.GetDNSConfigRequest]) (*connect_go.Response[v1.GetDNSConfigResponse], error) { return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("ionscale.v1.IonscaleService.GetDNSConfig is not implemented")) } diff --git a/pkg/gen/ionscale/v1/tailnets.pb.go b/pkg/gen/ionscale/v1/tailnets.pb.go index c5b7274..e4d3be8 100644 --- a/pkg/gen/ionscale/v1/tailnets.pb.go +++ b/pkg/gen/ionscale/v1/tailnets.pb.go @@ -1070,6 +1070,176 @@ func (*DisableServiceCollectionResponse) Descriptor() ([]byte, []int) { return file_ionscale_v1_tailnets_proto_rawDescGZIP(), []int{22} } +type EnableSSHRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"` +} + +func (x *EnableSSHRequest) Reset() { + *x = EnableSSHRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ionscale_v1_tailnets_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnableSSHRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnableSSHRequest) ProtoMessage() {} + +func (x *EnableSSHRequest) ProtoReflect() protoreflect.Message { + mi := &file_ionscale_v1_tailnets_proto_msgTypes[23] + 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 EnableSSHRequest.ProtoReflect.Descriptor instead. +func (*EnableSSHRequest) Descriptor() ([]byte, []int) { + return file_ionscale_v1_tailnets_proto_rawDescGZIP(), []int{23} +} + +func (x *EnableSSHRequest) GetTailnetId() uint64 { + if x != nil { + return x.TailnetId + } + return 0 +} + +type EnableSSHResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *EnableSSHResponse) Reset() { + *x = EnableSSHResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ionscale_v1_tailnets_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnableSSHResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnableSSHResponse) ProtoMessage() {} + +func (x *EnableSSHResponse) ProtoReflect() protoreflect.Message { + mi := &file_ionscale_v1_tailnets_proto_msgTypes[24] + 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 EnableSSHResponse.ProtoReflect.Descriptor instead. +func (*EnableSSHResponse) Descriptor() ([]byte, []int) { + return file_ionscale_v1_tailnets_proto_rawDescGZIP(), []int{24} +} + +type DisableSSHRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TailnetId uint64 `protobuf:"varint,1,opt,name=tailnet_id,json=tailnetId,proto3" json:"tailnet_id,omitempty"` +} + +func (x *DisableSSHRequest) Reset() { + *x = DisableSSHRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ionscale_v1_tailnets_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DisableSSHRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DisableSSHRequest) ProtoMessage() {} + +func (x *DisableSSHRequest) ProtoReflect() protoreflect.Message { + mi := &file_ionscale_v1_tailnets_proto_msgTypes[25] + 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 DisableSSHRequest.ProtoReflect.Descriptor instead. +func (*DisableSSHRequest) Descriptor() ([]byte, []int) { + return file_ionscale_v1_tailnets_proto_rawDescGZIP(), []int{25} +} + +func (x *DisableSSHRequest) GetTailnetId() uint64 { + if x != nil { + return x.TailnetId + } + return 0 +} + +type DisableSSHResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DisableSSHResponse) Reset() { + *x = DisableSSHResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ionscale_v1_tailnets_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DisableSSHResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DisableSSHResponse) ProtoMessage() {} + +func (x *DisableSSHResponse) ProtoReflect() protoreflect.Message { + mi := &file_ionscale_v1_tailnets_proto_msgTypes[26] + 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 DisableSSHResponse.ProtoReflect.Descriptor instead. +func (*DisableSSHResponse) Descriptor() ([]byte, []int) { + return file_ionscale_v1_tailnets_proto_rawDescGZIP(), []int{26} +} + var File_ionscale_v1_tailnets_proto protoreflect.FileDescriptor var file_ionscale_v1_tailnets_proto_rawDesc = []byte{ @@ -1151,11 +1321,21 @@ var file_ionscale_v1_tailnets_proto_rawDesc = []byte{ 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x22, 0x22, 0x0a, 0x20, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x0a, 0x10, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x22, 0x13, 0x0a, 0x11, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x32, 0x0a, 0x11, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x53, 0x48, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x61, 0x69, 0x6c, + 0x6e, 0x65, 0x74, 0x49, 0x64, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x53, 0x48, 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 ( @@ -1170,7 +1350,7 @@ func file_ionscale_v1_tailnets_proto_rawDescGZIP() []byte { return file_ionscale_v1_tailnets_proto_rawDescData } -var file_ionscale_v1_tailnets_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_ionscale_v1_tailnets_proto_msgTypes = make([]protoimpl.MessageInfo, 27) var file_ionscale_v1_tailnets_proto_goTypes = []interface{}{ (*Tailnet)(nil), // 0: ionscale.v1.Tailnet (*CreateTailnetRequest)(nil), // 1: ionscale.v1.CreateTailnetRequest @@ -1195,10 +1375,14 @@ var file_ionscale_v1_tailnets_proto_goTypes = []interface{}{ (*EnableServiceCollectionResponse)(nil), // 20: ionscale.v1.EnableServiceCollectionResponse (*DisableServiceCollectionRequest)(nil), // 21: ionscale.v1.DisableServiceCollectionRequest (*DisableServiceCollectionResponse)(nil), // 22: ionscale.v1.DisableServiceCollectionResponse - (*IAMPolicy)(nil), // 23: ionscale.v1.IAMPolicy + (*EnableSSHRequest)(nil), // 23: ionscale.v1.EnableSSHRequest + (*EnableSSHResponse)(nil), // 24: ionscale.v1.EnableSSHResponse + (*DisableSSHRequest)(nil), // 25: ionscale.v1.DisableSSHRequest + (*DisableSSHResponse)(nil), // 26: ionscale.v1.DisableSSHResponse + (*IAMPolicy)(nil), // 27: ionscale.v1.IAMPolicy } var file_ionscale_v1_tailnets_proto_depIdxs = []int32{ - 23, // 0: ionscale.v1.CreateTailnetRequest.iam_policy:type_name -> ionscale.v1.IAMPolicy + 27, // 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 @@ -1492,6 +1676,54 @@ func file_ionscale_v1_tailnets_proto_init() { return nil } } + file_ionscale_v1_tailnets_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnableSSHRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ionscale_v1_tailnets_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnableSSHResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ionscale_v1_tailnets_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DisableSSHRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ionscale_v1_tailnets_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DisableSSHResponse); 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{ @@ -1499,7 +1731,7 @@ func file_ionscale_v1_tailnets_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ionscale_v1_tailnets_proto_rawDesc, NumEnums: 0, - NumMessages: 23, + NumMessages: 27, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/ionscale/v1/acl.proto b/proto/ionscale/v1/acl.proto index 20dd965..5186fe9 100644 --- a/proto/ionscale/v1/acl.proto +++ b/proto/ionscale/v1/acl.proto @@ -29,6 +29,7 @@ message ACLPolicy { repeated ACL acls = 3; map tagowners = 4; AutoApprovers autoapprovers = 5; + repeated SSHRule ssh = 6; } message ACL { @@ -40,4 +41,11 @@ message ACL { message AutoApprovers { map routes = 1; repeated string exitnode = 2; +} + +message SSHRule { + string action = 1; + repeated string src = 2; + repeated string dst = 3; + repeated string users = 4; } \ No newline at end of file diff --git a/proto/ionscale/v1/ionscale.proto b/proto/ionscale/v1/ionscale.proto index 30c6092..09d9043 100644 --- a/proto/ionscale/v1/ionscale.proto +++ b/proto/ionscale/v1/ionscale.proto @@ -38,6 +38,8 @@ service IonscaleService { rpc DisableFileSharing (DisableFileSharingRequest) returns (DisableFileSharingResponse) {} rpc EnabledServiceCollection (EnableServiceCollectionRequest) returns (EnableServiceCollectionResponse) {} rpc DisableServiceCollection (DisableServiceCollectionRequest) returns (DisableServiceCollectionResponse) {} + rpc EnabledSSH (EnableSSHRequest) returns (EnableSSHResponse) {} + rpc DisableSSH (DisableSSHRequest) returns (DisableSSHResponse) {} rpc GetDNSConfig (GetDNSConfigRequest) returns (GetDNSConfigResponse) {} rpc SetDNSConfig (SetDNSConfigRequest) returns (SetDNSConfigResponse) {} diff --git a/proto/ionscale/v1/tailnets.proto b/proto/ionscale/v1/tailnets.proto index b5b16af..d97af99 100644 --- a/proto/ionscale/v1/tailnets.proto +++ b/proto/ionscale/v1/tailnets.proto @@ -91,4 +91,19 @@ message DisableServiceCollectionRequest { } message DisableServiceCollectionResponse { +} + + +message EnableSSHRequest { + uint64 tailnet_id = 1; +} + +message EnableSSHResponse { +} + +message DisableSSHRequest { + uint64 tailnet_id = 1; +} + +message DisableSSHResponse { } \ No newline at end of file