diff --git a/admin/worker/reset_all_deployments.go b/admin/worker/reset_all_deployments.go index ec68f4f6ec0..59171b59726 100644 --- a/admin/worker/reset_all_deployments.go +++ b/admin/worker/reset_all_deployments.go @@ -2,7 +2,6 @@ package worker import ( "context" - "fmt" "github.com/rilldata/rill/admin/database" "github.com/rilldata/rill/runtime/pkg/observability" @@ -50,7 +49,8 @@ func (w *Worker) resetAllDeploymentsForProject(ctx context.Context, proj *databa // Make sure the deployment provisioner is in the current provisioner set _, ok := w.admin.ProvisionerSet[depl.Provisioner] if !ok { - return fmt.Errorf("reset all deployments: %q is not in the provisioner set", depl.Provisioner) + w.logger.Error("reset all deployments: provisioner is not in the provisioner set", zap.String("provisioner", depl.Provisioner), zap.String("deployment_id", depl.ID), observability.ZapCtx(ctx)) + continue } w.logger.Info("reset all deployments: redeploying deployment", zap.String("deployment_id", depl.ID), observability.ZapCtx(ctx)) diff --git a/cli/cmd/start/start.go b/cli/cmd/start/start.go index 47b15f43210..bdcf36bbb09 100644 --- a/cli/cmd/start/start.go +++ b/cli/cmd/start/start.go @@ -36,6 +36,7 @@ func StartCmd(ch *cmdutil.Helper) *cobra.Command { var logFormat string var env []string var vars []string + var allowedOrigins []string var tlsCertPath string var tlsKeyPath string @@ -143,22 +144,25 @@ func StartCmd(ch *cmdutil.Helper) *cobra.Command { } localURL := fmt.Sprintf("%s://localhost:%d", scheme, httpPort) + allowedOrigins = append(allowedOrigins, localURL) + app, err := local.NewApp(cmd.Context(), &local.AppOptions{ - Version: ch.Version, - Verbose: verbose, - Debug: debug, - Reset: reset, - Environment: environment, - OlapDriver: olapDriver, - OlapDSN: olapDSN, - ProjectPath: projectPath, - LogFormat: parsedLogFormat, - Variables: varsMap, - Activity: ch.Telemetry(cmd.Context()), - AdminURL: ch.AdminURL, - AdminToken: ch.AdminToken(), - CMDHelper: ch, - LocalURL: localURL, + Version: ch.Version, + Verbose: verbose, + Debug: debug, + Reset: reset, + Environment: environment, + OlapDriver: olapDriver, + OlapDSN: olapDSN, + ProjectPath: projectPath, + LogFormat: parsedLogFormat, + Variables: varsMap, + Activity: ch.Telemetry(cmd.Context()), + AdminURL: ch.AdminURL, + AdminToken: ch.AdminToken(), + CMDHelper: ch, + LocalURL: localURL, + AllowedOrigins: allowedOrigins, }) if err != nil { return err @@ -192,6 +196,7 @@ func StartCmd(ch *cmdutil.Helper) *cobra.Command { // --env was previously used for variables, but is now used to set the environment name. We maintain backwards compatibility by keeping --env as a slice var, and setting any value containing an equals sign as a variable. startCmd.Flags().StringSliceVarP(&env, "env", "e", []string{}, `Environment name (default "dev")`) startCmd.Flags().StringSliceVarP(&vars, "var", "v", []string{}, "Set project variables") + startCmd.Flags().StringSliceVarP(&allowedOrigins, "allowed-origins", "", []string{}, "add additional allowed-origins") // We have deprecated the ability configure the OLAP database via the CLI. This should now be done via rill.yaml. // Keeping these for backwards compatibility for a while. diff --git a/cli/cmd/sudo/clone.go b/cli/cmd/sudo/clone.go index 55065006080..296c50643d4 100644 --- a/cli/cmd/sudo/clone.go +++ b/cli/cmd/sudo/clone.go @@ -41,7 +41,7 @@ func cloneCmd(ch *cmdutil.Helper) *cobra.Command { fmt.Println("Clone command:") if res.ArchiveDownloadUrl != "" { - fmt.Printf("\tcurl -o %s__%s.tar.gz %s\n\n", args[0], args[1], res.ArchiveDownloadUrl) + fmt.Printf("\tcurl -o %s__%s.tar.gz '%s'\n\n", args[0], args[1], res.ArchiveDownloadUrl) return nil } diff --git a/cli/pkg/local/app.go b/cli/pkg/local/app.go index fa7f8e68cd1..057fccc0183 100644 --- a/cli/pkg/local/app.go +++ b/cli/pkg/local/app.go @@ -72,24 +72,26 @@ type App struct { pkceAuthenticators map[string]*pkce.Authenticator // map of state to pkce authenticators ch *cmdutil.Helper localURL string + allowedOrigins []string } type AppOptions struct { - Version cmdutil.Version - Verbose bool - Debug bool - Reset bool - Environment string - OlapDriver string - OlapDSN string - ProjectPath string - LogFormat LogFormat - Variables map[string]string - Activity *activity.Client - AdminURL string - AdminToken string - CMDHelper *cmdutil.Helper - LocalURL string + Version cmdutil.Version + Verbose bool + Debug bool + Reset bool + Environment string + OlapDriver string + OlapDSN string + ProjectPath string + LogFormat LogFormat + Variables map[string]string + Activity *activity.Client + AdminURL string + AdminToken string + CMDHelper *cmdutil.Helper + LocalURL string + AllowedOrigins []string } func NewApp(ctx context.Context, opts *AppOptions) (*App, error) { @@ -300,6 +302,7 @@ func NewApp(ctx context.Context, opts *AppOptions) (*App, error) { pkceAuthenticators: make(map[string]*pkce.Authenticator), ch: opts.CMDHelper, localURL: opts.LocalURL, + allowedOrigins: opts.AllowedOrigins, } // Collect and emit information about connectors at start time @@ -377,7 +380,7 @@ func (a *App) Serve(httpPort, grpcPort int, enableUI, openBrowser, readonly bool GRPCPort: grpcPort, TLSCertPath: tlsCertPath, TLSKeyPath: tlsKeyPath, - AllowedOrigins: []string{"*"}, + AllowedOrigins: a.allowedOrigins, ServePrometheus: true, } runtimeServer, err := runtimeserver.NewServer(ctx, opts, a.Runtime, runtimeServerLogger, ratelimit.NewNoop(), a.activity) diff --git a/cli/pkg/local/server.go b/cli/pkg/local/server.go index e73f00a7eed..a4b5b04f0a6 100644 --- a/cli/pkg/local/server.go +++ b/cli/pkg/local/server.go @@ -94,6 +94,7 @@ func (s *Server) GetMetadata(ctx context.Context, r *connect.Request[localv1.Get AnalyticsEnabled: s.metadata.AnalyticsEnabled, Readonly: s.metadata.Readonly, GrpcPort: int32(s.metadata.GRPCPort), + LoginUrl: s.app.localURL + "/auth", }), nil } @@ -674,6 +675,17 @@ func (s *Server) GetCurrentUser(ctx context.Context, r *connect.Request[localv1. return nil, errors.New("failed to get current user") } + // get rill user orgs + resp, err := c.ListOrganizations(ctx, &adminv1.ListOrganizationsRequest{}) + if err != nil { + return nil, err + } + + userOrgs := make([]string, 0, len(resp.Organizations)) + for _, org := range resp.Organizations { + userOrgs = append(userOrgs, org.Name) + } + return connect.NewResponse(&localv1.GetCurrentUserResponse{ User: &adminv1.User{ Id: userResp.User.Id, @@ -681,6 +693,54 @@ func (s *Server) GetCurrentUser(ctx context.Context, r *connect.Request[localv1. DisplayName: userResp.User.DisplayName, PhotoUrl: userResp.User.PhotoUrl, }, + RillUserOrgs: userOrgs, + }), nil +} + +func (s *Server) GetCurrentProject(ctx context.Context, r *connect.Request[localv1.GetCurrentProjectRequest]) (*connect.Response[localv1.GetCurrentProjectResponse], error) { + localProjectName := filepath.Base(s.app.ProjectPath) + + if !s.app.ch.IsAuthenticated() { + // user should be logged in first + return connect.NewResponse(&localv1.GetCurrentProjectResponse{ + LocalProjectName: localProjectName, + }), nil + } + // Get admin client + c, err := client.New(s.app.adminURL, s.app.ch.AdminTokenDefault, "Rill Localhost") + if err != nil { + return nil, err + } + + rc, err := dotrillcloud.GetAll(s.app.ProjectPath, s.app.adminURL) + if err != nil { + return nil, err + } + if rc == nil { + return connect.NewResponse(&localv1.GetCurrentProjectResponse{ + LocalProjectName: localProjectName, + }), nil + } + + var project *adminv1.Project + proj, err := c.GetProjectByID(ctx, &adminv1.GetProjectByIDRequest{ + Id: rc.ProjectID, + }) + if err != nil { + // unset if project doesnt exist + if errors.Is(err, database.ErrNotFound) { + err = dotrillcloud.Delete(s.app.ProjectPath, s.app.adminURL) + if err != nil { + return nil, err + } + } + } else { + project = proj.Project + } + + return connect.NewResponse(&localv1.GetCurrentProjectResponse{ + LocalProjectName: localProjectName, + Project: project, }), nil } diff --git a/package.json b/package.json index f354642e8b8..11e4f998ba9 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "build": "npm run build -w web-local", "dev": "sh -c 'npm run dev-runtime & npm run dev-web & wait'", "dev-web": "npm run dev -w web-local", - "dev-runtime": "go run cli/main.go start dev-project --no-ui", + "dev-runtime": "go run cli/main.go start dev-project --no-ui --allowed-origins http://localhost:3000", "clean": "rm -rf dev-project", "test": "npm run test -w web-common & npm run test -w web-auth & PLAYWRIGHT_TEST=true make cli && npm run test -w web-local" }, diff --git a/proto/gen/rill/local/v1/api.pb.go b/proto/gen/rill/local/v1/api.pb.go index ea1e8706e82..75cbee2ed35 100644 --- a/proto/gen/rill/local/v1/api.pb.go +++ b/proto/gen/rill/local/v1/api.pb.go @@ -161,6 +161,7 @@ type GetMetadataResponse struct { AnalyticsEnabled bool `protobuf:"varint,9,opt,name=analytics_enabled,json=analyticsEnabled,proto3" json:"analytics_enabled,omitempty"` Readonly bool `protobuf:"varint,10,opt,name=readonly,proto3" json:"readonly,omitempty"` GrpcPort int32 `protobuf:"varint,11,opt,name=grpc_port,json=grpcPort,proto3" json:"grpc_port,omitempty"` + LoginUrl string `protobuf:"bytes,12,opt,name=login_url,json=loginUrl,proto3" json:"login_url,omitempty"` } func (x *GetMetadataResponse) Reset() { @@ -272,6 +273,13 @@ func (x *GetMetadataResponse) GetGrpcPort() int32 { return 0 } +func (x *GetMetadataResponse) GetLoginUrl() string { + if x != nil { + return x.LoginUrl + } + return "" +} + type GetVersionRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -967,7 +975,8 @@ type GetCurrentUserResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - User *v1.User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + User *v1.User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + RillUserOrgs []string `protobuf:"bytes,2,rep,name=rill_user_orgs,json=rillUserOrgs,proto3" json:"rill_user_orgs,omitempty"` } func (x *GetCurrentUserResponse) Reset() { @@ -1009,6 +1018,106 @@ func (x *GetCurrentUserResponse) GetUser() *v1.User { return nil } +func (x *GetCurrentUserResponse) GetRillUserOrgs() []string { + if x != nil { + return x.RillUserOrgs + } + return nil +} + +type GetCurrentProjectRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetCurrentProjectRequest) Reset() { + *x = GetCurrentProjectRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_local_v1_api_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetCurrentProjectRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCurrentProjectRequest) ProtoMessage() {} + +func (x *GetCurrentProjectRequest) ProtoReflect() protoreflect.Message { + mi := &file_rill_local_v1_api_proto_msgTypes[16] + 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 GetCurrentProjectRequest.ProtoReflect.Descriptor instead. +func (*GetCurrentProjectRequest) Descriptor() ([]byte, []int) { + return file_rill_local_v1_api_proto_rawDescGZIP(), []int{16} +} + +type GetCurrentProjectResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LocalProjectName string `protobuf:"bytes,1,opt,name=local_project_name,json=localProjectName,proto3" json:"local_project_name,omitempty"` + Project *v1.Project `protobuf:"bytes,2,opt,name=project,proto3" json:"project,omitempty"` +} + +func (x *GetCurrentProjectResponse) Reset() { + *x = GetCurrentProjectResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_local_v1_api_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetCurrentProjectResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCurrentProjectResponse) ProtoMessage() {} + +func (x *GetCurrentProjectResponse) ProtoReflect() protoreflect.Message { + mi := &file_rill_local_v1_api_proto_msgTypes[17] + 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 GetCurrentProjectResponse.ProtoReflect.Descriptor instead. +func (*GetCurrentProjectResponse) Descriptor() ([]byte, []int) { + return file_rill_local_v1_api_proto_rawDescGZIP(), []int{17} +} + +func (x *GetCurrentProjectResponse) GetLocalProjectName() string { + if x != nil { + return x.LocalProjectName + } + return "" +} + +func (x *GetCurrentProjectResponse) GetProject() *v1.Project { + if x != nil { + return x.Project + } + return nil +} + var File_rill_local_v1_api_proto protoreflect.FileDescriptor var file_rill_local_v1_api_proto_rawDesc = []byte{ @@ -1024,7 +1133,7 @@ var file_rill_local_v1_api_proto_rawDesc = []byte{ 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xea, 0x02, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x87, 0x03, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, @@ -1047,180 +1156,200 @@ var file_rill_local_v1_api_proto_rawDesc = []byte{ 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x67, 0x72, 0x70, 0x63, - 0x50, 0x6f, 0x72, 0x74, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x46, 0x0a, 0x12, 0x47, 0x65, 0x74, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x74, - 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, - 0x74, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb7, 0x08, 0x0a, - 0x18, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x73, 0x5f, - 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x75, 0x72, - 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x55, 0x72, - 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x73, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, - 0x69, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x12, 0x35, 0x0a, 0x17, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x67, 0x72, 0x61, 0x6e, - 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x14, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x55, 0x0a, 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x92, 0x01, 0x0a, 0x1f, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x5f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x4a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x55, 0x72, + 0x6c, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x46, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x22, 0x19, + 0x0a, 0x17, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb7, 0x08, 0x0a, 0x18, 0x44, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x73, 0x5f, 0x61, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0f, 0x69, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x2e, + 0x0a, 0x13, 0x69, 0x73, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x73, 0x47, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x35, + 0x0a, 0x17, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x14, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x55, 0x0a, 0x16, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x14, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x92, 0x01, 0x0a, 0x1f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x5f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x4a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x1d, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x69, + 0x73, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x70, + 0x6f, 0x12, 0x33, 0x0a, 0x16, 0x69, 0x73, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x72, + 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x13, 0x69, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x40, 0x0a, 0x1d, 0x69, 0x73, 0x5f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x69, + 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x70, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x55, 0x72, 0x6c, 0x12, 0x3b, 0x0a, 0x17, 0x68, 0x61, 0x73, 0x5f, 0x75, + 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x15, 0x68, 0x61, 0x73, 0x55, + 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x88, 0x01, 0x01, 0x12, 0x4a, 0x0a, 0x23, 0x72, 0x69, 0x6c, 0x6c, 0x5f, 0x6f, 0x72, 0x67, + 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x5f, 0x61, 0x73, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1d, 0x72, 0x69, 0x6c, 0x6c, 0x4f, 0x72, 0x67, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x41, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x69, 0x6c, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6f, 0x72, + 0x67, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x69, 0x6c, 0x6c, 0x55, 0x73, + 0x65, 0x72, 0x4f, 0x72, 0x67, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, + 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x49, 0x64, 0x1a, 0x71, 0x0a, 0x22, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 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, 0x35, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x1a, 0x0a, 0x18, 0x5f, 0x68, 0x61, 0x73, 0x5f, + 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x13, 0x50, 0x75, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, 0x63, 0x0a, 0x14, 0x50, 0x75, 0x73, 0x68, + 0x54, 0x6f, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x72, 0x6c, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, + 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, 0x63, 0x0a, + 0x14, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, + 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x72, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x55, 0x72, 0x6c, 0x22, 0x53, 0x0a, 0x16, 0x52, 0x65, 0x64, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x3c, 0x0a, + 0x17, 0x52, 0x65, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x55, 0x72, 0x6c, 0x22, 0x17, 0x0a, 0x15, 0x47, + 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x67, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, + 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x69, 0x6c, 0x6c, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6f, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0c, 0x72, 0x69, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4f, 0x72, 0x67, 0x73, 0x22, 0x1a, 0x0a, + 0x18, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x7b, 0x0a, 0x19, 0x47, 0x65, 0x74, + 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x32, 0xcd, 0x06, 0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, + 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0b, 0x47, 0x65, + 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x10, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x1d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, - 0x0a, 0x0e, 0x69, 0x73, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x52, 0x65, 0x70, 0x6f, 0x12, 0x33, 0x0a, 0x16, 0x69, 0x73, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x40, 0x0a, 0x1d, 0x69, 0x73, 0x5f, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x19, 0x69, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x70, 0x6f, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x72, 0x6c, 0x12, 0x3b, 0x0a, 0x17, 0x68, 0x61, - 0x73, 0x5f, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x15, 0x68, - 0x61, 0x73, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x88, 0x01, 0x01, 0x12, 0x4a, 0x0a, 0x23, 0x72, 0x69, 0x6c, 0x6c, 0x5f, - 0x6f, 0x72, 0x67, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x5f, 0x61, 0x73, 0x5f, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x72, 0x69, 0x6c, 0x6c, 0x4f, 0x72, 0x67, 0x45, 0x78, 0x69, - 0x73, 0x74, 0x73, 0x41, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x69, 0x6c, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x6f, 0x72, 0x67, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x69, 0x6c, - 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4f, 0x72, 0x67, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x10, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x1a, 0x71, 0x0a, 0x22, 0x47, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 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, - 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x1a, 0x0a, 0x18, 0x5f, 0x68, - 0x61, 0x73, 0x5f, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x63, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x13, 0x50, 0x75, 0x73, 0x68, 0x54, 0x6f, - 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, - 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, 0x63, 0x0a, 0x14, 0x50, - 0x75, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x72, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, - 0x72, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x72, 0x65, 0x70, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, - 0x22, 0x63, 0x0a, 0x14, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, - 0x6f, 0x72, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x72, 0x67, 0x12, 0x18, - 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x55, 0x72, 0x6c, 0x22, 0x53, 0x0a, 0x16, 0x52, - 0x65, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x22, 0x3c, 0x0a, 0x17, 0x52, 0x65, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x66, - 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x55, 0x72, 0x6c, 0x22, 0x17, - 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x41, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x27, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x32, 0xe3, 0x05, 0x0a, 0x0c, 0x4c, - 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x04, 0x50, - 0x69, 0x6e, 0x67, 0x12, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, - 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x10, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, - 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0c, 0x50, 0x75, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, + 0x0a, 0x0c, 0x50, 0x75, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x12, 0x22, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x75, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, - 0x0d, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x23, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x52, - 0x65, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x25, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x5f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, - 0x72, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x42, 0xad, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x41, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, - 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x2f, 0x76, 0x31, 0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, - 0x4c, 0x58, 0xaa, 0x02, 0x0d, 0x52, 0x69, 0x6c, 0x6c, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, - 0x56, 0x31, 0xca, 0x02, 0x0d, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x5c, - 0x56, 0x31, 0xe2, 0x02, 0x19, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x5c, - 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x3a, 0x3a, 0x56, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x0d, 0x44, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x52, 0x65, 0x64, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x0e, 0x47, + 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x24, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x11, + 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xad, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x41, 0x70, + 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, + 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, + 0x6c, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x76, 0x31, 0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x4c, 0x58, 0xaa, 0x02, 0x0d, 0x52, 0x69, 0x6c, 0x6c, 0x2e, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x52, 0x69, 0x6c, 0x6c, 0x5c, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x52, 0x69, 0x6c, 0x6c, 0x5c, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1235,56 +1364,62 @@ func file_rill_local_v1_api_proto_rawDescGZIP() []byte { return file_rill_local_v1_api_proto_rawDescData } -var file_rill_local_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_rill_local_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_rill_local_v1_api_proto_goTypes = []any{ - (*PingRequest)(nil), // 0: rill.local.v1.PingRequest - (*PingResponse)(nil), // 1: rill.local.v1.PingResponse - (*GetMetadataRequest)(nil), // 2: rill.local.v1.GetMetadataRequest - (*GetMetadataResponse)(nil), // 3: rill.local.v1.GetMetadataResponse - (*GetVersionRequest)(nil), // 4: rill.local.v1.GetVersionRequest - (*GetVersionResponse)(nil), // 5: rill.local.v1.GetVersionResponse - (*DeployValidationRequest)(nil), // 6: rill.local.v1.DeployValidationRequest - (*DeployValidationResponse)(nil), // 7: rill.local.v1.DeployValidationResponse - (*PushToGithubRequest)(nil), // 8: rill.local.v1.PushToGithubRequest - (*PushToGithubResponse)(nil), // 9: rill.local.v1.PushToGithubResponse - (*DeployProjectRequest)(nil), // 10: rill.local.v1.DeployProjectRequest - (*DeployProjectResponse)(nil), // 11: rill.local.v1.DeployProjectResponse - (*RedeployProjectRequest)(nil), // 12: rill.local.v1.RedeployProjectRequest - (*RedeployProjectResponse)(nil), // 13: rill.local.v1.RedeployProjectResponse - (*GetCurrentUserRequest)(nil), // 14: rill.local.v1.GetCurrentUserRequest - (*GetCurrentUserResponse)(nil), // 15: rill.local.v1.GetCurrentUserResponse - nil, // 16: rill.local.v1.DeployValidationResponse.GithubOrganizationPermissionsEntry - (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp - (v1.GithubPermission)(0), // 18: rill.admin.v1.GithubPermission - (*v1.User)(nil), // 19: rill.admin.v1.User + (*PingRequest)(nil), // 0: rill.local.v1.PingRequest + (*PingResponse)(nil), // 1: rill.local.v1.PingResponse + (*GetMetadataRequest)(nil), // 2: rill.local.v1.GetMetadataRequest + (*GetMetadataResponse)(nil), // 3: rill.local.v1.GetMetadataResponse + (*GetVersionRequest)(nil), // 4: rill.local.v1.GetVersionRequest + (*GetVersionResponse)(nil), // 5: rill.local.v1.GetVersionResponse + (*DeployValidationRequest)(nil), // 6: rill.local.v1.DeployValidationRequest + (*DeployValidationResponse)(nil), // 7: rill.local.v1.DeployValidationResponse + (*PushToGithubRequest)(nil), // 8: rill.local.v1.PushToGithubRequest + (*PushToGithubResponse)(nil), // 9: rill.local.v1.PushToGithubResponse + (*DeployProjectRequest)(nil), // 10: rill.local.v1.DeployProjectRequest + (*DeployProjectResponse)(nil), // 11: rill.local.v1.DeployProjectResponse + (*RedeployProjectRequest)(nil), // 12: rill.local.v1.RedeployProjectRequest + (*RedeployProjectResponse)(nil), // 13: rill.local.v1.RedeployProjectResponse + (*GetCurrentUserRequest)(nil), // 14: rill.local.v1.GetCurrentUserRequest + (*GetCurrentUserResponse)(nil), // 15: rill.local.v1.GetCurrentUserResponse + (*GetCurrentProjectRequest)(nil), // 16: rill.local.v1.GetCurrentProjectRequest + (*GetCurrentProjectResponse)(nil), // 17: rill.local.v1.GetCurrentProjectResponse + nil, // 18: rill.local.v1.DeployValidationResponse.GithubOrganizationPermissionsEntry + (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp + (v1.GithubPermission)(0), // 20: rill.admin.v1.GithubPermission + (*v1.User)(nil), // 21: rill.admin.v1.User + (*v1.Project)(nil), // 22: rill.admin.v1.Project } var file_rill_local_v1_api_proto_depIdxs = []int32{ - 17, // 0: rill.local.v1.PingResponse.time:type_name -> google.protobuf.Timestamp - 18, // 1: rill.local.v1.DeployValidationResponse.github_user_permission:type_name -> rill.admin.v1.GithubPermission - 16, // 2: rill.local.v1.DeployValidationResponse.github_organization_permissions:type_name -> rill.local.v1.DeployValidationResponse.GithubOrganizationPermissionsEntry - 19, // 3: rill.local.v1.GetCurrentUserResponse.user:type_name -> rill.admin.v1.User - 18, // 4: rill.local.v1.DeployValidationResponse.GithubOrganizationPermissionsEntry.value:type_name -> rill.admin.v1.GithubPermission - 0, // 5: rill.local.v1.LocalService.Ping:input_type -> rill.local.v1.PingRequest - 2, // 6: rill.local.v1.LocalService.GetMetadata:input_type -> rill.local.v1.GetMetadataRequest - 4, // 7: rill.local.v1.LocalService.GetVersion:input_type -> rill.local.v1.GetVersionRequest - 6, // 8: rill.local.v1.LocalService.DeployValidation:input_type -> rill.local.v1.DeployValidationRequest - 8, // 9: rill.local.v1.LocalService.PushToGithub:input_type -> rill.local.v1.PushToGithubRequest - 10, // 10: rill.local.v1.LocalService.DeployProject:input_type -> rill.local.v1.DeployProjectRequest - 12, // 11: rill.local.v1.LocalService.RedeployProject:input_type -> rill.local.v1.RedeployProjectRequest - 14, // 12: rill.local.v1.LocalService.GetCurrentUser:input_type -> rill.local.v1.GetCurrentUserRequest - 1, // 13: rill.local.v1.LocalService.Ping:output_type -> rill.local.v1.PingResponse - 3, // 14: rill.local.v1.LocalService.GetMetadata:output_type -> rill.local.v1.GetMetadataResponse - 5, // 15: rill.local.v1.LocalService.GetVersion:output_type -> rill.local.v1.GetVersionResponse - 7, // 16: rill.local.v1.LocalService.DeployValidation:output_type -> rill.local.v1.DeployValidationResponse - 9, // 17: rill.local.v1.LocalService.PushToGithub:output_type -> rill.local.v1.PushToGithubResponse - 11, // 18: rill.local.v1.LocalService.DeployProject:output_type -> rill.local.v1.DeployProjectResponse - 13, // 19: rill.local.v1.LocalService.RedeployProject:output_type -> rill.local.v1.RedeployProjectResponse - 15, // 20: rill.local.v1.LocalService.GetCurrentUser:output_type -> rill.local.v1.GetCurrentUserResponse - 13, // [13:21] is the sub-list for method output_type - 5, // [5:13] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 19, // 0: rill.local.v1.PingResponse.time:type_name -> google.protobuf.Timestamp + 20, // 1: rill.local.v1.DeployValidationResponse.github_user_permission:type_name -> rill.admin.v1.GithubPermission + 18, // 2: rill.local.v1.DeployValidationResponse.github_organization_permissions:type_name -> rill.local.v1.DeployValidationResponse.GithubOrganizationPermissionsEntry + 21, // 3: rill.local.v1.GetCurrentUserResponse.user:type_name -> rill.admin.v1.User + 22, // 4: rill.local.v1.GetCurrentProjectResponse.project:type_name -> rill.admin.v1.Project + 20, // 5: rill.local.v1.DeployValidationResponse.GithubOrganizationPermissionsEntry.value:type_name -> rill.admin.v1.GithubPermission + 0, // 6: rill.local.v1.LocalService.Ping:input_type -> rill.local.v1.PingRequest + 2, // 7: rill.local.v1.LocalService.GetMetadata:input_type -> rill.local.v1.GetMetadataRequest + 4, // 8: rill.local.v1.LocalService.GetVersion:input_type -> rill.local.v1.GetVersionRequest + 6, // 9: rill.local.v1.LocalService.DeployValidation:input_type -> rill.local.v1.DeployValidationRequest + 8, // 10: rill.local.v1.LocalService.PushToGithub:input_type -> rill.local.v1.PushToGithubRequest + 10, // 11: rill.local.v1.LocalService.DeployProject:input_type -> rill.local.v1.DeployProjectRequest + 12, // 12: rill.local.v1.LocalService.RedeployProject:input_type -> rill.local.v1.RedeployProjectRequest + 14, // 13: rill.local.v1.LocalService.GetCurrentUser:input_type -> rill.local.v1.GetCurrentUserRequest + 16, // 14: rill.local.v1.LocalService.GetCurrentProject:input_type -> rill.local.v1.GetCurrentProjectRequest + 1, // 15: rill.local.v1.LocalService.Ping:output_type -> rill.local.v1.PingResponse + 3, // 16: rill.local.v1.LocalService.GetMetadata:output_type -> rill.local.v1.GetMetadataResponse + 5, // 17: rill.local.v1.LocalService.GetVersion:output_type -> rill.local.v1.GetVersionResponse + 7, // 18: rill.local.v1.LocalService.DeployValidation:output_type -> rill.local.v1.DeployValidationResponse + 9, // 19: rill.local.v1.LocalService.PushToGithub:output_type -> rill.local.v1.PushToGithubResponse + 11, // 20: rill.local.v1.LocalService.DeployProject:output_type -> rill.local.v1.DeployProjectResponse + 13, // 21: rill.local.v1.LocalService.RedeployProject:output_type -> rill.local.v1.RedeployProjectResponse + 15, // 22: rill.local.v1.LocalService.GetCurrentUser:output_type -> rill.local.v1.GetCurrentUserResponse + 17, // 23: rill.local.v1.LocalService.GetCurrentProject:output_type -> rill.local.v1.GetCurrentProjectResponse + 15, // [15:24] is the sub-list for method output_type + 6, // [6:15] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_rill_local_v1_api_proto_init() } @@ -1485,6 +1620,30 @@ func file_rill_local_v1_api_proto_init() { return nil } } + file_rill_local_v1_api_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*GetCurrentProjectRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_local_v1_api_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*GetCurrentProjectResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_rill_local_v1_api_proto_msgTypes[7].OneofWrappers = []any{} type x struct{} @@ -1493,7 +1652,7 @@ func file_rill_local_v1_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rill_local_v1_api_proto_rawDesc, NumEnums: 0, - NumMessages: 17, + NumMessages: 19, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/rill/local/v1/api.pb.gw.go b/proto/gen/rill/local/v1/api.pb.gw.go index d0cc9b863ce..f9cc0095620 100644 --- a/proto/gen/rill/local/v1/api.pb.gw.go +++ b/proto/gen/rill/local/v1/api.pb.gw.go @@ -239,6 +239,32 @@ func local_request_LocalService_GetCurrentUser_0(ctx context.Context, marshaler } +func request_LocalService_GetCurrentProject_0(ctx context.Context, marshaler runtime.Marshaler, client LocalServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetCurrentProjectRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetCurrentProject(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_LocalService_GetCurrentProject_0(ctx context.Context, marshaler runtime.Marshaler, server LocalServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetCurrentProjectRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetCurrentProject(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterLocalServiceHandlerServer registers the http handlers for service LocalService to "mux". // UnaryRPC :call LocalServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -446,6 +472,31 @@ func RegisterLocalServiceHandlerServer(ctx context.Context, mux *runtime.ServeMu }) + mux.Handle("POST", pattern_LocalService_GetCurrentProject_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/rill.local.v1.LocalService/GetCurrentProject", runtime.WithHTTPPathPattern("/rill.local.v1.LocalService/GetCurrentProject")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_LocalService_GetCurrentProject_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LocalService_GetCurrentProject_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -663,6 +714,28 @@ func RegisterLocalServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) + mux.Handle("POST", pattern_LocalService_GetCurrentProject_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/rill.local.v1.LocalService/GetCurrentProject", runtime.WithHTTPPathPattern("/rill.local.v1.LocalService/GetCurrentProject")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_LocalService_GetCurrentProject_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LocalService_GetCurrentProject_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -682,6 +755,8 @@ var ( pattern_LocalService_RedeployProject_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"rill.local.v1.LocalService", "RedeployProject"}, "")) pattern_LocalService_GetCurrentUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"rill.local.v1.LocalService", "GetCurrentUser"}, "")) + + pattern_LocalService_GetCurrentProject_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"rill.local.v1.LocalService", "GetCurrentProject"}, "")) ) var ( @@ -700,4 +775,6 @@ var ( forward_LocalService_RedeployProject_0 = runtime.ForwardResponseMessage forward_LocalService_GetCurrentUser_0 = runtime.ForwardResponseMessage + + forward_LocalService_GetCurrentProject_0 = runtime.ForwardResponseMessage ) diff --git a/proto/gen/rill/local/v1/api.pb.validate.go b/proto/gen/rill/local/v1/api.pb.validate.go index 3a63b6bf3af..ed86c1ff0c8 100644 --- a/proto/gen/rill/local/v1/api.pb.validate.go +++ b/proto/gen/rill/local/v1/api.pb.validate.go @@ -412,6 +412,8 @@ func (m *GetMetadataResponse) validate(all bool) error { // no validation rules for GrpcPort + // no validation rules for LoginUrl + if len(errors) > 0 { return GetMetadataResponseMultiError(errors) } @@ -1810,3 +1812,238 @@ var _ interface { Cause() error ErrorName() string } = GetCurrentUserResponseValidationError{} + +// Validate checks the field values on GetCurrentProjectRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetCurrentProjectRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetCurrentProjectRequest with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetCurrentProjectRequestMultiError, or nil if none found. +func (m *GetCurrentProjectRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetCurrentProjectRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return GetCurrentProjectRequestMultiError(errors) + } + + return nil +} + +// GetCurrentProjectRequestMultiError is an error wrapping multiple validation +// errors returned by GetCurrentProjectRequest.ValidateAll() if the designated +// constraints aren't met. +type GetCurrentProjectRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetCurrentProjectRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetCurrentProjectRequestMultiError) AllErrors() []error { return m } + +// GetCurrentProjectRequestValidationError is the validation error returned by +// GetCurrentProjectRequest.Validate if the designated constraints aren't met. +type GetCurrentProjectRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetCurrentProjectRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetCurrentProjectRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetCurrentProjectRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetCurrentProjectRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetCurrentProjectRequestValidationError) ErrorName() string { + return "GetCurrentProjectRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e GetCurrentProjectRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetCurrentProjectRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetCurrentProjectRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetCurrentProjectRequestValidationError{} + +// Validate checks the field values on GetCurrentProjectResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetCurrentProjectResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetCurrentProjectResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetCurrentProjectResponseMultiError, or nil if none found. +func (m *GetCurrentProjectResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GetCurrentProjectResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for LocalProjectName + + if all { + switch v := interface{}(m.GetProject()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetCurrentProjectResponseValidationError{ + field: "Project", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetCurrentProjectResponseValidationError{ + field: "Project", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetProject()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetCurrentProjectResponseValidationError{ + field: "Project", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return GetCurrentProjectResponseMultiError(errors) + } + + return nil +} + +// GetCurrentProjectResponseMultiError is an error wrapping multiple validation +// errors returned by GetCurrentProjectResponse.ValidateAll() if the +// designated constraints aren't met. +type GetCurrentProjectResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetCurrentProjectResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetCurrentProjectResponseMultiError) AllErrors() []error { return m } + +// GetCurrentProjectResponseValidationError is the validation error returned by +// GetCurrentProjectResponse.Validate if the designated constraints aren't met. +type GetCurrentProjectResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetCurrentProjectResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetCurrentProjectResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetCurrentProjectResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetCurrentProjectResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetCurrentProjectResponseValidationError) ErrorName() string { + return "GetCurrentProjectResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e GetCurrentProjectResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetCurrentProjectResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetCurrentProjectResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetCurrentProjectResponseValidationError{} diff --git a/proto/gen/rill/local/v1/api_grpc.pb.go b/proto/gen/rill/local/v1/api_grpc.pb.go index a6692e36864..8f424b5b79b 100644 --- a/proto/gen/rill/local/v1/api_grpc.pb.go +++ b/proto/gen/rill/local/v1/api_grpc.pb.go @@ -19,14 +19,15 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - LocalService_Ping_FullMethodName = "/rill.local.v1.LocalService/Ping" - LocalService_GetMetadata_FullMethodName = "/rill.local.v1.LocalService/GetMetadata" - LocalService_GetVersion_FullMethodName = "/rill.local.v1.LocalService/GetVersion" - LocalService_DeployValidation_FullMethodName = "/rill.local.v1.LocalService/DeployValidation" - LocalService_PushToGithub_FullMethodName = "/rill.local.v1.LocalService/PushToGithub" - LocalService_DeployProject_FullMethodName = "/rill.local.v1.LocalService/DeployProject" - LocalService_RedeployProject_FullMethodName = "/rill.local.v1.LocalService/RedeployProject" - LocalService_GetCurrentUser_FullMethodName = "/rill.local.v1.LocalService/GetCurrentUser" + LocalService_Ping_FullMethodName = "/rill.local.v1.LocalService/Ping" + LocalService_GetMetadata_FullMethodName = "/rill.local.v1.LocalService/GetMetadata" + LocalService_GetVersion_FullMethodName = "/rill.local.v1.LocalService/GetVersion" + LocalService_DeployValidation_FullMethodName = "/rill.local.v1.LocalService/DeployValidation" + LocalService_PushToGithub_FullMethodName = "/rill.local.v1.LocalService/PushToGithub" + LocalService_DeployProject_FullMethodName = "/rill.local.v1.LocalService/DeployProject" + LocalService_RedeployProject_FullMethodName = "/rill.local.v1.LocalService/RedeployProject" + LocalService_GetCurrentUser_FullMethodName = "/rill.local.v1.LocalService/GetCurrentUser" + LocalService_GetCurrentProject_FullMethodName = "/rill.local.v1.LocalService/GetCurrentProject" ) // LocalServiceClient is the client API for LocalService service. @@ -47,8 +48,10 @@ type LocalServiceClient interface { DeployProject(ctx context.Context, in *DeployProjectRequest, opts ...grpc.CallOption) (*DeployProjectResponse, error) // RedeployProject updates a deployed project. RedeployProject(ctx context.Context, in *RedeployProjectRequest, opts ...grpc.CallOption) (*RedeployProjectResponse, error) - // User returns the locally logged in user + // GetCurrentUser returns the locally logged in user GetCurrentUser(ctx context.Context, in *GetCurrentUserRequest, opts ...grpc.CallOption) (*GetCurrentUserResponse, error) + // GetCurrentProject returns the rill cloud project connected to the local project + GetCurrentProject(ctx context.Context, in *GetCurrentProjectRequest, opts ...grpc.CallOption) (*GetCurrentProjectResponse, error) } type localServiceClient struct { @@ -139,6 +142,16 @@ func (c *localServiceClient) GetCurrentUser(ctx context.Context, in *GetCurrentU return out, nil } +func (c *localServiceClient) GetCurrentProject(ctx context.Context, in *GetCurrentProjectRequest, opts ...grpc.CallOption) (*GetCurrentProjectResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetCurrentProjectResponse) + err := c.cc.Invoke(ctx, LocalService_GetCurrentProject_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // LocalServiceServer is the server API for LocalService service. // All implementations must embed UnimplementedLocalServiceServer // for forward compatibility. @@ -157,8 +170,10 @@ type LocalServiceServer interface { DeployProject(context.Context, *DeployProjectRequest) (*DeployProjectResponse, error) // RedeployProject updates a deployed project. RedeployProject(context.Context, *RedeployProjectRequest) (*RedeployProjectResponse, error) - // User returns the locally logged in user + // GetCurrentUser returns the locally logged in user GetCurrentUser(context.Context, *GetCurrentUserRequest) (*GetCurrentUserResponse, error) + // GetCurrentProject returns the rill cloud project connected to the local project + GetCurrentProject(context.Context, *GetCurrentProjectRequest) (*GetCurrentProjectResponse, error) mustEmbedUnimplementedLocalServiceServer() } @@ -193,6 +208,9 @@ func (UnimplementedLocalServiceServer) RedeployProject(context.Context, *Redeplo func (UnimplementedLocalServiceServer) GetCurrentUser(context.Context, *GetCurrentUserRequest) (*GetCurrentUserResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetCurrentUser not implemented") } +func (UnimplementedLocalServiceServer) GetCurrentProject(context.Context, *GetCurrentProjectRequest) (*GetCurrentProjectResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCurrentProject not implemented") +} func (UnimplementedLocalServiceServer) mustEmbedUnimplementedLocalServiceServer() {} func (UnimplementedLocalServiceServer) testEmbeddedByValue() {} @@ -358,6 +376,24 @@ func _LocalService_GetCurrentUser_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _LocalService_GetCurrentProject_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetCurrentProjectRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LocalServiceServer).GetCurrentProject(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: LocalService_GetCurrentProject_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LocalServiceServer).GetCurrentProject(ctx, req.(*GetCurrentProjectRequest)) + } + return interceptor(ctx, in, info, handler) +} + // LocalService_ServiceDesc is the grpc.ServiceDesc for LocalService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -397,6 +433,10 @@ var LocalService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetCurrentUser", Handler: _LocalService_GetCurrentUser_Handler, }, + { + MethodName: "GetCurrentProject", + Handler: _LocalService_GetCurrentProject_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "rill/local/v1/api.proto", diff --git a/proto/gen/rill/local/v1/localv1connect/api.connect.go b/proto/gen/rill/local/v1/localv1connect/api.connect.go index c068b328182..1d73700fb5f 100644 --- a/proto/gen/rill/local/v1/localv1connect/api.connect.go +++ b/proto/gen/rill/local/v1/localv1connect/api.connect.go @@ -55,19 +55,23 @@ const ( // LocalServiceGetCurrentUserProcedure is the fully-qualified name of the LocalService's // GetCurrentUser RPC. LocalServiceGetCurrentUserProcedure = "/rill.local.v1.LocalService/GetCurrentUser" + // LocalServiceGetCurrentProjectProcedure is the fully-qualified name of the LocalService's + // GetCurrentProject RPC. + LocalServiceGetCurrentProjectProcedure = "/rill.local.v1.LocalService/GetCurrentProject" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. var ( - localServiceServiceDescriptor = v1.File_rill_local_v1_api_proto.Services().ByName("LocalService") - localServicePingMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("Ping") - localServiceGetMetadataMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("GetMetadata") - localServiceGetVersionMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("GetVersion") - localServiceDeployValidationMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("DeployValidation") - localServicePushToGithubMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("PushToGithub") - localServiceDeployProjectMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("DeployProject") - localServiceRedeployProjectMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("RedeployProject") - localServiceGetCurrentUserMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("GetCurrentUser") + localServiceServiceDescriptor = v1.File_rill_local_v1_api_proto.Services().ByName("LocalService") + localServicePingMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("Ping") + localServiceGetMetadataMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("GetMetadata") + localServiceGetVersionMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("GetVersion") + localServiceDeployValidationMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("DeployValidation") + localServicePushToGithubMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("PushToGithub") + localServiceDeployProjectMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("DeployProject") + localServiceRedeployProjectMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("RedeployProject") + localServiceGetCurrentUserMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("GetCurrentUser") + localServiceGetCurrentProjectMethodDescriptor = localServiceServiceDescriptor.Methods().ByName("GetCurrentProject") ) // LocalServiceClient is a client for the rill.local.v1.LocalService service. @@ -86,8 +90,10 @@ type LocalServiceClient interface { DeployProject(context.Context, *connect.Request[v1.DeployProjectRequest]) (*connect.Response[v1.DeployProjectResponse], error) // RedeployProject updates a deployed project. RedeployProject(context.Context, *connect.Request[v1.RedeployProjectRequest]) (*connect.Response[v1.RedeployProjectResponse], error) - // User returns the locally logged in user + // GetCurrentUser returns the locally logged in user GetCurrentUser(context.Context, *connect.Request[v1.GetCurrentUserRequest]) (*connect.Response[v1.GetCurrentUserResponse], error) + // GetCurrentProject returns the rill cloud project connected to the local project + GetCurrentProject(context.Context, *connect.Request[v1.GetCurrentProjectRequest]) (*connect.Response[v1.GetCurrentProjectResponse], error) } // NewLocalServiceClient constructs a client for the rill.local.v1.LocalService service. By default, @@ -148,19 +154,26 @@ func NewLocalServiceClient(httpClient connect.HTTPClient, baseURL string, opts . connect.WithSchema(localServiceGetCurrentUserMethodDescriptor), connect.WithClientOptions(opts...), ), + getCurrentProject: connect.NewClient[v1.GetCurrentProjectRequest, v1.GetCurrentProjectResponse]( + httpClient, + baseURL+LocalServiceGetCurrentProjectProcedure, + connect.WithSchema(localServiceGetCurrentProjectMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } // localServiceClient implements LocalServiceClient. type localServiceClient struct { - ping *connect.Client[v1.PingRequest, v1.PingResponse] - getMetadata *connect.Client[v1.GetMetadataRequest, v1.GetMetadataResponse] - getVersion *connect.Client[v1.GetVersionRequest, v1.GetVersionResponse] - deployValidation *connect.Client[v1.DeployValidationRequest, v1.DeployValidationResponse] - pushToGithub *connect.Client[v1.PushToGithubRequest, v1.PushToGithubResponse] - deployProject *connect.Client[v1.DeployProjectRequest, v1.DeployProjectResponse] - redeployProject *connect.Client[v1.RedeployProjectRequest, v1.RedeployProjectResponse] - getCurrentUser *connect.Client[v1.GetCurrentUserRequest, v1.GetCurrentUserResponse] + ping *connect.Client[v1.PingRequest, v1.PingResponse] + getMetadata *connect.Client[v1.GetMetadataRequest, v1.GetMetadataResponse] + getVersion *connect.Client[v1.GetVersionRequest, v1.GetVersionResponse] + deployValidation *connect.Client[v1.DeployValidationRequest, v1.DeployValidationResponse] + pushToGithub *connect.Client[v1.PushToGithubRequest, v1.PushToGithubResponse] + deployProject *connect.Client[v1.DeployProjectRequest, v1.DeployProjectResponse] + redeployProject *connect.Client[v1.RedeployProjectRequest, v1.RedeployProjectResponse] + getCurrentUser *connect.Client[v1.GetCurrentUserRequest, v1.GetCurrentUserResponse] + getCurrentProject *connect.Client[v1.GetCurrentProjectRequest, v1.GetCurrentProjectResponse] } // Ping calls rill.local.v1.LocalService.Ping. @@ -203,6 +216,11 @@ func (c *localServiceClient) GetCurrentUser(ctx context.Context, req *connect.Re return c.getCurrentUser.CallUnary(ctx, req) } +// GetCurrentProject calls rill.local.v1.LocalService.GetCurrentProject. +func (c *localServiceClient) GetCurrentProject(ctx context.Context, req *connect.Request[v1.GetCurrentProjectRequest]) (*connect.Response[v1.GetCurrentProjectResponse], error) { + return c.getCurrentProject.CallUnary(ctx, req) +} + // LocalServiceHandler is an implementation of the rill.local.v1.LocalService service. type LocalServiceHandler interface { // Ping returns the current time. @@ -219,8 +237,10 @@ type LocalServiceHandler interface { DeployProject(context.Context, *connect.Request[v1.DeployProjectRequest]) (*connect.Response[v1.DeployProjectResponse], error) // RedeployProject updates a deployed project. RedeployProject(context.Context, *connect.Request[v1.RedeployProjectRequest]) (*connect.Response[v1.RedeployProjectResponse], error) - // User returns the locally logged in user + // GetCurrentUser returns the locally logged in user GetCurrentUser(context.Context, *connect.Request[v1.GetCurrentUserRequest]) (*connect.Response[v1.GetCurrentUserResponse], error) + // GetCurrentProject returns the rill cloud project connected to the local project + GetCurrentProject(context.Context, *connect.Request[v1.GetCurrentProjectRequest]) (*connect.Response[v1.GetCurrentProjectResponse], error) } // NewLocalServiceHandler builds an HTTP handler from the service implementation. It returns the @@ -277,6 +297,12 @@ func NewLocalServiceHandler(svc LocalServiceHandler, opts ...connect.HandlerOpti connect.WithSchema(localServiceGetCurrentUserMethodDescriptor), connect.WithHandlerOptions(opts...), ) + localServiceGetCurrentProjectHandler := connect.NewUnaryHandler( + LocalServiceGetCurrentProjectProcedure, + svc.GetCurrentProject, + connect.WithSchema(localServiceGetCurrentProjectMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/rill.local.v1.LocalService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case LocalServicePingProcedure: @@ -295,6 +321,8 @@ func NewLocalServiceHandler(svc LocalServiceHandler, opts ...connect.HandlerOpti localServiceRedeployProjectHandler.ServeHTTP(w, r) case LocalServiceGetCurrentUserProcedure: localServiceGetCurrentUserHandler.ServeHTTP(w, r) + case LocalServiceGetCurrentProjectProcedure: + localServiceGetCurrentProjectHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -335,3 +363,7 @@ func (UnimplementedLocalServiceHandler) RedeployProject(context.Context, *connec func (UnimplementedLocalServiceHandler) GetCurrentUser(context.Context, *connect.Request[v1.GetCurrentUserRequest]) (*connect.Response[v1.GetCurrentUserResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("rill.local.v1.LocalService.GetCurrentUser is not implemented")) } + +func (UnimplementedLocalServiceHandler) GetCurrentProject(context.Context, *connect.Request[v1.GetCurrentProjectRequest]) (*connect.Response[v1.GetCurrentProjectResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("rill.local.v1.LocalService.GetCurrentProject is not implemented")) +} diff --git a/proto/rill/local/v1/api.proto b/proto/rill/local/v1/api.proto index 7951f3f2943..c8e5ebe64c1 100644 --- a/proto/rill/local/v1/api.proto +++ b/proto/rill/local/v1/api.proto @@ -26,8 +26,11 @@ service LocalService { // RedeployProject updates a deployed project. rpc RedeployProject(RedeployProjectRequest) returns (RedeployProjectResponse) {} - // User returns the locally logged in user + // GetCurrentUser returns the locally logged in user rpc GetCurrentUser(GetCurrentUserRequest) returns (GetCurrentUserResponse) {} + + // GetCurrentProject returns the rill cloud project connected to the local project + rpc GetCurrentProject(GetCurrentProjectRequest) returns (GetCurrentProjectResponse) {} } message PingRequest {} @@ -50,6 +53,7 @@ message GetMetadataResponse { bool analytics_enabled = 9; bool readonly = 10; int32 grpc_port = 11; + string login_url = 12; } message GetVersionRequest {} @@ -117,4 +121,12 @@ message GetCurrentUserRequest {} message GetCurrentUserResponse { admin.v1.User user = 1; + repeated string rill_user_orgs = 2; +} + +message GetCurrentProjectRequest {} + +message GetCurrentProjectResponse { + string local_project_name = 1; + admin.v1.Project project = 2; } diff --git a/runtime/drivers/clickhouse/clickhouse.go b/runtime/drivers/clickhouse/clickhouse.go index 65bb4874242..693eaea849e 100644 --- a/runtime/drivers/clickhouse/clickhouse.go +++ b/runtime/drivers/clickhouse/clickhouse.go @@ -329,10 +329,6 @@ func (c *connection) AsNotifier(properties map[string]any) (drivers.Notifier, er return nil, drivers.ErrNotNotifier } -func (c *connection) EstimateSize() (int64, bool) { - return 0, false -} - func (c *connection) AcquireLongRunning(ctx context.Context) (func(), error) { return nil, fmt.Errorf("not implemented") } diff --git a/runtime/drivers/druid/druid.go b/runtime/drivers/druid/druid.go index 5e60db42395..44fd038d784 100644 --- a/runtime/drivers/druid/druid.go +++ b/runtime/drivers/druid/druid.go @@ -257,10 +257,6 @@ func (c *connection) AsNotifier(properties map[string]any) (drivers.Notifier, er return nil, drivers.ErrNotNotifier } -func (c *connection) EstimateSize() (int64, bool) { - return 0, false -} - func (c *connection) AcquireLongRunning(ctx context.Context) (func(), error) { return func() {}, nil } diff --git a/runtime/drivers/duckdb/duckdb.go b/runtime/drivers/duckdb/duckdb.go index 828c9160733..e3007afe7a1 100644 --- a/runtime/drivers/duckdb/duckdb.go +++ b/runtime/drivers/duckdb/duckdb.go @@ -840,7 +840,7 @@ func (c *connection) periodicallyEmitStats(d time.Duration) { for { select { case <-statTicker.C: - estimatedDBSize, _ := c.EstimateSize() + estimatedDBSize := c.estimateSize(false) c.activity.RecordMetric(c.ctx, "duckdb_estimated_size_bytes", float64(estimatedDBSize)) // NOTE :: running CALL pragma_database_size() while duckdb is ingesting data is causing the WAL file to explode. diff --git a/runtime/drivers/duckdb/olap.go b/runtime/drivers/duckdb/olap.go index 81a08740f44..9529924e7b6 100644 --- a/runtime/drivers/duckdb/olap.go +++ b/runtime/drivers/duckdb/olap.go @@ -182,15 +182,16 @@ func (c *connection) Execute(ctx context.Context, stmt *drivers.Statement) (res return res, nil } -func (c *connection) EstimateSize() (int64, bool) { +func (c *connection) estimateSize(includeTemp bool) int64 { path := c.config.DBFilePath if path == "" { - return 0, true + return 0 } - // Add .wal file path (e.g final size will be sum of *.db and *.db.wal) - dbWalPath := fmt.Sprintf("%s.wal", path) - paths := []string{path, dbWalPath} + paths := []string{path} + if includeTemp { + paths = append(paths, fmt.Sprintf("%s.wal", path)) + } if c.config.ExtTableStorage { entries, err := os.ReadDir(c.config.DBStoragePath) if err == nil { // ignore error @@ -198,16 +199,24 @@ func (c *connection) EstimateSize() (int64, bool) { if !entry.IsDir() { continue } + // this is to avoid counting temp tables during source ingestion + // in certain cases we only want to compute the size of the serving db files + if strings.HasPrefix(entry.Name(), "__rill_tmp_") && !includeTemp { + continue + } path := filepath.Join(c.config.DBStoragePath, entry.Name()) version, exist, err := c.tableVersion(entry.Name()) if err != nil || !exist { continue } - paths = append(paths, filepath.Join(path, fmt.Sprintf("%s.db", version)), filepath.Join(path, fmt.Sprintf("%s.db.wal", version))) + paths = append(paths, filepath.Join(path, fmt.Sprintf("%s.db", version))) + if includeTemp { + paths = append(paths, filepath.Join(path, fmt.Sprintf("%s.db.wal", version))) + } } } } - return fileSize(paths), true + return fileSize(paths) } // AddTableColumn implements drivers.OLAPStore. @@ -743,10 +752,8 @@ func (c *connection) execWithLimits(parentCtx context.Context, stmt *drivers.Sta return c.Exec(parentCtx, stmt) } - // check current size - sz, _ := c.EstimateSize() // current size already exceeds limit - if sz >= storageLimit { + if c.estimateSize(true) >= storageLimit { return drivers.ErrStorageLimitExceeded } @@ -762,7 +769,7 @@ func (c *connection) execWithLimits(parentCtx context.Context, stmt *drivers.Sta case <-ctx.Done(): return case <-ticker.C: - if size, ok := c.EstimateSize(); ok && size > storageLimit { + if c.estimateSize(true) > storageLimit { limitExceeded.Store(true) cancel() return diff --git a/runtime/drivers/duckdb/utils.go b/runtime/drivers/duckdb/utils.go index e2e58db3296..0185dc13634 100644 --- a/runtime/drivers/duckdb/utils.go +++ b/runtime/drivers/duckdb/utils.go @@ -266,9 +266,5 @@ func sizeWithinStorageLimits(olap drivers.OLAPStore, size int64) bool { return true } - dbSizeInBytes, ok := olap.EstimateSize() - if ok && dbSizeInBytes+size > limit { - return false - } - return true + return olap.(*connection).estimateSize(true)+size <= limit } diff --git a/runtime/drivers/olap.go b/runtime/drivers/olap.go index 76a10483ec5..224482227f7 100644 --- a/runtime/drivers/olap.go +++ b/runtime/drivers/olap.go @@ -33,7 +33,6 @@ type OLAPStore interface { Exec(ctx context.Context, stmt *Statement) error Execute(ctx context.Context, stmt *Statement) (*Result, error) InformationSchema() InformationSchema - EstimateSize() (int64, bool) CreateTableAsSelect(ctx context.Context, name string, view bool, sql string, tableOpts map[string]any) error InsertTableAsSelect(ctx context.Context, name, sql string, byName, inPlace bool, strategy IncrementalStrategy, uniqueKey []string) error diff --git a/runtime/drivers/pinot/olap.go b/runtime/drivers/pinot/olap.go index 4c9f9aa6fff..0c21f452fe3 100644 --- a/runtime/drivers/pinot/olap.go +++ b/runtime/drivers/pinot/olap.go @@ -52,10 +52,6 @@ func (c *connection) WithConnection(ctx context.Context, priority int, longRunni return fmt.Errorf("pinot: WithConnection not supported") } -func (c *connection) EstimateSize() (int64, bool) { - return 0, false -} - func (c *connection) Exec(ctx context.Context, stmt *drivers.Statement) error { res, err := c.Execute(ctx, stmt) if err != nil { diff --git a/web-admin/src/features/alerts/listing/AlertsTableCompositeCell.svelte b/web-admin/src/features/alerts/listing/AlertsTableCompositeCell.svelte index 8bfe54ed66f..52b947d544d 100644 --- a/web-admin/src/features/alerts/listing/AlertsTableCompositeCell.svelte +++ b/web-admin/src/features/alerts/listing/AlertsTableCompositeCell.svelte @@ -4,6 +4,7 @@ import CheckCircleOutline from "@rilldata/web-common/components/icons/CheckCircleOutline.svelte"; import ProjectAccessControls from "../../projects/ProjectAccessControls.svelte"; import AlertOwnerBullet from "./AlertOwnerBullet.svelte"; + import { timeAgo } from "../../dashboards/listing/utils"; export let organization: string; export let project: string; @@ -34,8 +35,7 @@ {#if !lastTrigger} Hasn't triggered yet {:else} - - Last triggered {lastTrigger} + Last triggered {timeAgo(new Date(lastTrigger))} {/if} diff --git a/web-admin/src/features/projects/github/GithubOverwriteConfirmationDialog.svelte b/web-admin/src/features/projects/github/GithubOverwriteConfirmationDialog.svelte index 0ade0723ca0..877442cb6e2 100644 --- a/web-admin/src/features/projects/github/GithubOverwriteConfirmationDialog.svelte +++ b/web-admin/src/features/projects/github/GithubOverwriteConfirmationDialog.svelte @@ -1,6 +1,6 @@ -
+
diff --git a/web-common/src/features/authentication/LocalAvatarButton.svelte b/web-common/src/features/authentication/LocalAvatarButton.svelte index d9717677088..d6d94d661de 100644 --- a/web-common/src/features/authentication/LocalAvatarButton.svelte +++ b/web-common/src/features/authentication/LocalAvatarButton.svelte @@ -4,24 +4,24 @@ import NoUser from "@rilldata/web-common/components/icons/NoUser.svelte"; import { EntityStatus } from "@rilldata/web-common/features/entity-management/types"; import { - createLocalServiceDeployValidation, createLocalServiceGetCurrentUser, + createLocalServiceGetMetadata, } from "@rilldata/web-common/runtime-client/local-service"; import Spinner from "@rilldata/web-common/features/entity-management/Spinner.svelte"; $: user = createLocalServiceGetCurrentUser(); - $: deployValidation = createLocalServiceDeployValidation(); + $: metadata = createLocalServiceGetMetadata(); - $: loginUrl = `${$deployValidation.data?.loginUrl}/?redirect=${window.location.origin}${window.location.pathname}`; - $: logoutUrl = `${$deployValidation.data?.loginUrl}/logout?redirect=${$page.url.href}`; + $: loginUrl = `${$metadata.data?.loginUrl}/?redirect=${window.location.origin}${window.location.pathname}`; + $: logoutUrl = `${$metadata.data?.loginUrl}/logout?redirect=${$page.url.href}`; $: loggedIn = $user.isSuccess && $user.data?.user; -{#if ($user.isLoading || $deployValidation.isLoading) && !$user.error && !$deployValidation.error} +{#if ($user.isLoading || $metadata.isLoading) && !$user.error && !$metadata.error}
-{:else if $user.data && $deployValidation.data} +{:else if $user.data && $metadata.data} {#if loggedIn} diff --git a/web-common/src/features/dashboards/filters/Filters.svelte b/web-common/src/features/dashboards/filters/Filters.svelte index dc3e88db8b6..b09f297fa56 100644 --- a/web-common/src/features/dashboards/filters/Filters.svelte +++ b/web-common/src/features/dashboards/filters/Filters.svelte @@ -16,6 +16,7 @@ import { useTimeControlStore } from "../time-controls/time-control-store"; import DimensionFilter from "./dimension-filters/DimensionFilter.svelte"; import FilterButton from "./FilterButton.svelte"; + import TimeGrainSelector from "../time-controls/TimeGrainSelector.svelte"; export let readOnly = false; @@ -36,6 +37,7 @@ selectors: { dimensionFilters: { getDimensionFilterItems, getAllDimensionFilterItems }, measureFilters: { getMeasureFilterItems, getAllMeasureFilterItems }, + pivot: { showPivot }, }, } = StateManagers; @@ -47,6 +49,7 @@ allTimeRange, showTimeComparison, selectedComparisonTimeRange, + minTimeGrain, } = $timeControlsStore); $: ({ instanceId } = $runtime); @@ -103,6 +106,9 @@ showTimeComparison={!!showTimeComparison} {selectedComparisonTimeRange} /> + {#if !$showPivot && minTimeGrain} + + {/if} {/if}
{/if} diff --git a/web-common/src/features/dashboards/time-controls/TimeGrainSelector.svelte b/web-common/src/features/dashboards/time-controls/TimeGrainSelector.svelte index abb5145e141..8cb7585db04 100644 --- a/web-common/src/features/dashboards/time-controls/TimeGrainSelector.svelte +++ b/web-common/src/features/dashboards/time-controls/TimeGrainSelector.svelte @@ -1,6 +1,5 @@ - - {#if isDeployed} +{#if isDeployed} + - {:else} + + Push changes to Rill Cloud + + +{:else} + - {/if} - - Deploy this dashboard to Rill Cloud - - + + Deploy this dashboard to Rill Cloud + + +{/if} - + @@ -72,22 +89,36 @@ Deploy this project You’re about to deploy to Rill Cloud, where you can set alerts, - share dashboards, and more. See pricing details + See pricing details + - + + Continue +
+ + diff --git a/web-common/src/features/project/ProjectDeployer.ts b/web-common/src/features/project/ProjectDeployer.ts index 5be6f299cfd..5807e984389 100644 --- a/web-common/src/features/project/ProjectDeployer.ts +++ b/web-common/src/features/project/ProjectDeployer.ts @@ -5,10 +5,16 @@ import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryCl import { waitUntil } from "@rilldata/web-common/lib/waitUtils"; import { behaviourEvent } from "@rilldata/web-common/metrics/initMetrics"; import { BehaviourEventAction } from "@rilldata/web-common/metrics/service/BehaviourEventTypes"; -import type { DeployValidationResponse } from "@rilldata/web-common/proto/gen/rill/local/v1/api_pb"; +import { + GetCurrentProjectResponse, + GetCurrentUserResponse, + GetMetadataResponse, +} from "@rilldata/web-common/proto/gen/rill/local/v1/api_pb"; import { createLocalServiceDeploy, - createLocalServiceDeployValidation, + createLocalServiceGetCurrentProject, + createLocalServiceGetCurrentUser, + createLocalServiceGetMetadata, createLocalServiceRedeploy, getLocalServiceGetCurrentUserQueryKey, localServiceGetCurrentUser, @@ -16,34 +22,42 @@ import { import { derived, get, writable } from "svelte/store"; export class ProjectDeployer { - public readonly validation = createLocalServiceDeployValidation({ - query: { - refetchOnWindowFocus: true, - }, - }); + public readonly metadata = createLocalServiceGetMetadata(); + public readonly user = createLocalServiceGetCurrentUser(); + public readonly project = createLocalServiceGetCurrentProject(); public readonly promptOrgSelection = writable(false); private readonly deployMutation = createLocalServiceDeploy(); private readonly redeployMutation = createLocalServiceRedeploy(); public get isDeployed() { - const validation = get(this.validation).data as DeployValidationResponse; - return !!validation?.deployedProjectId; + const projectResp = get(this.project).data as GetCurrentProjectResponse; + return !!projectResp?.project; } public getStatus() { return derived( - [this.validation, this.deployMutation, this.redeployMutation], - ([validation, deployMutation, redeployMutation]) => { + [ + this.metadata, + this.user, + this.project, + this.deployMutation, + this.redeployMutation, + ], + ([metadata, user, project, deployMutation, redeployMutation]) => { if ( - validation.error || + metadata.error || + user.error || + project.error || deployMutation.error || redeployMutation.error ) { return { isLoading: false, error: extractDeployError( - (validation.error as ConnectError) ?? + (metadata.error as ConnectError) ?? + (user.error as ConnectError) ?? + (project.error as ConnectError) ?? (deployMutation.error as ConnectError) ?? (redeployMutation.error as ConnectError), ).message, @@ -61,48 +75,39 @@ export class ProjectDeployer { ); } - private async validate() { - let validation = get(this.validation).data as DeployValidationResponse; - if (validation?.deployedProjectId) { - return true; - } - - await waitUntil(() => !get(this.validation).isFetching); - validation = get(this.validation).data as DeployValidationResponse; + public async loginOrDeploy() { + await waitUntil( + () => !get(this.metadata).isLoading && !get(this.user).isLoading, + ); - if (!validation.isAuthenticated) { + const metadata = get(this.metadata).data as GetMetadataResponse; + const userResp = get(this.user).data as GetCurrentUserResponse; + if (!userResp.user) { void behaviourEvent?.fireDeployEvent(BehaviourEventAction.LoginStart); window.open( - `${validation.loginUrl}/?redirect=${get(page).url.toString()}`, + `${metadata.loginUrl}/?redirect=${get(page).url.toString()}`, "_self", ); - return false; } else { void behaviourEvent?.fireDeployEvent(BehaviourEventAction.LoginSuccess); } - // Disabling for now. Will support this though "Connect to github" - // if ( - // validation.isGithubRepo && - // (!validation.isGithubConnected || !validation.isGithubRepoAccessGranted) - // ) { - // // if the project is a github repo and not connected to github then redirect to grant access - // window.open(`${validation.githubGrantAccessUrl}`, "_self"); - // return false; - // } - - return true; + return this.deploy(); } public async deploy(org?: string) { - // safeguard around deploy - if (!(await this.validate())) return; + await waitUntil(() => !get(this.project).isLoading); + + const projectResp = get(this.project).data as GetCurrentProjectResponse; + if (projectResp.project) { + if (projectResp.project.githubUrl) { + // we do not support pushing to a project already connected to github + return; + } - const validation = get(this.validation).data as DeployValidationResponse; - if (validation.deployedProjectId) { const resp = await get(this.redeployMutation).mutateAsync({ - projectId: validation.deployedProjectId, - reupload: !validation.isGithubRepo, + projectId: projectResp.project.id, + reupload: true, }); window.open(resp.frontendUrl, "_self"); return; @@ -111,7 +116,7 @@ export class ProjectDeployer { let checkNextOrg = false; if (!org) { const { org: inferredOrg, checkNextOrg: inferredCheckNextOrg } = - await this.inferOrg(validation); + await this.inferOrg(get(this.user).data?.rillUserOrgs ?? []); // no org was inferred. right now this is because we have prompted the user for an org if (!inferredOrg) return; org = inferredOrg; @@ -121,19 +126,18 @@ export class ProjectDeployer { // hardcoded to upload for now const frontendUrl = await this.tryDeployWithOrg( org, - validation.localProjectName, - true, + projectResp.localProjectName, checkNextOrg, ); window.open(frontendUrl + "/-/invite", "_self"); } - private async inferOrg(validation: DeployValidationResponse) { + private async inferOrg(rillUserOrgs: string[]) { let org: string | undefined; let checkNextOrg = false; - if (validation.rillUserOrgs.length === 1) { - org = validation.rillUserOrgs[0]; - } else if (validation.rillUserOrgs.length > 1) { + if (rillUserOrgs.length === 1) { + org = rillUserOrgs[0]; + } else if (rillUserOrgs.length > 1) { this.promptOrgSelection.set(true); } else { const userResp = await queryClient.fetchQuery({ @@ -149,7 +153,6 @@ export class ProjectDeployer { private async tryDeployWithOrg( org: string, projectName: string, - upload: boolean, checkNextOrg: boolean, ) { let i = 0; @@ -160,7 +163,7 @@ export class ProjectDeployer { const resp = await get(this.deployMutation).mutateAsync({ projectName, org: `${org}${i === 0 ? "" : "-" + i}`, - upload, + upload: true, }); void behaviourEvent?.fireDeployEvent( BehaviourEventAction.DeploySuccess, diff --git a/web-common/src/features/project/ProjectTitle.svelte b/web-common/src/features/project/ProjectTitle.svelte index 730b4afd0ac..dc20f87774a 100644 --- a/web-common/src/features/project/ProjectTitle.svelte +++ b/web-common/src/features/project/ProjectTitle.svelte @@ -64,6 +64,7 @@ header { height: var(--header-height); } + .project-square { @apply relative; @apply h-5 aspect-square grid place-items-center rounded; @@ -72,7 +73,7 @@ } .link-wrapper { - @apply flex gap-x-3 items-center flex-none; + @apply flex gap-x-3 items-center flex-none w-full; } .project-link { diff --git a/web-common/src/features/project/PushToGitForDeployDialog.svelte b/web-common/src/features/project/PushToGitForDeployDialog.svelte new file mode 100644 index 00000000000..d3d85175efd --- /dev/null +++ b/web-common/src/features/project/PushToGitForDeployDialog.svelte @@ -0,0 +1,68 @@ + + + + + + + + + To update this deployment, use GitHub + +
+ This project has already been connected to a GitHub repo. Please push + changes directly to GitHub and the project in Rill Cloud will + automatically be updated. + + Learn more -> + +
+
+ + {#if subpath} +
+ subpath + + : /{subpath} + +
+ {/if} +
+
+
+ + + +
+
diff --git a/web-admin/src/features/projects/github/github-utils.ts b/web-common/src/features/project/github-utils.ts similarity index 78% rename from web-admin/src/features/projects/github/github-utils.ts rename to web-common/src/features/project/github-utils.ts index c92221a6ec2..694d3b540b8 100644 --- a/web-admin/src/features/projects/github/github-utils.ts +++ b/web-common/src/features/project/github-utils.ts @@ -1,5 +1,5 @@ export function getRepoNameFromGithubUrl(githubUrl: string) { const repoName = githubUrl.split("github.com/")[1]; // remove trailing forwards slash if present - return repoName?.replace("//$/", "") ?? ""; + return repoName?.replace(/\/$/, "") ?? ""; } diff --git a/web-common/src/proto/gen/rill/local/v1/api_connect.ts b/web-common/src/proto/gen/rill/local/v1/api_connect.ts index 727d65f8565..e6eedd98680 100644 --- a/web-common/src/proto/gen/rill/local/v1/api_connect.ts +++ b/web-common/src/proto/gen/rill/local/v1/api_connect.ts @@ -3,7 +3,7 @@ /* eslint-disable */ // @ts-nocheck -import { DeployProjectRequest, DeployProjectResponse, DeployValidationRequest, DeployValidationResponse, GetCurrentUserRequest, GetCurrentUserResponse, GetMetadataRequest, GetMetadataResponse, GetVersionRequest, GetVersionResponse, PingRequest, PingResponse, PushToGithubRequest, PushToGithubResponse, RedeployProjectRequest, RedeployProjectResponse } from "./api_pb.js"; +import { DeployProjectRequest, DeployProjectResponse, DeployValidationRequest, DeployValidationResponse, GetCurrentProjectRequest, GetCurrentProjectResponse, GetCurrentUserRequest, GetCurrentUserResponse, GetMetadataRequest, GetMetadataResponse, GetVersionRequest, GetVersionResponse, PingRequest, PingResponse, PushToGithubRequest, PushToGithubResponse, RedeployProjectRequest, RedeployProjectResponse } from "./api_pb.js"; import { MethodKind } from "@bufbuild/protobuf"; /** @@ -90,7 +90,7 @@ export const LocalService = { kind: MethodKind.Unary, }, /** - * User returns the locally logged in user + * GetCurrentUser returns the locally logged in user * * @generated from rpc rill.local.v1.LocalService.GetCurrentUser */ @@ -100,6 +100,17 @@ export const LocalService = { O: GetCurrentUserResponse, kind: MethodKind.Unary, }, + /** + * GetCurrentProject returns the rill cloud project connected to the local project + * + * @generated from rpc rill.local.v1.LocalService.GetCurrentProject + */ + getCurrentProject: { + name: "GetCurrentProject", + I: GetCurrentProjectRequest, + O: GetCurrentProjectResponse, + kind: MethodKind.Unary, + }, } } as const; diff --git a/web-common/src/proto/gen/rill/local/v1/api_pb.ts b/web-common/src/proto/gen/rill/local/v1/api_pb.ts index 600554544ab..2ff5632c610 100644 --- a/web-common/src/proto/gen/rill/local/v1/api_pb.ts +++ b/web-common/src/proto/gen/rill/local/v1/api_pb.ts @@ -5,7 +5,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3, Timestamp } from "@bufbuild/protobuf"; -import { GithubPermission, User } from "../../admin/v1/api_pb.js"; +import { GithubPermission, Project, User } from "../../admin/v1/api_pb.js"; /** * @generated from message rill.local.v1.PingRequest @@ -165,6 +165,11 @@ export class GetMetadataResponse extends Message { */ grpcPort = 0; + /** + * @generated from field: string login_url = 12; + */ + loginUrl = ""; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -184,6 +189,7 @@ export class GetMetadataResponse extends Message { { no: 9, name: "analytics_enabled", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, { no: 10, name: "readonly", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, { no: 11, name: "grpc_port", kind: "scalar", T: 5 /* ScalarType.INT32 */ }, + { no: 12, name: "login_url", kind: "scalar", T: 9 /* ScalarType.STRING */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): GetMetadataResponse { @@ -771,6 +777,11 @@ export class GetCurrentUserResponse extends Message { */ user?: User; + /** + * @generated from field: repeated string rill_user_orgs = 2; + */ + rillUserOrgs: string[] = []; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -780,6 +791,7 @@ export class GetCurrentUserResponse extends Message { static readonly typeName = "rill.local.v1.GetCurrentUserResponse"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "user", kind: "message", T: User }, + { no: 2, name: "rill_user_orgs", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): GetCurrentUserResponse { @@ -799,3 +811,77 @@ export class GetCurrentUserResponse extends Message { } } +/** + * @generated from message rill.local.v1.GetCurrentProjectRequest + */ +export class GetCurrentProjectRequest extends Message { + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "rill.local.v1.GetCurrentProjectRequest"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetCurrentProjectRequest { + return new GetCurrentProjectRequest().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetCurrentProjectRequest { + return new GetCurrentProjectRequest().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetCurrentProjectRequest { + return new GetCurrentProjectRequest().fromJsonString(jsonString, options); + } + + static equals(a: GetCurrentProjectRequest | PlainMessage | undefined, b: GetCurrentProjectRequest | PlainMessage | undefined): boolean { + return proto3.util.equals(GetCurrentProjectRequest, a, b); + } +} + +/** + * @generated from message rill.local.v1.GetCurrentProjectResponse + */ +export class GetCurrentProjectResponse extends Message { + /** + * @generated from field: string local_project_name = 1; + */ + localProjectName = ""; + + /** + * @generated from field: rill.admin.v1.Project project = 2; + */ + project?: Project; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "rill.local.v1.GetCurrentProjectResponse"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "local_project_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "project", kind: "message", T: Project }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetCurrentProjectResponse { + return new GetCurrentProjectResponse().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetCurrentProjectResponse { + return new GetCurrentProjectResponse().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetCurrentProjectResponse { + return new GetCurrentProjectResponse().fromJsonString(jsonString, options); + } + + static equals(a: GetCurrentProjectResponse | PlainMessage | undefined, b: GetCurrentProjectResponse | PlainMessage | undefined): boolean { + return proto3.util.equals(GetCurrentProjectResponse, a, b); + } +} + diff --git a/web-common/src/proto/gen/rill/ui/v1/dashboard_pb.ts b/web-common/src/proto/gen/rill/ui/v1/dashboard_pb.ts index 19a3741481a..19d0c0c88df 100644 --- a/web-common/src/proto/gen/rill/ui/v1/dashboard_pb.ts +++ b/web-common/src/proto/gen/rill/ui/v1/dashboard_pb.ts @@ -159,7 +159,7 @@ export class DashboardState extends Message { chartType?: string; /** - * * + * * Pivot related fields * * @generated from field: optional bool pivot_is_active = 22; @@ -360,7 +360,7 @@ proto3.util.setEnumType(DashboardState_LeaderboardSortDirection, "rill.ui.v1.Das ]); /** - * * + * * SortType is used to determine how to sort the leaderboard * and dimension detail table, as well as where to place the * sort arrow. diff --git a/web-common/src/runtime-client/local-service.ts b/web-common/src/runtime-client/local-service.ts index 9d8b9c4b4f8..5f491468321 100644 --- a/web-common/src/runtime-client/local-service.ts +++ b/web-common/src/runtime-client/local-service.ts @@ -5,6 +5,7 @@ import { LocalService } from "@rilldata/web-common/proto/gen/rill/local/v1/api_c import { DeployProjectRequest, DeployValidationRequest, + GetCurrentProjectRequest, GetCurrentUserRequest, GetMetadataRequest, GetVersionRequest, @@ -211,3 +212,28 @@ export function createLocalServiceGetCurrentUser< queryFn: queryOptions?.queryFn ?? localServiceGetCurrentUser, }); } + +export function localServiceGetCurrentProject() { + return getClient().getCurrentProject(new GetCurrentProjectRequest()); +} +export const getLocalServiceGetCurrentProjectQueryKey = () => [ + `/v1/local/get-project`, +]; +export function createLocalServiceGetCurrentProject< + TData = Awaited>, + TError = ConnectError, +>(options?: { + query?: CreateQueryOptions< + Awaited>, + TError, + TData + >; +}) { + const { query: queryOptions } = options ?? {}; + return createQuery({ + ...queryOptions, + queryKey: + queryOptions?.queryKey ?? getLocalServiceGetCurrentProjectQueryKey(), + queryFn: queryOptions?.queryFn ?? localServiceGetCurrentProject, + }); +} diff --git a/web-local/src/routes/(misc)/deploy/+page.svelte b/web-local/src/routes/(misc)/deploy/+page.svelte index 6bad84e4c16..e2ae52363f5 100644 --- a/web-local/src/routes/(misc)/deploy/+page.svelte +++ b/web-local/src/routes/(misc)/deploy/+page.svelte @@ -12,7 +12,9 @@ import Spinner from "@rilldata/web-common/features/entity-management/Spinner.svelte"; const deployer = new ProjectDeployer(); - const deployValidation = deployer.validation; + const metadata = deployer.metadata; + const user = deployer.user; + const project = deployer.project; const deployerStatus = deployer.getStatus(); const promptOrgSelection = deployer.promptOrgSelection; @@ -26,15 +28,21 @@ // } onMount(() => { - void deployer.deploy(); + void deployer.loginOrDeploy(); }); + + + + {#if $promptOrgSelection} {:else if $deployerStatus.isLoading}