diff --git a/cmd/cloud/main.go b/cmd/cloud/main.go index e67eea2..9172885 100644 --- a/cmd/cloud/main.go +++ b/cmd/cloud/main.go @@ -12,6 +12,7 @@ func NewCloudCommand() *cobra.Command { } cmd.AddCommand(newCloudLoginCommand()) + cmd.AddCommand(newRegisterCommand()) cmd.AddCommand(newQueryCommand()) cmd.AddCommand(newPingCommand()) cmd.AddCommand(newWhoamiCommand()) diff --git a/cmd/cloud/register.go b/cmd/cloud/register.go new file mode 100644 index 0000000..3ed3dc4 --- /dev/null +++ b/cmd/cloud/register.go @@ -0,0 +1,70 @@ +package cloud + +import ( + "github.com/safedep/vet/internal/auth" + "github.com/safedep/vet/internal/ui" + "github.com/safedep/vet/pkg/cloud" + "github.com/safedep/vet/pkg/common/logger" + "github.com/spf13/cobra" +) + +var ( + registerEmail string + registerName string + registerOrgName string + registerOrgDomain string +) + +func newRegisterCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "register", + Short: "Register a new user and tenant", + RunE: func(cmd *cobra.Command, args []string) error { + err := registerUserTenant() + if err != nil { + logger.Errorf("Failed to register user: %v", err) + } + + return nil + }, + } + + cmd.Flags().StringVar(®isterEmail, "email", "cloud@safedep.io", "Email of the user (not required for SafeDep cloud)") + cmd.Flags().StringVar(®isterName, "name", "", "Name of the user") + cmd.Flags().StringVar(®isterOrgName, "org-name", "", "Name of the organization") + cmd.Flags().StringVar(®isterOrgDomain, "org-domain", "", "Domain of the organization") + + _ = cmd.MarkFlagRequired("name") + _ = cmd.MarkFlagRequired("org-name") + _ = cmd.MarkFlagRequired("org-domain") + + return cmd +} + +func registerUserTenant() error { + conn, err := auth.ControlPlaneClientConnection("vet-cloud-register") + if err != nil { + return err + } + + onboardingService, err := cloud.NewOnboardingService(conn) + if err != nil { + return err + } + + res, err := onboardingService.Register(&cloud.RegisterRequest{ + Name: registerName, + Email: registerEmail, + OrgName: registerOrgName, + OrgDomain: registerOrgDomain, + }) + + if err != nil { + return err + } + + ui.PrintSuccess("Registered user and tenant.") + ui.PrintSuccess("Tenant domain: %s", res.TenantDomain) + + return nil +} diff --git a/pkg/cloud/onboarding.go b/pkg/cloud/onboarding.go new file mode 100644 index 0000000..055db45 --- /dev/null +++ b/pkg/cloud/onboarding.go @@ -0,0 +1,46 @@ +package cloud + +import ( + "context" + + "buf.build/gen/go/safedep/api/grpc/go/safedep/services/controltower/v1/controltowerv1grpc" + controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1" + "google.golang.org/grpc" +) + +type onboardingService struct { + conn *grpc.ClientConn +} + +type RegisterRequest struct { + Email string + Name string + OrgName string + OrgDomain string +} + +type RegisterResponse struct { + TenantDomain string +} + +func NewOnboardingService(conn *grpc.ClientConn) (*onboardingService, error) { + return &onboardingService{conn}, nil +} + +func (s *onboardingService) Register(req *RegisterRequest) (*RegisterResponse, error) { + onbService := controltowerv1grpc.NewOnboardingServiceClient(s.conn) + res, err := onbService.OnboardUser(context.Background(), &controltowerv1.OnboardUserRequest{ + Email: req.Email, + Name: req.Name, + OrganizationName: req.OrgName, + OrganizationDomain: req.OrgDomain, + }) + + if err != nil { + return nil, err + } + + return &RegisterResponse{ + TenantDomain: res.GetTenant().GetDomain(), + }, nil +}