feat: add flags to create tailnet with some proper default IAM policies

This commit is contained in:
Johan Siebens
2022-09-23 14:04:23 +02:00
parent 6e3e22bc72
commit 980ae6dd85
7 changed files with 124 additions and 50 deletions
+46 -2
View File
@@ -4,9 +4,11 @@ import (
"context"
"fmt"
"github.com/bufbuild/connect-go"
idomain "github.com/jsiebens/ionscale/internal/domain"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
"github.com/muesli/coral"
"github.com/rodaine/table"
"strings"
)
func tailnetCommand() *coral.Command {
@@ -71,20 +73,62 @@ func createTailnetsCommand() *coral.Command {
}
var name string
var domain string
var email string
var target = Target{}
target.prepareCommand(command)
command.Flags().StringVarP(&name, "name", "n", "", "")
_ = command.MarkFlagRequired("name")
command.Flags().StringVar(&domain, "domain", "", "")
command.Flags().StringVar(&email, "email", "", "")
command.PreRunE = func(cmd *coral.Command, args []string) error {
if name == "" && email == "" && domain == "" {
return fmt.Errorf("at least flag --name, --email or --domain is required")
}
if domain != "" && email != "" {
return fmt.Errorf("flags --email and --domain are mutually exclusive")
}
return nil
}
command.RunE = func(command *coral.Command, args []string) error {
var tailnetName = ""
var iamPolicy = api.IAMPolicy{}
if len(domain) != 0 {
domainToLower := strings.ToLower(domain)
tailnetName = domainToLower
iamPolicy = api.IAMPolicy{
Filters: []string{fmt.Sprintf("domain == %s", domainToLower)},
}
}
if len(email) != 0 {
emailToLower := strings.ToLower(email)
tailnetName = emailToLower
iamPolicy = api.IAMPolicy{
Emails: []string{emailToLower},
Roles: map[string]string{
emailToLower: string(idomain.UserRoleAdmin),
},
}
}
if len(name) != 0 {
tailnetName = name
}
client, err := target.createGRPCClient()
if err != nil {
return err
}
resp, err := client.CreateTailnet(context.Background(), connect.NewRequest(&api.CreateTailnetRequest{Name: name}))
resp, err := client.CreateTailnet(context.Background(), connect.NewRequest(&api.CreateTailnetRequest{
Name: tailnetName,
IamPolicy: &iamPolicy,
}))
if err != nil {
return err
+1 -1
View File
@@ -18,7 +18,7 @@ type Repository interface {
GetOrCreateAccount(ctx context.Context, externalID, loginName string) (*Account, bool, error)
SaveTailnet(ctx context.Context, tailnet *Tailnet) error
GetOrCreateTailnet(ctx context.Context, name string) (*Tailnet, bool, error)
GetOrCreateTailnet(ctx context.Context, name string, iamPolicy IAMPolicy) (*Tailnet, bool, error)
GetTailnet(ctx context.Context, id uint64) (*Tailnet, error)
ListTailnets(ctx context.Context) ([]Tailnet, error)
DeleteTailnet(ctx context.Context, id uint64) error
+2 -2
View File
@@ -25,13 +25,13 @@ func (r *repository) SaveTailnet(ctx context.Context, tailnet *Tailnet) error {
return nil
}
func (r *repository) GetOrCreateTailnet(ctx context.Context, name string) (*Tailnet, bool, error) {
func (r *repository) GetOrCreateTailnet(ctx context.Context, name string, iamPolicy IAMPolicy) (*Tailnet, bool, error) {
tailnet := &Tailnet{}
id := util.NextID()
tx := r.withContext(ctx).
Where(Tailnet{Name: name}).
Attrs(Tailnet{ID: id, ACLPolicy: DefaultPolicy()}).
Attrs(Tailnet{ID: id, ACLPolicy: DefaultPolicy(), IAMPolicy: iamPolicy}).
FirstOrCreate(tailnet)
if tx.Error != nil {
+4
View File
@@ -85,10 +85,14 @@ func (p *OIDCProvider) Exchange(redirectURI, code string) (*User, error) {
return nil, err
}
domain := strings.Split(email, "@")[1]
return &User{
ID: sub,
Name: email,
Attr: map[string]interface{}{
"email": email,
"domain": domain,
"token": tokenClaims,
"userinfo": userInfoClaims,
},
+9 -1
View File
@@ -16,7 +16,15 @@ func (s *Service) CreateTailnet(ctx context.Context, req *connect.Request[api.Cr
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
tailnet, created, err := s.repository.GetOrCreateTailnet(ctx, req.Msg.Name)
name := req.Msg.Name
iamPolicy := domain.IAMPolicy{
Subs: req.Msg.IamPolicy.Subs,
Emails: req.Msg.IamPolicy.Emails,
Filters: req.Msg.IamPolicy.Filters,
Roles: apiRolesMapToDomainRolesMap(req.Msg.IamPolicy.Roles),
}
tailnet, created, err := s.repository.GetOrCreateTailnet(ctx, name, iamPolicy)
if err != nil {
return nil, err
}
+59 -44
View File
@@ -80,7 +80,8 @@ type CreateTailnetRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
IamPolicy *IAMPolicy `protobuf:"bytes,2,opt,name=iam_policy,json=iamPolicy,proto3" json:"iam_policy,omitempty"`
}
func (x *CreateTailnetRequest) Reset() {
@@ -122,6 +123,13 @@ func (x *CreateTailnetRequest) GetName() string {
return ""
}
func (x *CreateTailnetRequest) GetIamPolicy() *IAMPolicy {
if x != nil {
return x.IamPolicy
}
return nil
}
type CreateTailnetResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -446,41 +454,45 @@ var File_ionscale_v1_tailnets_proto protoreflect.FileDescriptor
var file_ionscale_v1_tailnets_proto_rawDesc = []byte{
0x0a, 0x1a, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61,
0x69, 0x6c, 0x6e, 0x65, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x2d, 0x0a, 0x07, 0x54, 0x61, 0x69,
0x6c, 0x6e, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x22, 0x47, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61,
0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a,
0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69,
0x6c, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x23, 0x0a,
0x11, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02,
0x69, 0x64, 0x22, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52,
0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74,
0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x45,
0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61,
0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x4b, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
0x0a, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x04, 0x52, 0x09, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05,
0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72,
0x63, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65,
0x6e, 0x73, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
0x67, 0x65, 0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b,
0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x15, 0x69, 0x6f, 0x6e, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x61, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x22, 0x2d, 0x0a, 0x07, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22,
0x61, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0a, 0x69,
0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x16, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x41,
0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x09, 0x69, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69,
0x63, 0x79, 0x22, 0x47, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69,
0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e,
0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x23, 0x0a, 0x11, 0x47,
0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64,
0x22, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x74,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61,
0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x45, 0x0a, 0x13,
0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x69, 0x6c,
0x6e, 0x65, 0x74, 0x22, 0x4b, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69,
0x6c, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74,
0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
0x09, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f,
0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65,
0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6a, 0x73, 0x69, 0x65, 0x62, 0x65, 0x6e, 0x73,
0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x65,
0x6e, 0x2f, 0x69, 0x6f, 0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6f,
0x6e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -506,16 +518,18 @@ var file_ionscale_v1_tailnets_proto_goTypes = []interface{}{
(*ListTailnetResponse)(nil), // 6: ionscale.v1.ListTailnetResponse
(*DeleteTailnetRequest)(nil), // 7: ionscale.v1.DeleteTailnetRequest
(*DeleteTailnetResponse)(nil), // 8: ionscale.v1.DeleteTailnetResponse
(*IAMPolicy)(nil), // 9: ionscale.v1.IAMPolicy
}
var file_ionscale_v1_tailnets_proto_depIdxs = []int32{
0, // 0: ionscale.v1.CreateTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
0, // 1: ionscale.v1.GetTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
0, // 2: ionscale.v1.ListTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
9, // 0: ionscale.v1.CreateTailnetRequest.iam_policy:type_name -> ionscale.v1.IAMPolicy
0, // 1: ionscale.v1.CreateTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
0, // 2: ionscale.v1.GetTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
0, // 3: ionscale.v1.ListTailnetResponse.tailnet:type_name -> ionscale.v1.Tailnet
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_ionscale_v1_tailnets_proto_init() }
@@ -523,6 +537,7 @@ func file_ionscale_v1_tailnets_proto_init() {
if File_ionscale_v1_tailnets_proto != nil {
return
}
file_ionscale_v1_iam_proto_init()
if !protoimpl.UnsafeEnabled {
file_ionscale_v1_tailnets_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Tailnet); i {
+3
View File
@@ -3,6 +3,8 @@ syntax = "proto3";
package ionscale.v1;
option go_package = "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1;ionscalev1";
import "ionscale/v1/iam.proto";
message Tailnet {
uint64 id = 1;
string name = 2;
@@ -10,6 +12,7 @@ message Tailnet {
message CreateTailnetRequest {
string name = 1;
IAMPolicy iam_policy = 2;
}
message CreateTailnetResponse {