diff --git a/api/v1alpha1/utils.go b/api/v1alpha1/utils.go index 855cf0a8..f8aba517 100644 --- a/api/v1alpha1/utils.go +++ b/api/v1alpha1/utils.go @@ -1,5 +1,17 @@ package v1alpha1 +import ( + "fmt" + "reflect" + "slices" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/utils/ptr" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" +) + // LabelControllerManaged is a label on all resources managed by the controllers const LabelControllerManaged = "cosmo-workspace.github.io/controller-managed" @@ -37,6 +49,35 @@ func KeepResourceDeletePolicy(obj AnnotationHolder) bool { return v == ResourceAnnEnumDeletePolicyKeep } +func SetOwnerReferenceIfNotKeepPolicy(owner metav1.Object, obj metav1.Object, scheme *runtime.Scheme) error { + if !KeepResourceDeletePolicy(owner) && !KeepResourceDeletePolicy(obj) { + // Set owner reference + err := ctrl.SetControllerReference(owner, obj, scheme) + if err != nil { + return fmt.Errorf("failed to set owner reference on %s: %w", obj.(runtime.Object).GetObjectKind().GroupVersionKind(), err) + } + return nil + + } else { + // Remove owner reference + if len(obj.GetOwnerReferences()) > 0 { + gvk, _ := apiutil.GVKForObject(owner.(runtime.Object), scheme) + refs := slices.DeleteFunc(obj.GetOwnerReferences(), func(v metav1.OwnerReference) bool { + return reflect.DeepEqual(v, metav1.OwnerReference{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, + Name: owner.GetName(), + UID: owner.GetUID(), + Controller: ptr.To(true), + BlockOwnerDeletion: ptr.To(true), + }) + }) + obj.SetOwnerReferences(refs) + } + return nil + } +} + const ( EventAnnKeyUserName = "cosmo-workspace.github.io/user" EventAnnKeyInstanceName = LabelKeyInstanceName diff --git a/internal/cmd/user/get.go b/internal/cmd/user/get.go index d1d2db9d..b1954d1c 100644 --- a/internal/cmd/user/get.go +++ b/internal/cmd/user/get.go @@ -226,6 +226,14 @@ func printAddonWithVars(addons []*dashv1alpha1.UserAddon) string { return strings.Join(arr, " ") } +func printDeletePolicy(deletePolicy *dashv1alpha1.DeletePolicy) string { + if deletePolicy != nil { + return deletePolicy.String() + } else { + return dashv1alpha1.DeletePolicy_delete.String() + } +} + func OutputTable(out io.Writer, users []*dashv1alpha1.User) { data := [][]string{} @@ -242,11 +250,11 @@ func OutputWideTable(out io.Writer, users []*dashv1alpha1.User) { data := [][]string{} for _, v := range users { - data = append(data, []string{v.Name, v.DisplayName, strings.Join(v.Roles, ","), v.AuthType, cosmov1alpha1.UserNamespace(v.Name), v.Status, printAddonWithVars(v.Addons)}) + data = append(data, []string{v.Name, v.DisplayName, strings.Join(v.Roles, ","), v.AuthType, cosmov1alpha1.UserNamespace(v.Name), v.Status, printDeletePolicy(v.DeletePolicy), printAddonWithVars(v.Addons)}) } cli.OutputTable(out, - []string{"NAME", "DISPLAYNAME", "ROLES", "AUTHTYPE", "NAMESPACE", "PHASE", "ADDONS"}, + []string{"NAME", "DISPLAYNAME", "ROLES", "AUTHTYPE", "NAMESPACE", "PHASE", "DELETEPOLOCY", "ADDONS"}, data) } diff --git a/internal/cmd/user/update.go b/internal/cmd/user/update.go index 0b20c051..59d372ff 100644 --- a/internal/cmd/user/update.go +++ b/internal/cmd/user/update.go @@ -21,5 +21,10 @@ func UpdateCmd(cmd *cobra.Command, o *cli.RootOptions) *cobra.Command { Aliases: []string{"addon", "useraddon", "user-addon"}, Short: "Update addon", }, o)) + cmd.AddCommand(UpdateDeletePolicyCmd(&cobra.Command{ + Use: "deletepolicy USER_NAME [delete|keep]", + Aliases: []string{"delete-policy"}, + Short: "Update delete polocy", + }, o)) return cmd } diff --git a/internal/cmd/user/update_deletepolicy.go b/internal/cmd/user/update_deletepolicy.go new file mode 100644 index 00000000..faef6095 --- /dev/null +++ b/internal/cmd/user/update_deletepolicy.go @@ -0,0 +1,122 @@ +package user + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/fatih/color" + "github.com/spf13/cobra" + "k8s.io/utils/ptr" + + "github.com/cosmo-workspace/cosmo/pkg/apiconv" + "github.com/cosmo-workspace/cosmo/pkg/cli" + "github.com/cosmo-workspace/cosmo/pkg/clog" + "github.com/cosmo-workspace/cosmo/pkg/kosmo" + dashv1alpha1 "github.com/cosmo-workspace/cosmo/proto/gen/dashboard/v1alpha1" +) + +type UpdateDeletePolicyOption struct { + *cli.RootOptions + + UserName string + DeletePolicy string +} + +func UpdateDeletePolicyCmd(cmd *cobra.Command, cliOpt *cli.RootOptions) *cobra.Command { + o := &UpdateDeletePolicyOption{RootOptions: cliOpt} + cmd.RunE = cli.ConnectErrorHandler(o) + return cmd +} + +func (o *UpdateDeletePolicyOption) Validate(cmd *cobra.Command, args []string) error { + if err := o.RootOptions.Validate(cmd, args); err != nil { + return err + } + if len(args) < 2 { + return errors.New("invalid args") + } + return nil +} + +func (o *UpdateDeletePolicyOption) Complete(cmd *cobra.Command, args []string) error { + if err := o.RootOptions.Complete(cmd, args); err != nil { + return err + } + + o.UserName = args[0] + o.DeletePolicy = args[1] + + cmd.SilenceErrors = true + cmd.SilenceUsage = true + return nil +} + +func (o *UpdateDeletePolicyOption) RunE(cmd *cobra.Command, args []string) error { + if err := o.Validate(cmd, args); err != nil { + return fmt.Errorf("validation error: %w", err) + } + if err := o.Complete(cmd, args); err != nil { + return fmt.Errorf("invalid options: %w", err) + } + + ctx, cancel := context.WithTimeout(o.Ctx, time.Second*10) + defer cancel() + ctx = clog.IntoContext(ctx, o.Logr) + + o.Logr.Info("updating user delete polocy", "userName", o.UserName, "deletepolicy", o.DeletePolicy) + + var ( + user *dashv1alpha1.User + err error + ) + if o.UseKubeAPI { + user, err = o.UpdateUserDeletePolicyWithKubeClient(ctx) + } else { + user, err = o.UpdateUserDeletePolicyWithDashClient(ctx) + } + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), color.GreenString("Successfully updated user %s", o.UserName)) + OutputWideTable(cmd.OutOrStdout(), []*dashv1alpha1.User{user}) + + return nil +} + +func (o *UpdateDeletePolicyOption) UpdateUserDeletePolicyWithDashClient(ctx context.Context) (*dashv1alpha1.User, error) { + delPolicy := apiconv.C2D_DeletePolicy(o.DeletePolicy) + if delPolicy == nil { + delPolicy = ptr.To(dashv1alpha1.DeletePolicy_delete) + } + + req := &dashv1alpha1.UpdateUserDeletePolicyRequest{ + UserName: o.UserName, + DeletePolicy: *delPolicy, + } + o.Logr.DebugAll().Info("UserServiceClient.UpdateUserDeletePolicy", "req", req) + c := o.CosmoDashClient + res, err := c.UserServiceClient.UpdateUserDeletePolicy(ctx, cli.NewRequestWithToken(req, o.CliConfig)) + if err != nil { + return nil, fmt.Errorf("failed to connect dashboard server: %w", err) + } + o.Logr.DebugAll().Info("UserServiceClient.UpdateUserDeletePolicy", "res", res) + + return res.Msg.User, nil +} + +func (o *UpdateDeletePolicyOption) UpdateUserDeletePolicyWithKubeClient(ctx context.Context) (*dashv1alpha1.User, error) { + c := o.KosmoClient + opts := kosmo.UpdateUserOpts{ + DeletePolicy: &o.DeletePolicy, + } + o.Logr.DebugAll().Info("UpdateUser", "opts", opts) + user, err := c.UpdateUser(ctx, o.UserName, opts) + if err != nil { + return nil, err + } + d := apiconv.C2D_User(*user) + + return d, nil +} diff --git a/internal/cmd/user/update_display_name.go b/internal/cmd/user/update_display_name.go index 8ba8c1aa..fc905374 100644 --- a/internal/cmd/user/update_display_name.go +++ b/internal/cmd/user/update_display_name.go @@ -29,8 +29,6 @@ type UpdateDisplayNameOption struct { func UpdateDisplayNameCmd(cmd *cobra.Command, cliOpt *cli.RootOptions) *cobra.Command { o := &UpdateDisplayNameOption{RootOptions: cliOpt} cmd.RunE = cli.ConnectErrorHandler(o) - cmd.Flags().StringVar(&o.DisplayName, "display-name", "", "user display name (Required)") - cmd.MarkFlagRequired("display-name") cmd.Flags().BoolVar(&o.Force, "force", false, "not ask confirmation") return cmd } @@ -39,7 +37,7 @@ func (o *UpdateDisplayNameOption) Validate(cmd *cobra.Command, args []string) er if err := o.RootOptions.Validate(cmd, args); err != nil { return err } - if len(args) < 1 { + if len(args) < 2 { return errors.New("invalid args") } return nil @@ -51,6 +49,7 @@ func (o *UpdateDisplayNameOption) Complete(cmd *cobra.Command, args []string) er } o.UserName = args[0] + o.DisplayName = args[1] cmd.SilenceErrors = true cmd.SilenceUsage = true diff --git a/internal/cmd/workspace/get.go b/internal/cmd/workspace/get.go index 2333d1af..54011ece 100644 --- a/internal/cmd/workspace/get.go +++ b/internal/cmd/workspace/get.go @@ -237,22 +237,38 @@ func OutputWideTable(out io.Writer, username string, workspaces []*dashv1alpha1. data := [][]string{} for _, v := range workspaces { - mainURL := v.Status.MainUrl - if v.OwnerName != username { - mainURL = `[shared workspace. see shared URLs by "cosmoctl ws get-network"]` - } - vars := make([]string, 0, len(v.Spec.Vars)) - for k, vv := range v.Spec.Vars { - vars = append(vars, fmt.Sprintf("%s=%s", k, vv)) - } - data = append(data, []string{v.OwnerName, v.Name, v.Spec.Template, strings.Join(vars, ","), v.Status.Phase, mainURL}) + data = append(data, []string{v.OwnerName, v.Name, v.Spec.Template, printVars(v.Spec.Vars), v.Status.Phase, printDeletePolicy(v.DeletePolicy), printMainURL(v, username)}) } cli.OutputTable(out, - []string{"USER", "NAME", "TEMPLATE", "VARS", "PHASE", "MAINURL"}, + []string{"USER", "NAME", "TEMPLATE", "VARS", "PHASE", "DELETEPOLICY", "MAINURL"}, data) } +func printMainURL(v *dashv1alpha1.Workspace, username string) string { + mainURL := v.Status.MainUrl + if v.OwnerName != username { + mainURL = `[shared workspace. see shared URLs by "cosmoctl ws get-network"]` + } + return mainURL +} + +func printVars(vars map[string]string) string { + varSlice := make([]string, 0, len(vars)) + for k, vv := range vars { + varSlice = append(varSlice, fmt.Sprintf("%s=%s", k, vv)) + } + return strings.Join(varSlice, ",") +} + +func printDeletePolicy(deletePolicy *dashv1alpha1.DeletePolicy) string { + if deletePolicy != nil { + return deletePolicy.String() + } else { + return dashv1alpha1.DeletePolicy_delete.String() + } +} + func (o *GetOption) listWorkspacesByKubeClient(ctx context.Context, userName string, includeShared bool) ([]*dashv1alpha1.Workspace, error) { c := o.KosmoClient workspaces, err := c.ListWorkspacesByUserName(ctx, userName, func(o *kosmo.ListWorkspacesOptions) { diff --git a/internal/cmd/workspace/suspend.go b/internal/cmd/workspace/suspend.go index 0d22c315..4e467a5b 100644 --- a/internal/cmd/workspace/suspend.go +++ b/internal/cmd/workspace/suspend.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strings" "time" "github.com/fatih/color" @@ -21,6 +22,7 @@ type SuspendOption struct { WorkspaceNames []string UserName string + Force bool } func SuspendCmd(cmd *cobra.Command, cliOpt *cli.RootOptions) *cobra.Command { @@ -29,6 +31,7 @@ func SuspendCmd(cmd *cobra.Command, cliOpt *cli.RootOptions) *cobra.Command { cmd.RunE = cli.ConnectErrorHandler(o) cmd.Flags().StringVarP(&o.UserName, "user", "u", "", "user name (defualt: login user)") + cmd.Flags().BoolVar(&o.Force, "force", false, "not ask confirmation") return cmd } @@ -69,6 +72,25 @@ func (o *SuspendOption) RunE(cmd *cobra.Command, args []string) error { return fmt.Errorf("invalid options: %w", err) } + o.Logr.Info("suspend workspaces", "workspaces", o.WorkspaceNames) + + if !o.Force { + AskLoop: + for { + input, err := cli.AskInput("Confirm? [y/n] ", false) + if err != nil { + return err + } + switch strings.ToLower(input) { + case "y": + break AskLoop + case "n": + fmt.Println("canceled") + return nil + } + } + } + ctx, cancel := context.WithTimeout(o.Ctx, time.Second*10) defer cancel() ctx = clog.IntoContext(ctx, o.Logr) diff --git a/internal/cmd/workspace/update.go b/internal/cmd/workspace/update.go index 0dd1f596..5e434475 100644 --- a/internal/cmd/workspace/update.go +++ b/internal/cmd/workspace/update.go @@ -1,191 +1,20 @@ package workspace import ( - "context" - "errors" - "fmt" - "strings" - "time" - - "github.com/fatih/color" "github.com/spf13/cobra" - "github.com/cosmo-workspace/cosmo/pkg/apiconv" "github.com/cosmo-workspace/cosmo/pkg/cli" - "github.com/cosmo-workspace/cosmo/pkg/clog" - "github.com/cosmo-workspace/cosmo/pkg/kosmo" - dashv1alpha1 "github.com/cosmo-workspace/cosmo/proto/gen/dashboard/v1alpha1" ) -type UpdateOption struct { - *cli.RootOptions - - WorkspaceName string - UserName string - TemplateVars []string - Force bool - - vars map[string]string -} - -func UpdateCmd(cmd *cobra.Command, cliOpt *cli.RootOptions) *cobra.Command { - o := &UpdateOption{RootOptions: cliOpt} - cmd.RunE = cli.ConnectErrorHandler(o) - cmd.Flags().StringVarP(&o.UserName, "user", "u", "", "user name (defualt: login user)") - cmd.Flags().StringSliceVar(&o.TemplateVars, "set", []string{}, "template vars. the format is VarName=VarValue (example: --set VAR1=VAL1 --set VAR2=VAL2)") - cmd.Flags().BoolVar(&o.Force, "force", false, "not ask confirmation") - +func UpdateCmd(cmd *cobra.Command, o *cli.RootOptions) *cobra.Command { + cmd.AddCommand(UpdateVarsCmd(&cobra.Command{ + Use: "vars WORKSPACE_NAME", + Short: "Update workspace vars", + }, o)) + cmd.AddCommand(UpdateDeletePolicyCmd(&cobra.Command{ + Use: "deletepolicy WORKSPACE_NAME [delete|keep]", + Aliases: []string{"delete-policy"}, + Short: "Update delete polocy", + }, o)) return cmd } - -func (o *UpdateOption) Validate(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return errors.New("invalid args") - } - if o.UseKubeAPI && o.UserName == "" { - return fmt.Errorf("user name is required") - } - return nil -} - -func (o *UpdateOption) Complete(cmd *cobra.Command, args []string) error { - if err := o.RootOptions.Complete(cmd, args); err != nil { - return err - } - o.WorkspaceName = args[0] - - if !o.UseKubeAPI && o.UserName == "" { - o.UserName = o.CliConfig.User - } - - if len(o.TemplateVars) > 0 { - vars := make(map[string]string) - for _, v := range o.TemplateVars { - varAndVal := strings.Split(v, "=") - if len(varAndVal) != 2 { - return fmt.Errorf("vars format error: vars %s must be 'VAR=VAL'", v) - } - vars[varAndVal[0]] = varAndVal[1] - } - o.vars = vars - } - - cmd.SilenceErrors = true - cmd.SilenceUsage = true - return nil -} - -func (o *UpdateOption) RunE(cmd *cobra.Command, args []string) error { - if err := o.Validate(cmd, args); err != nil { - return fmt.Errorf("validation error: %w", err) - } - if err := o.Complete(cmd, args); err != nil { - return fmt.Errorf("invalid options: %w", err) - } - - ctx, cancel := context.WithTimeout(o.Ctx, time.Second*10) - defer cancel() - ctx = clog.IntoContext(ctx, o.Logr) - - var ( - currentWs *dashv1alpha1.Workspace - err error - ) - if o.UseKubeAPI { - currentWs, err = o.GetWorkspaceWithKubeClient(ctx) - } else { - currentWs, err = o.GetWorkspaceWithDashClient(ctx) - } - if err != nil { - return err - } - - o.Logr.Info("updating workspace", "user", o.UserName, "name", o.WorkspaceName, "currentVars", currentWs.Spec.Vars, "newVars", o.vars) - - if !o.Force { - AskLoop: - for { - input, err := cli.AskInput("Confirm? [y/n] ", false) - if err != nil { - return err - } - switch strings.ToLower(input) { - case "y": - break AskLoop - case "n": - fmt.Println("canceled") - return nil - } - } - } - - var ws *dashv1alpha1.Workspace - if o.UseKubeAPI { - ws, err = o.UpdateWorkspaceWithKubeClient(ctx) - } else { - ws, err = o.UpdateWorkspaceWithDashClient(ctx) - } - if err != nil { - return err - } - - fmt.Fprintln(cmd.OutOrStdout(), color.GreenString("Successfully updated workspace %s", o.WorkspaceName)) - OutputTable(cmd.OutOrStdout(), o.UserName, []*dashv1alpha1.Workspace{ws}) - - return nil -} - -func (o *UpdateOption) UpdateWorkspaceWithDashClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { - req := &dashv1alpha1.UpdateWorkspaceRequest{ - WsName: o.WorkspaceName, - UserName: o.UserName, - Vars: o.vars, - } - c := o.CosmoDashClient - o.Logr.DebugAll().Info("WorkspaceServiceClient.UpdateWorkspace", "req", req) - res, err := c.WorkspaceServiceClient.UpdateWorkspace(ctx, cli.NewRequestWithToken(req, o.CliConfig)) - if err != nil { - return nil, fmt.Errorf("failed to connect dashboard server: %w", err) - } - o.Logr.DebugAll().Info("WorkspaceServiceClient.UpdateWorkspace", "res", res) - - return res.Msg.Workspace, nil -} - -func (o *UpdateOption) UpdateWorkspaceWithKubeClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { - opts := kosmo.UpdateWorkspaceOpts{ - Vars: o.vars, - } - c := o.KosmoClient - o.Logr.DebugAll().Info("UpdateWorkspace", "userName", o.UserName, "workspaceName", o.WorkspaceName, "opts", opts) - ws, err := c.UpdateWorkspace(ctx, o.UserName, o.WorkspaceName, opts) - if err != nil { - return nil, err - } - return apiconv.C2D_Workspace(*ws), nil -} - -func (o *UpdateOption) GetWorkspaceWithDashClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { - req := &dashv1alpha1.GetWorkspaceRequest{ - WsName: o.WorkspaceName, - UserName: o.UserName, - } - c := o.CosmoDashClient - o.Logr.DebugAll().Info("WorkspaceServiceClient.GetWorkspace", "req", req) - res, err := c.WorkspaceServiceClient.GetWorkspace(ctx, cli.NewRequestWithToken(req, o.CliConfig)) - if err != nil { - return nil, fmt.Errorf("failed to connect dashboard server: %w", err) - } - o.Logr.DebugAll().Info("WorkspaceServiceClient.GetWorkspace", "res", res) - - return res.Msg.Workspace, nil -} - -func (o *UpdateOption) GetWorkspaceWithKubeClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { - c := o.KosmoClient - ws, err := c.GetWorkspace(ctx, o.UserName, o.WorkspaceName) - if err != nil { - return nil, err - } - return apiconv.C2D_Workspace(*ws), nil -} diff --git a/internal/cmd/workspace/update_deletepolicy.go b/internal/cmd/workspace/update_deletepolicy.go new file mode 100644 index 00000000..4241350b --- /dev/null +++ b/internal/cmd/workspace/update_deletepolicy.go @@ -0,0 +1,121 @@ +package workspace + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/fatih/color" + "github.com/spf13/cobra" + + "github.com/cosmo-workspace/cosmo/pkg/apiconv" + "github.com/cosmo-workspace/cosmo/pkg/cli" + "github.com/cosmo-workspace/cosmo/pkg/clog" + "github.com/cosmo-workspace/cosmo/pkg/kosmo" + dashv1alpha1 "github.com/cosmo-workspace/cosmo/proto/gen/dashboard/v1alpha1" +) + +type UpdateDeletePolicyOption struct { + *cli.RootOptions + + WorkspaceName string + UserName string + DeletePolicy string +} + +func UpdateDeletePolicyCmd(cmd *cobra.Command, cliOpt *cli.RootOptions) *cobra.Command { + o := &UpdateDeletePolicyOption{RootOptions: cliOpt} + cmd.RunE = cli.ConnectErrorHandler(o) + cmd.Flags().StringVarP(&o.UserName, "user", "u", "", "user name (defualt: login user)") + return cmd +} + +func (o *UpdateDeletePolicyOption) Validate(cmd *cobra.Command, args []string) error { + if err := o.RootOptions.Validate(cmd, args); err != nil { + return err + } + if len(args) < 2 { + return errors.New("invalid args") + } + return nil +} + +func (o *UpdateDeletePolicyOption) Complete(cmd *cobra.Command, args []string) error { + if err := o.RootOptions.Complete(cmd, args); err != nil { + return err + } + + o.WorkspaceName = args[0] + o.DeletePolicy = args[1] + + if !o.UseKubeAPI && o.UserName == "" { + o.UserName = o.CliConfig.User + } + + cmd.SilenceErrors = true + cmd.SilenceUsage = true + return nil +} + +func (o *UpdateDeletePolicyOption) RunE(cmd *cobra.Command, args []string) error { + if err := o.Validate(cmd, args); err != nil { + return fmt.Errorf("validation error: %w", err) + } + if err := o.Complete(cmd, args); err != nil { + return fmt.Errorf("invalid options: %w", err) + } + + ctx, cancel := context.WithTimeout(o.Ctx, time.Second*10) + defer cancel() + ctx = clog.IntoContext(ctx, o.Logr) + + o.Logr.Info("updating delete polocy", "workspace", o.WorkspaceName, "userName", o.UserName, "deletepolicy", o.DeletePolicy) + + var ( + ws *dashv1alpha1.Workspace + err error + ) + if o.UseKubeAPI { + ws, err = o.UpdateWorkspaceWithKubeClient(ctx) + } else { + ws, err = o.UpdateWorkspaceWithDashClient(ctx) + } + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), color.GreenString("Successfully updated workspace %s", o.UserName)) + OutputWideTable(cmd.OutOrStdout(), o.UserName, []*dashv1alpha1.Workspace{ws}) + + return nil +} + +func (o *UpdateDeletePolicyOption) UpdateWorkspaceWithDashClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { + req := &dashv1alpha1.UpdateWorkspaceRequest{ + WsName: o.WorkspaceName, + UserName: o.UserName, + DeletePolicy: apiconv.C2D_DeletePolicy(o.DeletePolicy), + } + c := o.CosmoDashClient + o.Logr.DebugAll().Info("WorkspaceServiceClient.UpdateWorkspace", "req", req) + res, err := c.WorkspaceServiceClient.UpdateWorkspace(ctx, cli.NewRequestWithToken(req, o.CliConfig)) + if err != nil { + return nil, fmt.Errorf("failed to connect dashboard server: %w", err) + } + o.Logr.DebugAll().Info("WorkspaceServiceClient.UpdateWorkspace", "res", res) + + return res.Msg.Workspace, nil +} + +func (o *UpdateDeletePolicyOption) UpdateWorkspaceWithKubeClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { + opts := kosmo.UpdateWorkspaceOpts{ + DeletePolicy: &o.DeletePolicy, + } + c := o.KosmoClient + o.Logr.DebugAll().Info("UpdateWorkspace", "userName", o.UserName, "workspaceName", o.WorkspaceName, "opts", opts) + ws, err := c.UpdateWorkspace(ctx, o.UserName, o.WorkspaceName, opts) + if err != nil { + return nil, err + } + return apiconv.C2D_Workspace(*ws), nil +} diff --git a/internal/cmd/workspace/update_vars.go b/internal/cmd/workspace/update_vars.go new file mode 100644 index 00000000..79412220 --- /dev/null +++ b/internal/cmd/workspace/update_vars.go @@ -0,0 +1,191 @@ +package workspace + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + "github.com/fatih/color" + "github.com/spf13/cobra" + + "github.com/cosmo-workspace/cosmo/pkg/apiconv" + "github.com/cosmo-workspace/cosmo/pkg/cli" + "github.com/cosmo-workspace/cosmo/pkg/clog" + "github.com/cosmo-workspace/cosmo/pkg/kosmo" + dashv1alpha1 "github.com/cosmo-workspace/cosmo/proto/gen/dashboard/v1alpha1" +) + +type UpdateVarsOption struct { + *cli.RootOptions + + WorkspaceName string + UserName string + TemplateVars []string + Force bool + + vars map[string]string +} + +func UpdateVarsCmd(cmd *cobra.Command, cliOpt *cli.RootOptions) *cobra.Command { + o := &UpdateVarsOption{RootOptions: cliOpt} + cmd.RunE = cli.ConnectErrorHandler(o) + cmd.Flags().StringVarP(&o.UserName, "user", "u", "", "user name (defualt: login user)") + cmd.Flags().StringSliceVar(&o.TemplateVars, "set", []string{}, "template vars. the format is VarName=VarValue (example: --set VAR1=VAL1 --set VAR2=VAL2)") + cmd.Flags().BoolVar(&o.Force, "force", false, "not ask confirmation") + + return cmd +} + +func (o *UpdateVarsOption) Validate(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("invalid args") + } + if o.UseKubeAPI && o.UserName == "" { + return fmt.Errorf("user name is required") + } + return nil +} + +func (o *UpdateVarsOption) Complete(cmd *cobra.Command, args []string) error { + if err := o.RootOptions.Complete(cmd, args); err != nil { + return err + } + o.WorkspaceName = args[0] + + if !o.UseKubeAPI && o.UserName == "" { + o.UserName = o.CliConfig.User + } + + if len(o.TemplateVars) > 0 { + vars := make(map[string]string) + for _, v := range o.TemplateVars { + varAndVal := strings.Split(v, "=") + if len(varAndVal) != 2 { + return fmt.Errorf("vars format error: vars %s must be 'VAR=VAL'", v) + } + vars[varAndVal[0]] = varAndVal[1] + } + o.vars = vars + } + + cmd.SilenceErrors = true + cmd.SilenceUsage = true + return nil +} + +func (o *UpdateVarsOption) RunE(cmd *cobra.Command, args []string) error { + if err := o.Validate(cmd, args); err != nil { + return fmt.Errorf("validation error: %w", err) + } + if err := o.Complete(cmd, args); err != nil { + return fmt.Errorf("invalid options: %w", err) + } + + ctx, cancel := context.WithTimeout(o.Ctx, time.Second*10) + defer cancel() + ctx = clog.IntoContext(ctx, o.Logr) + + var ( + currentWs *dashv1alpha1.Workspace + err error + ) + if o.UseKubeAPI { + currentWs, err = o.GetWorkspaceWithKubeClient(ctx) + } else { + currentWs, err = o.GetWorkspaceWithDashClient(ctx) + } + if err != nil { + return err + } + + o.Logr.Info("updating workspace", "user", o.UserName, "name", o.WorkspaceName, "currentVars", currentWs.Spec.Vars, "newVars", o.vars) + + if !o.Force { + AskLoop: + for { + input, err := cli.AskInput("Confirm? [y/n] ", false) + if err != nil { + return err + } + switch strings.ToLower(input) { + case "y": + break AskLoop + case "n": + fmt.Println("canceled") + return nil + } + } + } + + var ws *dashv1alpha1.Workspace + if o.UseKubeAPI { + ws, err = o.UpdateWorkspaceWithKubeClient(ctx) + } else { + ws, err = o.UpdateWorkspaceWithDashClient(ctx) + } + if err != nil { + return err + } + + fmt.Fprintln(cmd.OutOrStdout(), color.GreenString("Successfully updated workspace %s", o.WorkspaceName)) + OutputTable(cmd.OutOrStdout(), o.UserName, []*dashv1alpha1.Workspace{ws}) + + return nil +} + +func (o *UpdateVarsOption) UpdateWorkspaceWithDashClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { + req := &dashv1alpha1.UpdateWorkspaceRequest{ + WsName: o.WorkspaceName, + UserName: o.UserName, + Vars: o.vars, + } + c := o.CosmoDashClient + o.Logr.DebugAll().Info("WorkspaceServiceClient.UpdateWorkspace", "req", req) + res, err := c.WorkspaceServiceClient.UpdateWorkspace(ctx, cli.NewRequestWithToken(req, o.CliConfig)) + if err != nil { + return nil, fmt.Errorf("failed to connect dashboard server: %w", err) + } + o.Logr.DebugAll().Info("WorkspaceServiceClient.UpdateWorkspace", "res", res) + + return res.Msg.Workspace, nil +} + +func (o *UpdateVarsOption) UpdateWorkspaceWithKubeClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { + opts := kosmo.UpdateWorkspaceOpts{ + Vars: o.vars, + } + c := o.KosmoClient + o.Logr.DebugAll().Info("UpdateWorkspace", "userName", o.UserName, "workspaceName", o.WorkspaceName, "opts", opts) + ws, err := c.UpdateWorkspace(ctx, o.UserName, o.WorkspaceName, opts) + if err != nil { + return nil, err + } + return apiconv.C2D_Workspace(*ws), nil +} + +func (o *UpdateVarsOption) GetWorkspaceWithDashClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { + req := &dashv1alpha1.GetWorkspaceRequest{ + WsName: o.WorkspaceName, + UserName: o.UserName, + } + c := o.CosmoDashClient + o.Logr.DebugAll().Info("WorkspaceServiceClient.GetWorkspace", "req", req) + res, err := c.WorkspaceServiceClient.GetWorkspace(ctx, cli.NewRequestWithToken(req, o.CliConfig)) + if err != nil { + return nil, fmt.Errorf("failed to connect dashboard server: %w", err) + } + o.Logr.DebugAll().Info("WorkspaceServiceClient.GetWorkspace", "res", res) + + return res.Msg.Workspace, nil +} + +func (o *UpdateVarsOption) GetWorkspaceWithKubeClient(ctx context.Context) (*dashv1alpha1.Workspace, error) { + c := o.KosmoClient + ws, err := c.GetWorkspace(ctx, o.UserName, o.WorkspaceName) + if err != nil { + return nil, err + } + return apiconv.C2D_Workspace(*ws), nil +} diff --git a/internal/controllers/user_controller.go b/internal/controllers/user_controller.go index 7169abf1..ffd7f3cd 100644 --- a/internal/controllers/user_controller.go +++ b/internal/controllers/user_controller.go @@ -236,8 +236,7 @@ func (r *UserReconciler) patchNamespaceToUserDesired(ns *corev1.Namespace, user label[cosmov1alpha1.NamespaceLabelKeyUserName] = user.Name ns.SetLabels(label) - err := ctrl.SetControllerReference(&user, ns, r.Scheme) - if err != nil { + if err := cosmov1alpha1.SetOwnerReferenceIfNotKeepPolicy(&user, ns, r.Scheme); err != nil { return fmt.Errorf("failed to set owner reference: %w", err) } diff --git a/internal/controllers/workspace_controller.go b/internal/controllers/workspace_controller.go index 50b9142b..ab27b9e2 100644 --- a/internal/controllers/workspace_controller.go +++ b/internal/controllers/workspace_controller.go @@ -74,7 +74,7 @@ func (r *WorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( // sync op, err := controllerutil.CreateOrUpdate(ctx, r.Client, inst, func() error { - if err := workspace.PatchWorkspaceInstanceAsDesired(inst, ws, r.Scheme); err != nil { + if err := workspace.PatchWorkspaceInstanceAsDesired(inst, &ws, r.Scheme); err != nil { return err } instance.Mutate(inst, tmpl) diff --git a/internal/dashboard/root.go b/internal/dashboard/root.go index 6cf4f667..d63041a1 100644 --- a/internal/dashboard/root.go +++ b/internal/dashboard/root.go @@ -16,6 +16,7 @@ import ( "github.com/go-webauthn/webauthn/webauthn" "github.com/spf13/cobra" + traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -39,6 +40,7 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(cosmov1alpha1.AddToScheme(scheme)) + utilruntime.Must(traefikv1alpha1.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme } diff --git a/internal/dashboard/user_sub_handler.go b/internal/dashboard/user_sub_handler.go index aa179bcc..9deaa611 100644 --- a/internal/dashboard/user_sub_handler.go +++ b/internal/dashboard/user_sub_handler.go @@ -7,6 +7,7 @@ import ( connect_go "github.com/bufbuild/connect-go" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" apierrs "k8s.io/apimachinery/pkg/api/errors" @@ -90,6 +91,37 @@ func (s *Server) UpdateUserDisplayName(ctx context.Context, req *connect_go.Requ return connect_go.NewResponse(res), nil } +func (s *Server) UpdateUserDeletePolicy(ctx context.Context, req *connect_go.Request[dashv1alpha1.UpdateUserDeletePolicyRequest]) (*connect_go.Response[dashv1alpha1.UpdateUserDeletePolicyResponse], error) { + log := clog.FromContext(ctx).WithCaller() + log.Debug().Info("request", "req", req) + + currentUser, err := s.Klient.GetUser(ctx, req.Msg.UserName) + if err != nil { + return nil, ErrResponse(log, err) + } + + // caller can attach or detach only: + // - User who have group-role which caller is admin for + // - Addons which is allowed for caller to manage + err = adminAuthentication(ctx, + validateCallerHasAdminForAtLeastOneRole(currentUser.Spec.Roles)) + if err != nil { + return nil, ErrResponse(log, err) + } + + user, err := s.Klient.UpdateUser(ctx, req.Msg.UserName, kosmo.UpdateUserOpts{DeletePolicy: ptr.To(apiconv.D2C_DeletePolicy(ptr.To(req.Msg.DeletePolicy)))}) + if err != nil { + return nil, ErrResponse(log, err) + } + + res := &dashv1alpha1.UpdateUserDeletePolicyResponse{ + Message: "Successfully updated", + User: apiconv.C2D_User(*user), + } + log.Info(res.Message, "username", req.Msg.UserName) + return connect_go.NewResponse(res), nil +} + func diff[T any](slice1 []T, slice2 []T) []T { var diff []T // Loop two times, first to find slice1 strings not in slice2, diff --git a/internal/dashboard/workspace_handler.go b/internal/dashboard/workspace_handler.go index caa6f029..f9d064e4 100644 --- a/internal/dashboard/workspace_handler.go +++ b/internal/dashboard/workspace_handler.go @@ -7,8 +7,10 @@ import ( "slices" connect_go "github.com/bufbuild/connect-go" + traefikv1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" apierrs "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" "github.com/cosmo-workspace/cosmo/pkg/apiconv" @@ -115,8 +117,14 @@ func (s *Server) GetWorkspace(ctx context.Context, req *connect_go.Request[dashv res := &dashv1alpha1.GetWorkspaceResponse{} if req.Msg.WithRaw != nil && *req.Msg.WithRaw { var inst cosmov1alpha1.Instance - s.Klient.Get(ctx, types.NamespacedName{Name: ws.Status.Instance.Name, Namespace: ws.Status.Instance.Namespace}, &inst) - res.Workspace = apiconv.C2D_Workspace(*ws, apiconv.WithWorkspaceRaw(), apiconv.WithWorkspaceInstanceRaw(&inst)) + if err := s.Klient.Get(ctx, types.NamespacedName{Name: ws.Status.Instance.Name, Namespace: ws.Status.Instance.Namespace}, &inst); err != nil { + log.Error(err, "failed to get instance of workspace", "workspace", ws.Name, "namespace", ws.Namespace) + } + var ir traefikv1.IngressRoute + if err := s.Klient.Get(ctx, types.NamespacedName{Name: ws.Status.Instance.Name, Namespace: ws.Status.Instance.Namespace}, &ir); err != nil { + log.Error(err, "failed to get ingressroute of workspace", "workspace", ws.Name, "namespace", ws.Namespace) + } + res.Workspace = apiconv.C2D_Workspace(*ws, apiconv.WithWorkspaceRaw(), apiconv.WithWorkspaceInstanceRaw(&inst), apiconv.WithWorkspaceIngressRouteRaw(&ir)) } else { res.Workspace = apiconv.C2D_Workspace(*ws) @@ -170,9 +178,15 @@ func (s *Server) UpdateWorkspace(ctx context.Context, req *connect_go.Request[da } } + var delPolicy *string + if req.Msg.DeletePolicy != nil { + delPolicy = ptr.To(apiconv.D2C_DeletePolicy(req.Msg.DeletePolicy)) + } + ws, err := s.Klient.UpdateWorkspace(ctx, req.Msg.WsName, req.Msg.UserName, kosmo.UpdateWorkspaceOpts{ - Replicas: req.Msg.Replicas, - Vars: req.Msg.Vars, + Replicas: req.Msg.Replicas, + Vars: req.Msg.Vars, + DeletePolicy: delPolicy, }) if err != nil { return nil, ErrResponse(log, err) diff --git a/pkg/apiconv/raw.go b/pkg/apiconv/raw.go index 4913235f..8f975a6b 100644 --- a/pkg/apiconv/raw.go +++ b/pkg/apiconv/raw.go @@ -1,7 +1,9 @@ package apiconv import ( + traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" @@ -13,7 +15,8 @@ import ( var scheme = runtime.NewScheme() func init() { - _ = cosmov1alpha1.AddToScheme(scheme) + utilruntime.Must(cosmov1alpha1.AddToScheme(scheme)) + utilruntime.Must(traefikv1alpha1.AddToScheme(scheme)) } func ToYAML(obj client.Object) *string { diff --git a/pkg/apiconv/user.go b/pkg/apiconv/user.go index 05b24df7..f8ca5852 100644 --- a/pkg/apiconv/user.go +++ b/pkg/apiconv/user.go @@ -10,6 +10,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" eventsv1 "k8s.io/api/events/v1" + "k8s.io/utils/ptr" cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" "github.com/cosmo-workspace/cosmo/pkg/kubeutil" @@ -45,15 +46,42 @@ func C2D_Users(users []cosmov1alpha1.User, opts ...UserConvertOptions) []*dashv1 return ts } +func C2D_DeletePolicy(deletePolicy string) *dashv1alpha1.DeletePolicy { + switch deletePolicy { + case cosmov1alpha1.ResourceAnnEnumDeletePolicyDelete: + return ptr.To(dashv1alpha1.DeletePolicy_delete) + case cosmov1alpha1.ResourceAnnEnumDeletePolicyKeep: + return ptr.To(dashv1alpha1.DeletePolicy_keep) + default: + return nil + } +} + +func D2C_DeletePolicy(deletePolicy *dashv1alpha1.DeletePolicy) string { + if deletePolicy == nil { + return "" + } + switch *deletePolicy { + case dashv1alpha1.DeletePolicy_delete: + return cosmov1alpha1.ResourceAnnEnumDeletePolicyDelete + case dashv1alpha1.DeletePolicy_keep: + return cosmov1alpha1.ResourceAnnEnumDeletePolicyKeep + default: + return "" + } +} + func C2D_User(user cosmov1alpha1.User, opts ...UserConvertOptions) *dashv1alpha1.User { d := &dashv1alpha1.User{ - Name: user.Name, - DisplayName: user.Spec.DisplayName, - Roles: C2S_UserRole(user.Spec.Roles), - AuthType: user.Spec.AuthType.String(), - Addons: C2D_UserAddons(user.Spec.Addons), - Status: string(user.Status.Phase), + Name: user.Name, + DisplayName: user.Spec.DisplayName, + Roles: C2S_UserRole(user.Spec.Roles), + AuthType: user.Spec.AuthType.String(), + Addons: C2D_UserAddons(user.Spec.Addons), + Status: string(user.Status.Phase), + DeletePolicy: C2D_DeletePolicy(kubeutil.GetAnnotation(&user, cosmov1alpha1.ResourceAnnKeyDeletePolicy)), } + for _, opt := range opts { opt(&user, d) } diff --git a/pkg/apiconv/workspace.go b/pkg/apiconv/workspace.go index 8f58e8fc..da0dc0ee 100644 --- a/pkg/apiconv/workspace.go +++ b/pkg/apiconv/workspace.go @@ -3,6 +3,7 @@ package apiconv import ( "time" + traefikv1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "google.golang.org/protobuf/types/known/timestamppb" "k8s.io/utils/ptr" @@ -25,6 +26,12 @@ func WithWorkspaceInstanceRaw(inst *cosmov1alpha1.Instance) func(c *cosmov1alpha } } +func WithWorkspaceIngressRouteRaw(ir *traefikv1.IngressRoute) func(c *cosmov1alpha1.Workspace, d *dashv1alpha1.Workspace) { + return func(c *cosmov1alpha1.Workspace, d *dashv1alpha1.Workspace) { + d.RawIngressRoute = ToYAML(ir) + } +} + func C2D_Workspaces(wss []cosmov1alpha1.Workspace, opts ...WorkspaceConvertOptions) []*dashv1alpha1.Workspace { apiwss := make([]*dashv1alpha1.Workspace, len(wss)) for i, v := range wss { @@ -52,6 +59,7 @@ func C2D_Workspace(ws cosmov1alpha1.Workspace, opts ...WorkspaceConvertOptions) Phase: string(ws.Status.Phase), MainUrl: ws.Status.URLs[cosmov1alpha1.MainRuleKey(ws.Status.Config)], }, + DeletePolicy: C2D_DeletePolicy(kubeutil.GetAnnotation(&ws, cosmov1alpha1.ResourceAnnKeyDeletePolicy)), } t, err := time.Parse(time.RFC3339, kubeutil.GetAnnotation(&ws, cosmov1alpha1.WorkspaceAnnKeyLastStartedAt)) diff --git a/pkg/kosmo/user.go b/pkg/kosmo/user.go index fcbf7a11..c78658e0 100644 --- a/pkg/kosmo/user.go +++ b/pkg/kosmo/user.go @@ -12,6 +12,7 @@ import ( cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" "github.com/cosmo-workspace/cosmo/pkg/clog" + "github.com/cosmo-workspace/cosmo/pkg/kubeutil" ) func (c *Client) GetUser(ctx context.Context, name string) (*cosmov1alpha1.User, error) { @@ -114,6 +115,10 @@ func (c *Client) DeleteUser(ctx context.Context, username string) (*cosmov1alpha return nil, err } + if cosmov1alpha1.KeepResourceDeletePolicy(user) { + return nil, fmt.Errorf("protected: keep resource policy is set") + } + if err := c.Delete(ctx, user); err != nil { log.Error(err, "failed to delete user") return nil, fmt.Errorf("failed to delete user: %w", err) @@ -123,9 +128,10 @@ func (c *Client) DeleteUser(ctx context.Context, username string) (*cosmov1alpha } type UpdateUserOpts struct { - DisplayName *string - UserRoles []cosmov1alpha1.UserRole - UserAddons []cosmov1alpha1.UserAddon + DisplayName *string + UserRoles []cosmov1alpha1.UserRole + UserAddons []cosmov1alpha1.UserAddon + DeletePolicy *string } func (c *Client) UpdateUser(ctx context.Context, username string, opts UpdateUserOpts) (*cosmov1alpha1.User, error) { @@ -151,6 +157,10 @@ func (c *Client) UpdateUser(ctx context.Context, username string, opts UpdateUse user.Spec.Addons = opts.UserAddons } + if opts.DeletePolicy != nil { + kubeutil.SetAnnotation(user, cosmov1alpha1.ResourceAnnKeyDeletePolicy, *opts.DeletePolicy) + } + if equality.Semantic.DeepEqual(before, user) { logr.Debug().Info("no change", "user", before) return nil, apierrs.NewBadRequest("no change") diff --git a/pkg/kosmo/workspace.go b/pkg/kosmo/workspace.go index c683a67f..a26c975d 100644 --- a/pkg/kosmo/workspace.go +++ b/pkg/kosmo/workspace.go @@ -136,6 +136,11 @@ func (c *Client) DeleteWorkspace(ctx context.Context, name, username string, opt if err != nil { return nil, err } + + if cosmov1alpha1.KeepResourceDeletePolicy(ws) { + return nil, fmt.Errorf("protected: keep resource policy is set") + } + if err := c.Delete(ctx, ws, opts...); err != nil { log.Error(err, "failed to delete workspace", "username", username, "workspace", name) return nil, fmt.Errorf("failed to delete workspace: %w", err) @@ -144,8 +149,9 @@ func (c *Client) DeleteWorkspace(ctx context.Context, name, username string, opt } type UpdateWorkspaceOpts struct { - Replicas *int64 - Vars map[string]string + Replicas *int64 + Vars map[string]string + DeletePolicy *string } func (c *Client) UpdateWorkspace(ctx context.Context, name, username string, opts UpdateWorkspaceOpts) (*cosmov1alpha1.Workspace, error) { @@ -164,6 +170,9 @@ func (c *Client) UpdateWorkspace(ctx context.Context, name, username string, opt if opts.Vars != nil { ws.Spec.Vars = opts.Vars } + if opts.DeletePolicy != nil { + kubeutil.SetAnnotation(ws, cosmov1alpha1.ResourceAnnKeyDeletePolicy, *opts.DeletePolicy) + } if equality.Semantic.DeepEqual(before, ws) { return nil, apierrs.NewBadRequest("no change") diff --git a/pkg/transformer/metadata.go b/pkg/transformer/metadata.go index 0934d7c4..40d0a07e 100644 --- a/pkg/transformer/metadata.go +++ b/pkg/transformer/metadata.go @@ -2,16 +2,10 @@ package transformer import ( "fmt" - "reflect" - "slices" "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/utils/ptr" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" "github.com/cosmo-workspace/cosmo/pkg/instance" @@ -50,28 +44,8 @@ func (t *MetadataTransformer) Transform(src *unstructured.Unstructured) (*unstru labels[cosmov1alpha1.LabelKeyTemplateName] = t.tmplName obj.SetLabels(labels) - if !cosmov1alpha1.KeepResourceDeletePolicy(t.inst) && !cosmov1alpha1.KeepResourceDeletePolicy(obj) { - // Set owner reference - err := ctrl.SetControllerReference(t.inst, obj, t.scheme) - if err != nil { - return nil, fmt.Errorf("failed to set owner reference on %s: %w", obj.GetObjectKind().GroupVersionKind(), err) - } - } else { - // Remove owner reference - if len(obj.GetOwnerReferences()) > 0 { - gvk, _ := apiutil.GVKForObject(t.inst, t.scheme) - refs := slices.DeleteFunc(obj.GetOwnerReferences(), func(v metav1.OwnerReference) bool { - return reflect.DeepEqual(v, metav1.OwnerReference{ - APIVersion: gvk.GroupVersion().String(), - Kind: gvk.Kind, - Name: t.inst.GetName(), - UID: t.inst.GetUID(), - Controller: ptr.To(true), - BlockOwnerDeletion: ptr.To(true), - }) - }) - obj.SetOwnerReferences(refs) - } + if err := cosmov1alpha1.SetOwnerReferenceIfNotKeepPolicy(t.inst, obj, t.scheme); err != nil { + return nil, fmt.Errorf("failed to set owner reference: %w", err) } return obj, nil } diff --git a/pkg/useraddon/useraddon.go b/pkg/useraddon/useraddon.go index bcbf5b46..24e7b418 100644 --- a/pkg/useraddon/useraddon.go +++ b/pkg/useraddon/useraddon.go @@ -6,9 +6,9 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation" - ctrl "sigs.k8s.io/controller-runtime" cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" + "github.com/cosmo-workspace/cosmo/pkg/kubeutil" "github.com/cosmo-workspace/cosmo/pkg/template" ) @@ -81,12 +81,12 @@ func PatchUserAddonInstanceAsDesired(inst cosmov1alpha1.InstanceObject, addon co vars[cosmov1alpha1.TemplateVarUserName] = user.Name inst.GetSpec().Vars = vars - // set owner reference if scheme is not nil - if scheme != nil { - err := ctrl.SetControllerReference(&user, inst, scheme) - if err != nil { - return fmt.Errorf("failed to set controller reference: %w", err) - } + if err := cosmov1alpha1.SetOwnerReferenceIfNotKeepPolicy(&user, inst, scheme); err != nil { + return fmt.Errorf("failed to set owner reference: %w", err) + } + + if policy := kubeutil.GetAnnotation(&user, cosmov1alpha1.ResourceAnnKeyDeletePolicy); policy != "" { + kubeutil.SetAnnotation(inst, cosmov1alpha1.ResourceAnnKeyDeletePolicy, policy) } return nil diff --git a/pkg/workspace/traefik_ingressroute.go b/pkg/workspace/traefik_ingressroute.go index 555d00c5..d4767256 100644 --- a/pkg/workspace/traefik_ingressroute.go +++ b/pkg/workspace/traefik_ingressroute.go @@ -7,7 +7,6 @@ import ( traefikv1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" - ctrl "sigs.k8s.io/controller-runtime" cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" "github.com/cosmo-workspace/cosmo/pkg/instance" @@ -49,11 +48,8 @@ func (c *TraefikIngressRouteConfig) PatchTraefikIngressRouteAsDesired(ir *traefi } ir.Spec.Routes = routes - if scheme != nil { - err := ctrl.SetControllerReference(&ws, ir, scheme) - if err != nil { - return fmt.Errorf("failed to set owner reference: %w", err) - } + if err := cosmov1alpha1.SetOwnerReferenceIfNotKeepPolicy(&ws, ir, scheme); err != nil { + return fmt.Errorf("failed to set owner reference: %w", err) } return nil } diff --git a/pkg/workspace/workspace.go b/pkg/workspace/workspace.go index a92a2d60..b508cb68 100644 --- a/pkg/workspace/workspace.go +++ b/pkg/workspace/workspace.go @@ -6,7 +6,6 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" "github.com/cosmo-workspace/cosmo/pkg/kubeutil" @@ -20,7 +19,7 @@ func JSONPatch(op, path string, value any) (string, error) { return fmt.Sprintf(`[{"op": "%s","path": "%s","value": %s}]`, op, path, string(v)), nil } -func PatchWorkspaceInstanceAsDesired(inst *cosmov1alpha1.Instance, ws cosmov1alpha1.Workspace, scheme *runtime.Scheme) error { +func PatchWorkspaceInstanceAsDesired(inst *cosmov1alpha1.Instance, ws *cosmov1alpha1.Workspace, scheme *runtime.Scheme) error { svcTargetRef := cosmov1alpha1.ObjectRef{} svcTargetRef.SetName(ws.Status.Config.ServiceName) svcTargetRef.SetGroupVersionKind(kubeutil.ServiceGVK) @@ -60,11 +59,12 @@ func PatchWorkspaceInstanceAsDesired(inst *cosmov1alpha1.Instance, ws cosmov1alp }) } - if scheme != nil { - err := ctrl.SetControllerReference(&ws, inst, scheme) - if err != nil { - return fmt.Errorf("failed to set owner reference: %w", err) - } + if policy := kubeutil.GetAnnotation(ws, cosmov1alpha1.ResourceAnnKeyDeletePolicy); policy != "" { + kubeutil.SetAnnotation(inst, cosmov1alpha1.ResourceAnnKeyDeletePolicy, policy) + } + + if err := cosmov1alpha1.SetOwnerReferenceIfNotKeepPolicy(ws, inst, scheme); err != nil { + return fmt.Errorf("failed to set owner reference: %w", err) } return nil @@ -85,7 +85,7 @@ func svcPorts(netRules []cosmov1alpha1.NetworkRule) []corev1.ServicePort { return ports } -func varsWithWorkspaceDefault(ws cosmov1alpha1.Workspace) map[string]string { +func varsWithWorkspaceDefault(ws *cosmov1alpha1.Workspace) map[string]string { user := cosmov1alpha1.UserNameByNamespace(ws.GetNamespace()) var vars map[string]string diff --git a/pkg/workspace/workspace_test.go b/pkg/workspace/workspace_test.go index 74b5c7e3..d96ffdf5 100644 --- a/pkg/workspace/workspace_test.go +++ b/pkg/workspace/workspace_test.go @@ -137,7 +137,7 @@ func TestPatchWorkspaceInstanceAsDesired(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := PatchWorkspaceInstanceAsDesired(tt.args.inst, tt.args.ws, tt.args.scheme) + err := PatchWorkspaceInstanceAsDesired(tt.args.inst, &tt.args.ws, tt.args.scheme) if err != nil { snaps.MatchSnapshot(t, err.Error()) } else { diff --git a/proto/gen/dashboard/v1alpha1/dashboardv1alpha1connect/user_service.connect.go b/proto/gen/dashboard/v1alpha1/dashboardv1alpha1connect/user_service.connect.go index 59ab8051..ce4a8389 100644 --- a/proto/gen/dashboard/v1alpha1/dashboardv1alpha1connect/user_service.connect.go +++ b/proto/gen/dashboard/v1alpha1/dashboardv1alpha1connect/user_service.connect.go @@ -59,6 +59,9 @@ const ( // UserServiceUpdateUserAddonsProcedure is the fully-qualified name of the UserService's // UpdateUserAddons RPC. UserServiceUpdateUserAddonsProcedure = "/dashboard.v1alpha1.UserService/UpdateUserAddons" + // UserServiceUpdateUserDeletePolicyProcedure is the fully-qualified name of the UserService's + // UpdateUserDeletePolicy RPC. + UserServiceUpdateUserDeletePolicyProcedure = "/dashboard.v1alpha1.UserService/UpdateUserDeletePolicy" ) // UserServiceClient is a client for the dashboard.v1alpha1.UserService service. @@ -81,6 +84,8 @@ type UserServiceClient interface { UpdateUserRole(context.Context, *connect_go.Request[v1alpha1.UpdateUserRoleRequest]) (*connect_go.Response[v1alpha1.UpdateUserRoleResponse], error) // Update a single User role UpdateUserAddons(context.Context, *connect_go.Request[v1alpha1.UpdateUserAddonsRequest]) (*connect_go.Response[v1alpha1.UpdateUserAddonsResponse], error) + // Update user delete policy + UpdateUserDeletePolicy(context.Context, *connect_go.Request[v1alpha1.UpdateUserDeletePolicyRequest]) (*connect_go.Response[v1alpha1.UpdateUserDeletePolicyResponse], error) } // NewUserServiceClient constructs a client for the dashboard.v1alpha1.UserService service. By @@ -138,20 +143,26 @@ func NewUserServiceClient(httpClient connect_go.HTTPClient, baseURL string, opts baseURL+UserServiceUpdateUserAddonsProcedure, opts..., ), + updateUserDeletePolicy: connect_go.NewClient[v1alpha1.UpdateUserDeletePolicyRequest, v1alpha1.UpdateUserDeletePolicyResponse]( + httpClient, + baseURL+UserServiceUpdateUserDeletePolicyProcedure, + opts..., + ), } } // userServiceClient implements UserServiceClient. type userServiceClient struct { - deleteUser *connect_go.Client[v1alpha1.DeleteUserRequest, v1alpha1.DeleteUserResponse] - getUser *connect_go.Client[v1alpha1.GetUserRequest, v1alpha1.GetUserResponse] - getUsers *connect_go.Client[v1alpha1.GetUsersRequest, v1alpha1.GetUsersResponse] - getEvents *connect_go.Client[v1alpha1.GetEventsRequest, v1alpha1.GetEventsResponse] - createUser *connect_go.Client[v1alpha1.CreateUserRequest, v1alpha1.CreateUserResponse] - updateUserDisplayName *connect_go.Client[v1alpha1.UpdateUserDisplayNameRequest, v1alpha1.UpdateUserDisplayNameResponse] - updateUserPassword *connect_go.Client[v1alpha1.UpdateUserPasswordRequest, v1alpha1.UpdateUserPasswordResponse] - updateUserRole *connect_go.Client[v1alpha1.UpdateUserRoleRequest, v1alpha1.UpdateUserRoleResponse] - updateUserAddons *connect_go.Client[v1alpha1.UpdateUserAddonsRequest, v1alpha1.UpdateUserAddonsResponse] + deleteUser *connect_go.Client[v1alpha1.DeleteUserRequest, v1alpha1.DeleteUserResponse] + getUser *connect_go.Client[v1alpha1.GetUserRequest, v1alpha1.GetUserResponse] + getUsers *connect_go.Client[v1alpha1.GetUsersRequest, v1alpha1.GetUsersResponse] + getEvents *connect_go.Client[v1alpha1.GetEventsRequest, v1alpha1.GetEventsResponse] + createUser *connect_go.Client[v1alpha1.CreateUserRequest, v1alpha1.CreateUserResponse] + updateUserDisplayName *connect_go.Client[v1alpha1.UpdateUserDisplayNameRequest, v1alpha1.UpdateUserDisplayNameResponse] + updateUserPassword *connect_go.Client[v1alpha1.UpdateUserPasswordRequest, v1alpha1.UpdateUserPasswordResponse] + updateUserRole *connect_go.Client[v1alpha1.UpdateUserRoleRequest, v1alpha1.UpdateUserRoleResponse] + updateUserAddons *connect_go.Client[v1alpha1.UpdateUserAddonsRequest, v1alpha1.UpdateUserAddonsResponse] + updateUserDeletePolicy *connect_go.Client[v1alpha1.UpdateUserDeletePolicyRequest, v1alpha1.UpdateUserDeletePolicyResponse] } // DeleteUser calls dashboard.v1alpha1.UserService.DeleteUser. @@ -199,6 +210,11 @@ func (c *userServiceClient) UpdateUserAddons(ctx context.Context, req *connect_g return c.updateUserAddons.CallUnary(ctx, req) } +// UpdateUserDeletePolicy calls dashboard.v1alpha1.UserService.UpdateUserDeletePolicy. +func (c *userServiceClient) UpdateUserDeletePolicy(ctx context.Context, req *connect_go.Request[v1alpha1.UpdateUserDeletePolicyRequest]) (*connect_go.Response[v1alpha1.UpdateUserDeletePolicyResponse], error) { + return c.updateUserDeletePolicy.CallUnary(ctx, req) +} + // UserServiceHandler is an implementation of the dashboard.v1alpha1.UserService service. type UserServiceHandler interface { // Delete user by ID @@ -219,6 +235,8 @@ type UserServiceHandler interface { UpdateUserRole(context.Context, *connect_go.Request[v1alpha1.UpdateUserRoleRequest]) (*connect_go.Response[v1alpha1.UpdateUserRoleResponse], error) // Update a single User role UpdateUserAddons(context.Context, *connect_go.Request[v1alpha1.UpdateUserAddonsRequest]) (*connect_go.Response[v1alpha1.UpdateUserAddonsResponse], error) + // Update user delete policy + UpdateUserDeletePolicy(context.Context, *connect_go.Request[v1alpha1.UpdateUserDeletePolicyRequest]) (*connect_go.Response[v1alpha1.UpdateUserDeletePolicyResponse], error) } // NewUserServiceHandler builds an HTTP handler from the service implementation. It returns the path @@ -273,6 +291,11 @@ func NewUserServiceHandler(svc UserServiceHandler, opts ...connect_go.HandlerOpt svc.UpdateUserAddons, opts..., )) + mux.Handle(UserServiceUpdateUserDeletePolicyProcedure, connect_go.NewUnaryHandler( + UserServiceUpdateUserDeletePolicyProcedure, + svc.UpdateUserDeletePolicy, + opts..., + )) return "/dashboard.v1alpha1.UserService/", mux } @@ -314,3 +337,7 @@ func (UnimplementedUserServiceHandler) UpdateUserRole(context.Context, *connect_ func (UnimplementedUserServiceHandler) UpdateUserAddons(context.Context, *connect_go.Request[v1alpha1.UpdateUserAddonsRequest]) (*connect_go.Response[v1alpha1.UpdateUserAddonsResponse], error) { return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("dashboard.v1alpha1.UserService.UpdateUserAddons is not implemented")) } + +func (UnimplementedUserServiceHandler) UpdateUserDeletePolicy(context.Context, *connect_go.Request[v1alpha1.UpdateUserDeletePolicyRequest]) (*connect_go.Response[v1alpha1.UpdateUserDeletePolicyResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("dashboard.v1alpha1.UserService.UpdateUserDeletePolicy is not implemented")) +} diff --git a/proto/gen/dashboard/v1alpha1/user.pb.go b/proto/gen/dashboard/v1alpha1/user.pb.go index dfbf7d9b..e2dffcf9 100644 --- a/proto/gen/dashboard/v1alpha1/user.pb.go +++ b/proto/gen/dashboard/v1alpha1/user.pb.go @@ -25,19 +25,66 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type DeletePolicy int32 + +const ( + DeletePolicy_delete DeletePolicy = 0 + DeletePolicy_keep DeletePolicy = 1 +) + +// Enum value maps for DeletePolicy. +var ( + DeletePolicy_name = map[int32]string{ + 0: "delete", + 1: "keep", + } + DeletePolicy_value = map[string]int32{ + "delete": 0, + "keep": 1, + } +) + +func (x DeletePolicy) Enum() *DeletePolicy { + p := new(DeletePolicy) + *p = x + return p +} + +func (x DeletePolicy) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DeletePolicy) Descriptor() protoreflect.EnumDescriptor { + return file_dashboard_v1alpha1_user_proto_enumTypes[0].Descriptor() +} + +func (DeletePolicy) Type() protoreflect.EnumType { + return &file_dashboard_v1alpha1_user_proto_enumTypes[0] +} + +func (x DeletePolicy) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DeletePolicy.Descriptor instead. +func (DeletePolicy) EnumDescriptor() ([]byte, []int) { + return file_dashboard_v1alpha1_user_proto_rawDescGZIP(), []int{0} +} + type User struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` - Roles []string `protobuf:"bytes,3,rep,name=roles,proto3" json:"roles,omitempty"` - AuthType string `protobuf:"bytes,4,opt,name=auth_type,json=authType,proto3" json:"auth_type,omitempty"` - Addons []*UserAddon `protobuf:"bytes,5,rep,name=addons,proto3" json:"addons,omitempty"` - DefaultPassword string `protobuf:"bytes,6,opt,name=default_password,json=defaultPassword,proto3" json:"default_password,omitempty"` - Status string `protobuf:"bytes,7,opt,name=status,proto3" json:"status,omitempty"` - Raw *string `protobuf:"bytes,8,opt,name=raw,proto3,oneof" json:"raw,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Roles []string `protobuf:"bytes,3,rep,name=roles,proto3" json:"roles,omitempty"` + AuthType string `protobuf:"bytes,4,opt,name=auth_type,json=authType,proto3" json:"auth_type,omitempty"` + Addons []*UserAddon `protobuf:"bytes,5,rep,name=addons,proto3" json:"addons,omitempty"` + DefaultPassword string `protobuf:"bytes,6,opt,name=default_password,json=defaultPassword,proto3" json:"default_password,omitempty"` + Status string `protobuf:"bytes,7,opt,name=status,proto3" json:"status,omitempty"` + Raw *string `protobuf:"bytes,8,opt,name=raw,proto3,oneof" json:"raw,omitempty"` + DeletePolicy *DeletePolicy `protobuf:"varint,9,opt,name=delete_policy,json=deletePolicy,proto3,enum=dashboard.v1alpha1.DeletePolicy,oneof" json:"delete_policy,omitempty"` } func (x *User) Reset() { @@ -128,6 +175,13 @@ func (x *User) GetRaw() string { return "" } +func (x *User) GetDeletePolicy() DeletePolicy { + if x != nil && x.DeletePolicy != nil { + return *x.DeletePolicy + } + return DeletePolicy_delete +} + type UserAddon struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -206,7 +260,7 @@ var file_dashboard_v1alpha1_user_proto_rawDesc = []byte{ 0x70, 0x68, 0x61, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x89, 0x02, 0x0a, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf1, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, @@ -223,36 +277,45 @@ var file_dashboard_v1alpha1_user_proto_rawDesc = []byte{ 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x88, 0x01, 0x01, - 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x72, 0x61, 0x77, 0x22, 0xec, 0x01, 0x0a, 0x09, 0x55, 0x73, 0x65, - 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, - 0x01, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x63, 0x6f, 0x70, - 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x04, 0x76, 0x61, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x2e, - 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x76, 0x61, 0x72, 0x73, 0x12, - 0x15, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, - 0x72, 0x61, 0x77, 0x88, 0x01, 0x01, 0x1a, 0x37, 0x0a, 0x09, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, - 0x06, 0x0a, 0x04, 0x5f, 0x72, 0x61, 0x77, 0x42, 0xdd, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, - 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x2d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x64, 0x61, 0x73, 0x68, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, - 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x12, 0x44, 0x61, - 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0xe2, 0x02, 0x1e, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x13, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x3a, 0x3a, 0x56, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x54, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, + 0x02, 0x10, 0x01, 0x48, 0x01, 0x52, 0x0c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x72, 0x61, 0x77, 0x42, 0x10, + 0x0a, 0x0e, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x22, 0xec, 0x01, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x12, 0x23, + 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x04, 0x76, 0x61, + 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x04, 0x76, 0x61, 0x72, 0x73, 0x12, 0x15, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x88, 0x01, 0x01, 0x1a, 0x37, + 0x0a, 0x09, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x72, 0x61, 0x77, 0x2a, + 0x24, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x0a, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x6b, + 0x65, 0x65, 0x70, 0x10, 0x01, 0x42, 0xdd, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x61, + 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, + 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, + 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, + 0x1e, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x13, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -267,20 +330,23 @@ func file_dashboard_v1alpha1_user_proto_rawDescGZIP() []byte { return file_dashboard_v1alpha1_user_proto_rawDescData } +var file_dashboard_v1alpha1_user_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_dashboard_v1alpha1_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_dashboard_v1alpha1_user_proto_goTypes = []interface{}{ - (*User)(nil), // 0: dashboard.v1alpha1.User - (*UserAddon)(nil), // 1: dashboard.v1alpha1.UserAddon - nil, // 2: dashboard.v1alpha1.UserAddon.VarsEntry + (DeletePolicy)(0), // 0: dashboard.v1alpha1.DeletePolicy + (*User)(nil), // 1: dashboard.v1alpha1.User + (*UserAddon)(nil), // 2: dashboard.v1alpha1.UserAddon + nil, // 3: dashboard.v1alpha1.UserAddon.VarsEntry } var file_dashboard_v1alpha1_user_proto_depIdxs = []int32{ - 1, // 0: dashboard.v1alpha1.User.addons:type_name -> dashboard.v1alpha1.UserAddon - 2, // 1: dashboard.v1alpha1.UserAddon.vars:type_name -> dashboard.v1alpha1.UserAddon.VarsEntry - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 2, // 0: dashboard.v1alpha1.User.addons:type_name -> dashboard.v1alpha1.UserAddon + 0, // 1: dashboard.v1alpha1.User.delete_policy:type_name -> dashboard.v1alpha1.DeletePolicy + 3, // 2: dashboard.v1alpha1.UserAddon.vars:type_name -> dashboard.v1alpha1.UserAddon.VarsEntry + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_dashboard_v1alpha1_user_proto_init() } @@ -321,13 +387,14 @@ func file_dashboard_v1alpha1_user_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_dashboard_v1alpha1_user_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 3, NumExtensions: 0, NumServices: 0, }, GoTypes: file_dashboard_v1alpha1_user_proto_goTypes, DependencyIndexes: file_dashboard_v1alpha1_user_proto_depIdxs, + EnumInfos: file_dashboard_v1alpha1_user_proto_enumTypes, MessageInfos: file_dashboard_v1alpha1_user_proto_msgTypes, }.Build() File_dashboard_v1alpha1_user_proto = out.File diff --git a/proto/gen/dashboard/v1alpha1/user.pb.validate.go b/proto/gen/dashboard/v1alpha1/user.pb.validate.go index 1c6b4596..e3b1c58d 100644 --- a/proto/gen/dashboard/v1alpha1/user.pb.validate.go +++ b/proto/gen/dashboard/v1alpha1/user.pb.validate.go @@ -104,6 +104,21 @@ func (m *User) validate(all bool) error { // no validation rules for Raw } + if m.DeletePolicy != nil { + + if _, ok := DeletePolicy_name[int32(m.GetDeletePolicy())]; !ok { + err := UserValidationError{ + field: "DeletePolicy", + reason: "value must be one of the defined enum values", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + if len(errors) > 0 { return UserMultiError(errors) } diff --git a/proto/gen/dashboard/v1alpha1/user_service.pb.go b/proto/gen/dashboard/v1alpha1/user_service.pb.go index bf9d498c..a51a6dfb 100644 --- a/proto/gen/dashboard/v1alpha1/user_service.pb.go +++ b/proto/gen/dashboard/v1alpha1/user_service.pb.go @@ -906,6 +906,116 @@ func (x *UpdateUserAddonsResponse) GetUser() *User { return nil } +type UpdateUserDeletePolicyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserName string `protobuf:"bytes,1,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + DeletePolicy DeletePolicy `protobuf:"varint,2,opt,name=delete_policy,json=deletePolicy,proto3,enum=dashboard.v1alpha1.DeletePolicy" json:"delete_policy,omitempty"` +} + +func (x *UpdateUserDeletePolicyRequest) Reset() { + *x = UpdateUserDeletePolicyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserDeletePolicyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserDeletePolicyRequest) ProtoMessage() {} + +func (x *UpdateUserDeletePolicyRequest) ProtoReflect() protoreflect.Message { + mi := &file_dashboard_v1alpha1_user_service_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 UpdateUserDeletePolicyRequest.ProtoReflect.Descriptor instead. +func (*UpdateUserDeletePolicyRequest) Descriptor() ([]byte, []int) { + return file_dashboard_v1alpha1_user_service_proto_rawDescGZIP(), []int{16} +} + +func (x *UpdateUserDeletePolicyRequest) GetUserName() string { + if x != nil { + return x.UserName + } + return "" +} + +func (x *UpdateUserDeletePolicyRequest) GetDeletePolicy() DeletePolicy { + if x != nil { + return x.DeletePolicy + } + return DeletePolicy_delete +} + +type UpdateUserDeletePolicyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + User *User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *UpdateUserDeletePolicyResponse) Reset() { + *x = UpdateUserDeletePolicyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserDeletePolicyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserDeletePolicyResponse) ProtoMessage() {} + +func (x *UpdateUserDeletePolicyResponse) ProtoReflect() protoreflect.Message { + mi := &file_dashboard_v1alpha1_user_service_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 UpdateUserDeletePolicyResponse.ProtoReflect.Descriptor instead. +func (*UpdateUserDeletePolicyResponse) Descriptor() ([]byte, []int) { + return file_dashboard_v1alpha1_user_service_proto_rawDescGZIP(), []int{17} +} + +func (x *UpdateUserDeletePolicyResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *UpdateUserDeletePolicyResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + type GetEventsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -918,7 +1028,7 @@ type GetEventsRequest struct { func (x *GetEventsRequest) Reset() { *x = GetEventsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[16] + mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -931,7 +1041,7 @@ func (x *GetEventsRequest) String() string { func (*GetEventsRequest) ProtoMessage() {} func (x *GetEventsRequest) ProtoReflect() protoreflect.Message { - mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[16] + mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -944,7 +1054,7 @@ func (x *GetEventsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEventsRequest.ProtoReflect.Descriptor instead. func (*GetEventsRequest) Descriptor() ([]byte, []int) { - return file_dashboard_v1alpha1_user_service_proto_rawDescGZIP(), []int{16} + return file_dashboard_v1alpha1_user_service_proto_rawDescGZIP(), []int{18} } func (x *GetEventsRequest) GetUserName() string { @@ -973,7 +1083,7 @@ type GetEventsResponse struct { func (x *GetEventsResponse) Reset() { *x = GetEventsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[17] + mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -986,7 +1096,7 @@ func (x *GetEventsResponse) String() string { func (*GetEventsResponse) ProtoMessage() {} func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { - mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[17] + mi := &file_dashboard_v1alpha1_user_service_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -999,7 +1109,7 @@ func (x *GetEventsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEventsResponse.ProtoReflect.Descriptor instead. func (*GetEventsResponse) Descriptor() ([]byte, []int) { - return file_dashboard_v1alpha1_user_service_proto_rawDescGZIP(), []int{17} + return file_dashboard_v1alpha1_user_service_proto_rawDescGZIP(), []int{19} } func (x *GetEventsResponse) GetMessage() string { @@ -1132,93 +1242,117 @@ var file_dashboard_v1alpha1_user_service_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x6d, 0x0a, 0x10, 0x47, - 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x04, - 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x88, 0x01, - 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x22, 0x5e, 0x0a, 0x11, 0x47, 0x65, - 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x32, 0x97, 0x07, 0x0a, 0x0b, 0x55, - 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x0a, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x26, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, - 0x65, 0x72, 0x12, 0x22, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x08, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x23, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, - 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x64, - 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x58, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, - 0x24, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0a, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x64, 0x61, 0x73, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x96, 0x01, 0x0a, 0x1d, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x4f, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x26, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x15, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x30, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, - 0x65, 0x72, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x2d, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x08, 0xfa, 0x42, + 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x22, 0x68, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x2c, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x6d, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x33, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x04, 0x66, 0x72, 0x6f, + 0x6d, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x22, 0x5e, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x0a, 0x05, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x61, + 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x32, 0x98, 0x08, + 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, + 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x64, 0x61, + 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x07, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x64, 0x61, 0x73, 0x68, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, + 0x0a, 0x08, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x23, 0x2e, 0x64, 0x61, 0x73, + 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x24, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x5b, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, - 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x64, + 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x15, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, + 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x12, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x12, 0x2d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2e, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x67, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, + 0x65, 0x12, 0x29, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x0e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x29, - 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x64, 0x61, 0x73, 0x68, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, - 0x73, 0x65, 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x64, 0x61, 0x73, 0x68, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x64, + 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x64, 0x64, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xe4, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x61, 0x73, - 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, - 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x12, 0x44, 0x61, 0x73, - 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, - 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1e, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, - 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x12, 0x31, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xe4, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, + 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2f, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, + 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xca, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, + 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1e, 0x44, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x44, 0x61, 0x73, 0x68, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1233,66 +1367,73 @@ func file_dashboard_v1alpha1_user_service_proto_rawDescGZIP() []byte { return file_dashboard_v1alpha1_user_service_proto_rawDescData } -var file_dashboard_v1alpha1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_dashboard_v1alpha1_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_dashboard_v1alpha1_user_service_proto_goTypes = []interface{}{ - (*DeleteUserRequest)(nil), // 0: dashboard.v1alpha1.DeleteUserRequest - (*DeleteUserResponse)(nil), // 1: dashboard.v1alpha1.DeleteUserResponse - (*GetUsersRequest)(nil), // 2: dashboard.v1alpha1.GetUsersRequest - (*GetUsersResponse)(nil), // 3: dashboard.v1alpha1.GetUsersResponse - (*GetUserRequest)(nil), // 4: dashboard.v1alpha1.GetUserRequest - (*GetUserResponse)(nil), // 5: dashboard.v1alpha1.GetUserResponse - (*CreateUserRequest)(nil), // 6: dashboard.v1alpha1.CreateUserRequest - (*CreateUserResponse)(nil), // 7: dashboard.v1alpha1.CreateUserResponse - (*UpdateUserDisplayNameRequest)(nil), // 8: dashboard.v1alpha1.UpdateUserDisplayNameRequest - (*UpdateUserDisplayNameResponse)(nil), // 9: dashboard.v1alpha1.UpdateUserDisplayNameResponse - (*UpdateUserPasswordRequest)(nil), // 10: dashboard.v1alpha1.UpdateUserPasswordRequest - (*UpdateUserPasswordResponse)(nil), // 11: dashboard.v1alpha1.UpdateUserPasswordResponse - (*UpdateUserRoleRequest)(nil), // 12: dashboard.v1alpha1.UpdateUserRoleRequest - (*UpdateUserRoleResponse)(nil), // 13: dashboard.v1alpha1.UpdateUserRoleResponse - (*UpdateUserAddonsRequest)(nil), // 14: dashboard.v1alpha1.UpdateUserAddonsRequest - (*UpdateUserAddonsResponse)(nil), // 15: dashboard.v1alpha1.UpdateUserAddonsResponse - (*GetEventsRequest)(nil), // 16: dashboard.v1alpha1.GetEventsRequest - (*GetEventsResponse)(nil), // 17: dashboard.v1alpha1.GetEventsResponse - (*User)(nil), // 18: dashboard.v1alpha1.User - (*UserAddon)(nil), // 19: dashboard.v1alpha1.UserAddon - (*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp - (*Event)(nil), // 21: dashboard.v1alpha1.Event + (*DeleteUserRequest)(nil), // 0: dashboard.v1alpha1.DeleteUserRequest + (*DeleteUserResponse)(nil), // 1: dashboard.v1alpha1.DeleteUserResponse + (*GetUsersRequest)(nil), // 2: dashboard.v1alpha1.GetUsersRequest + (*GetUsersResponse)(nil), // 3: dashboard.v1alpha1.GetUsersResponse + (*GetUserRequest)(nil), // 4: dashboard.v1alpha1.GetUserRequest + (*GetUserResponse)(nil), // 5: dashboard.v1alpha1.GetUserResponse + (*CreateUserRequest)(nil), // 6: dashboard.v1alpha1.CreateUserRequest + (*CreateUserResponse)(nil), // 7: dashboard.v1alpha1.CreateUserResponse + (*UpdateUserDisplayNameRequest)(nil), // 8: dashboard.v1alpha1.UpdateUserDisplayNameRequest + (*UpdateUserDisplayNameResponse)(nil), // 9: dashboard.v1alpha1.UpdateUserDisplayNameResponse + (*UpdateUserPasswordRequest)(nil), // 10: dashboard.v1alpha1.UpdateUserPasswordRequest + (*UpdateUserPasswordResponse)(nil), // 11: dashboard.v1alpha1.UpdateUserPasswordResponse + (*UpdateUserRoleRequest)(nil), // 12: dashboard.v1alpha1.UpdateUserRoleRequest + (*UpdateUserRoleResponse)(nil), // 13: dashboard.v1alpha1.UpdateUserRoleResponse + (*UpdateUserAddonsRequest)(nil), // 14: dashboard.v1alpha1.UpdateUserAddonsRequest + (*UpdateUserAddonsResponse)(nil), // 15: dashboard.v1alpha1.UpdateUserAddonsResponse + (*UpdateUserDeletePolicyRequest)(nil), // 16: dashboard.v1alpha1.UpdateUserDeletePolicyRequest + (*UpdateUserDeletePolicyResponse)(nil), // 17: dashboard.v1alpha1.UpdateUserDeletePolicyResponse + (*GetEventsRequest)(nil), // 18: dashboard.v1alpha1.GetEventsRequest + (*GetEventsResponse)(nil), // 19: dashboard.v1alpha1.GetEventsResponse + (*User)(nil), // 20: dashboard.v1alpha1.User + (*UserAddon)(nil), // 21: dashboard.v1alpha1.UserAddon + (DeletePolicy)(0), // 22: dashboard.v1alpha1.DeletePolicy + (*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp + (*Event)(nil), // 24: dashboard.v1alpha1.Event } var file_dashboard_v1alpha1_user_service_proto_depIdxs = []int32{ - 18, // 0: dashboard.v1alpha1.DeleteUserResponse.user:type_name -> dashboard.v1alpha1.User - 18, // 1: dashboard.v1alpha1.GetUsersResponse.items:type_name -> dashboard.v1alpha1.User - 18, // 2: dashboard.v1alpha1.GetUserResponse.user:type_name -> dashboard.v1alpha1.User - 19, // 3: dashboard.v1alpha1.CreateUserRequest.addons:type_name -> dashboard.v1alpha1.UserAddon - 18, // 4: dashboard.v1alpha1.CreateUserResponse.user:type_name -> dashboard.v1alpha1.User - 18, // 5: dashboard.v1alpha1.UpdateUserDisplayNameResponse.user:type_name -> dashboard.v1alpha1.User - 18, // 6: dashboard.v1alpha1.UpdateUserRoleResponse.user:type_name -> dashboard.v1alpha1.User - 19, // 7: dashboard.v1alpha1.UpdateUserAddonsRequest.addons:type_name -> dashboard.v1alpha1.UserAddon - 18, // 8: dashboard.v1alpha1.UpdateUserAddonsResponse.user:type_name -> dashboard.v1alpha1.User - 20, // 9: dashboard.v1alpha1.GetEventsRequest.from:type_name -> google.protobuf.Timestamp - 21, // 10: dashboard.v1alpha1.GetEventsResponse.items:type_name -> dashboard.v1alpha1.Event - 0, // 11: dashboard.v1alpha1.UserService.DeleteUser:input_type -> dashboard.v1alpha1.DeleteUserRequest - 4, // 12: dashboard.v1alpha1.UserService.GetUser:input_type -> dashboard.v1alpha1.GetUserRequest - 2, // 13: dashboard.v1alpha1.UserService.GetUsers:input_type -> dashboard.v1alpha1.GetUsersRequest - 16, // 14: dashboard.v1alpha1.UserService.GetEvents:input_type -> dashboard.v1alpha1.GetEventsRequest - 6, // 15: dashboard.v1alpha1.UserService.CreateUser:input_type -> dashboard.v1alpha1.CreateUserRequest - 8, // 16: dashboard.v1alpha1.UserService.UpdateUserDisplayName:input_type -> dashboard.v1alpha1.UpdateUserDisplayNameRequest - 10, // 17: dashboard.v1alpha1.UserService.UpdateUserPassword:input_type -> dashboard.v1alpha1.UpdateUserPasswordRequest - 12, // 18: dashboard.v1alpha1.UserService.UpdateUserRole:input_type -> dashboard.v1alpha1.UpdateUserRoleRequest - 14, // 19: dashboard.v1alpha1.UserService.UpdateUserAddons:input_type -> dashboard.v1alpha1.UpdateUserAddonsRequest - 1, // 20: dashboard.v1alpha1.UserService.DeleteUser:output_type -> dashboard.v1alpha1.DeleteUserResponse - 5, // 21: dashboard.v1alpha1.UserService.GetUser:output_type -> dashboard.v1alpha1.GetUserResponse - 3, // 22: dashboard.v1alpha1.UserService.GetUsers:output_type -> dashboard.v1alpha1.GetUsersResponse - 17, // 23: dashboard.v1alpha1.UserService.GetEvents:output_type -> dashboard.v1alpha1.GetEventsResponse - 7, // 24: dashboard.v1alpha1.UserService.CreateUser:output_type -> dashboard.v1alpha1.CreateUserResponse - 9, // 25: dashboard.v1alpha1.UserService.UpdateUserDisplayName:output_type -> dashboard.v1alpha1.UpdateUserDisplayNameResponse - 11, // 26: dashboard.v1alpha1.UserService.UpdateUserPassword:output_type -> dashboard.v1alpha1.UpdateUserPasswordResponse - 13, // 27: dashboard.v1alpha1.UserService.UpdateUserRole:output_type -> dashboard.v1alpha1.UpdateUserRoleResponse - 15, // 28: dashboard.v1alpha1.UserService.UpdateUserAddons:output_type -> dashboard.v1alpha1.UpdateUserAddonsResponse - 20, // [20:29] is the sub-list for method output_type - 11, // [11:20] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 20, // 0: dashboard.v1alpha1.DeleteUserResponse.user:type_name -> dashboard.v1alpha1.User + 20, // 1: dashboard.v1alpha1.GetUsersResponse.items:type_name -> dashboard.v1alpha1.User + 20, // 2: dashboard.v1alpha1.GetUserResponse.user:type_name -> dashboard.v1alpha1.User + 21, // 3: dashboard.v1alpha1.CreateUserRequest.addons:type_name -> dashboard.v1alpha1.UserAddon + 20, // 4: dashboard.v1alpha1.CreateUserResponse.user:type_name -> dashboard.v1alpha1.User + 20, // 5: dashboard.v1alpha1.UpdateUserDisplayNameResponse.user:type_name -> dashboard.v1alpha1.User + 20, // 6: dashboard.v1alpha1.UpdateUserRoleResponse.user:type_name -> dashboard.v1alpha1.User + 21, // 7: dashboard.v1alpha1.UpdateUserAddonsRequest.addons:type_name -> dashboard.v1alpha1.UserAddon + 20, // 8: dashboard.v1alpha1.UpdateUserAddonsResponse.user:type_name -> dashboard.v1alpha1.User + 22, // 9: dashboard.v1alpha1.UpdateUserDeletePolicyRequest.delete_policy:type_name -> dashboard.v1alpha1.DeletePolicy + 20, // 10: dashboard.v1alpha1.UpdateUserDeletePolicyResponse.user:type_name -> dashboard.v1alpha1.User + 23, // 11: dashboard.v1alpha1.GetEventsRequest.from:type_name -> google.protobuf.Timestamp + 24, // 12: dashboard.v1alpha1.GetEventsResponse.items:type_name -> dashboard.v1alpha1.Event + 0, // 13: dashboard.v1alpha1.UserService.DeleteUser:input_type -> dashboard.v1alpha1.DeleteUserRequest + 4, // 14: dashboard.v1alpha1.UserService.GetUser:input_type -> dashboard.v1alpha1.GetUserRequest + 2, // 15: dashboard.v1alpha1.UserService.GetUsers:input_type -> dashboard.v1alpha1.GetUsersRequest + 18, // 16: dashboard.v1alpha1.UserService.GetEvents:input_type -> dashboard.v1alpha1.GetEventsRequest + 6, // 17: dashboard.v1alpha1.UserService.CreateUser:input_type -> dashboard.v1alpha1.CreateUserRequest + 8, // 18: dashboard.v1alpha1.UserService.UpdateUserDisplayName:input_type -> dashboard.v1alpha1.UpdateUserDisplayNameRequest + 10, // 19: dashboard.v1alpha1.UserService.UpdateUserPassword:input_type -> dashboard.v1alpha1.UpdateUserPasswordRequest + 12, // 20: dashboard.v1alpha1.UserService.UpdateUserRole:input_type -> dashboard.v1alpha1.UpdateUserRoleRequest + 14, // 21: dashboard.v1alpha1.UserService.UpdateUserAddons:input_type -> dashboard.v1alpha1.UpdateUserAddonsRequest + 16, // 22: dashboard.v1alpha1.UserService.UpdateUserDeletePolicy:input_type -> dashboard.v1alpha1.UpdateUserDeletePolicyRequest + 1, // 23: dashboard.v1alpha1.UserService.DeleteUser:output_type -> dashboard.v1alpha1.DeleteUserResponse + 5, // 24: dashboard.v1alpha1.UserService.GetUser:output_type -> dashboard.v1alpha1.GetUserResponse + 3, // 25: dashboard.v1alpha1.UserService.GetUsers:output_type -> dashboard.v1alpha1.GetUsersResponse + 19, // 26: dashboard.v1alpha1.UserService.GetEvents:output_type -> dashboard.v1alpha1.GetEventsResponse + 7, // 27: dashboard.v1alpha1.UserService.CreateUser:output_type -> dashboard.v1alpha1.CreateUserResponse + 9, // 28: dashboard.v1alpha1.UserService.UpdateUserDisplayName:output_type -> dashboard.v1alpha1.UpdateUserDisplayNameResponse + 11, // 29: dashboard.v1alpha1.UserService.UpdateUserPassword:output_type -> dashboard.v1alpha1.UpdateUserPasswordResponse + 13, // 30: dashboard.v1alpha1.UserService.UpdateUserRole:output_type -> dashboard.v1alpha1.UpdateUserRoleResponse + 15, // 31: dashboard.v1alpha1.UserService.UpdateUserAddons:output_type -> dashboard.v1alpha1.UpdateUserAddonsResponse + 17, // 32: dashboard.v1alpha1.UserService.UpdateUserDeletePolicy:output_type -> dashboard.v1alpha1.UpdateUserDeletePolicyResponse + 23, // [23:33] is the sub-list for method output_type + 13, // [13:23] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_dashboard_v1alpha1_user_service_proto_init() } @@ -1496,7 +1637,7 @@ func file_dashboard_v1alpha1_user_service_proto_init() { } } file_dashboard_v1alpha1_user_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetEventsRequest); i { + switch v := v.(*UpdateUserDeletePolicyRequest); i { case 0: return &v.state case 1: @@ -1508,6 +1649,30 @@ func file_dashboard_v1alpha1_user_service_proto_init() { } } file_dashboard_v1alpha1_user_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserDeletePolicyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dashboard_v1alpha1_user_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEventsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dashboard_v1alpha1_user_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetEventsResponse); i { case 0: return &v.state @@ -1522,14 +1687,14 @@ func file_dashboard_v1alpha1_user_service_proto_init() { } file_dashboard_v1alpha1_user_service_proto_msgTypes[2].OneofWrappers = []interface{}{} file_dashboard_v1alpha1_user_service_proto_msgTypes[4].OneofWrappers = []interface{}{} - file_dashboard_v1alpha1_user_service_proto_msgTypes[16].OneofWrappers = []interface{}{} + file_dashboard_v1alpha1_user_service_proto_msgTypes[18].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_dashboard_v1alpha1_user_service_proto_rawDesc, NumEnums: 0, - NumMessages: 18, + NumMessages: 20, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/dashboard/v1alpha1/user_service.pb.validate.go b/proto/gen/dashboard/v1alpha1/user_service.pb.validate.go index 0a290abf..e679f82c 100644 --- a/proto/gen/dashboard/v1alpha1/user_service.pb.validate.go +++ b/proto/gen/dashboard/v1alpha1/user_service.pb.validate.go @@ -2079,6 +2079,265 @@ var _ interface { ErrorName() string } = UpdateUserAddonsResponseValidationError{} +// Validate checks the field values on UpdateUserDeletePolicyRequest 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 *UpdateUserDeletePolicyRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateUserDeletePolicyRequest 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 +// UpdateUserDeletePolicyRequestMultiError, or nil if none found. +func (m *UpdateUserDeletePolicyRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateUserDeletePolicyRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if utf8.RuneCountInString(m.GetUserName()) < 1 { + err := UpdateUserDeletePolicyRequestValidationError{ + field: "UserName", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + if _, ok := DeletePolicy_name[int32(m.GetDeletePolicy())]; !ok { + err := UpdateUserDeletePolicyRequestValidationError{ + field: "DeletePolicy", + reason: "value must be one of the defined enum values", + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return UpdateUserDeletePolicyRequestMultiError(errors) + } + + return nil +} + +// UpdateUserDeletePolicyRequestMultiError is an error wrapping multiple +// validation errors returned by UpdateUserDeletePolicyRequest.ValidateAll() +// if the designated constraints aren't met. +type UpdateUserDeletePolicyRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateUserDeletePolicyRequestMultiError) 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 UpdateUserDeletePolicyRequestMultiError) AllErrors() []error { return m } + +// UpdateUserDeletePolicyRequestValidationError is the validation error +// returned by UpdateUserDeletePolicyRequest.Validate if the designated +// constraints aren't met. +type UpdateUserDeletePolicyRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateUserDeletePolicyRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateUserDeletePolicyRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateUserDeletePolicyRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateUserDeletePolicyRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateUserDeletePolicyRequestValidationError) ErrorName() string { + return "UpdateUserDeletePolicyRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateUserDeletePolicyRequestValidationError) 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 %sUpdateUserDeletePolicyRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateUserDeletePolicyRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateUserDeletePolicyRequestValidationError{} + +// Validate checks the field values on UpdateUserDeletePolicyResponse 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 *UpdateUserDeletePolicyResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateUserDeletePolicyResponse 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 +// UpdateUserDeletePolicyResponseMultiError, or nil if none found. +func (m *UpdateUserDeletePolicyResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateUserDeletePolicyResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Message + + if all { + switch v := interface{}(m.GetUser()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, UpdateUserDeletePolicyResponseValidationError{ + field: "User", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, UpdateUserDeletePolicyResponseValidationError{ + field: "User", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetUser()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return UpdateUserDeletePolicyResponseValidationError{ + field: "User", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return UpdateUserDeletePolicyResponseMultiError(errors) + } + + return nil +} + +// UpdateUserDeletePolicyResponseMultiError is an error wrapping multiple +// validation errors returned by UpdateUserDeletePolicyResponse.ValidateAll() +// if the designated constraints aren't met. +type UpdateUserDeletePolicyResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateUserDeletePolicyResponseMultiError) 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 UpdateUserDeletePolicyResponseMultiError) AllErrors() []error { return m } + +// UpdateUserDeletePolicyResponseValidationError is the validation error +// returned by UpdateUserDeletePolicyResponse.Validate if the designated +// constraints aren't met. +type UpdateUserDeletePolicyResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateUserDeletePolicyResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateUserDeletePolicyResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateUserDeletePolicyResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateUserDeletePolicyResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateUserDeletePolicyResponseValidationError) ErrorName() string { + return "UpdateUserDeletePolicyResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateUserDeletePolicyResponseValidationError) 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 %sUpdateUserDeletePolicyResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateUserDeletePolicyResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateUserDeletePolicyResponseValidationError{} + // Validate checks the field values on GetEventsRequest 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. diff --git a/proto/gen/dashboard/v1alpha1/workspace.pb.go b/proto/gen/dashboard/v1alpha1/workspace.pb.go index 0e0c5772..b698fe05 100644 --- a/proto/gen/dashboard/v1alpha1/workspace.pb.go +++ b/proto/gen/dashboard/v1alpha1/workspace.pb.go @@ -252,12 +252,14 @@ type Workspace struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - OwnerName string `protobuf:"bytes,2,opt,name=owner_name,json=ownerName,proto3" json:"owner_name,omitempty"` - Spec *WorkspaceSpec `protobuf:"bytes,3,opt,name=spec,proto3" json:"spec,omitempty"` - Status *WorkspaceStatus `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` - Raw *string `protobuf:"bytes,5,opt,name=raw,proto3,oneof" json:"raw,omitempty"` - RawInstance *string `protobuf:"bytes,6,opt,name=raw_instance,json=rawInstance,proto3,oneof" json:"raw_instance,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + OwnerName string `protobuf:"bytes,2,opt,name=owner_name,json=ownerName,proto3" json:"owner_name,omitempty"` + Spec *WorkspaceSpec `protobuf:"bytes,3,opt,name=spec,proto3" json:"spec,omitempty"` + Status *WorkspaceStatus `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` + Raw *string `protobuf:"bytes,5,opt,name=raw,proto3,oneof" json:"raw,omitempty"` + RawInstance *string `protobuf:"bytes,6,opt,name=raw_instance,json=rawInstance,proto3,oneof" json:"raw_instance,omitempty"` + RawIngressRoute *string `protobuf:"bytes,7,opt,name=raw_ingress_route,json=rawIngressRoute,proto3,oneof" json:"raw_ingress_route,omitempty"` + DeletePolicy *DeletePolicy `protobuf:"varint,8,opt,name=delete_policy,json=deletePolicy,proto3,enum=dashboard.v1alpha1.DeletePolicy,oneof" json:"delete_policy,omitempty"` } func (x *Workspace) Reset() { @@ -334,6 +336,20 @@ func (x *Workspace) GetRawInstance() string { return "" } +func (x *Workspace) GetRawIngressRoute() string { + if x != nil && x.RawIngressRoute != nil { + return *x.RawIngressRoute + } + return "" +} + +func (x *Workspace) GetDeletePolicy() DeletePolicy { + if x != nil && x.DeletePolicy != nil { + return *x.DeletePolicy + } + return DeletePolicy_delete +} + var File_dashboard_v1alpha1_workspace_proto protoreflect.FileDescriptor var file_dashboard_v1alpha1_workspace_proto_rawDesc = []byte{ @@ -344,76 +360,89 @@ var file_dashboard_v1alpha1_workspace_proto_rawDesc = []byte{ 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xd5, 0x01, 0x0a, 0x0b, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, - 0x6c, 0x65, 0x12, 0x2c, 0x0a, 0x0b, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x1a, 0x06, 0x10, 0x80, - 0x80, 0x04, 0x20, 0x00, 0x52, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, - 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x75, - 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1b, - 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x50, 0x61, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x75, - 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, - 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, - 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x0d, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x73, 0x12, 0x3f, 0x0a, 0x04, 0x76, 0x61, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x04, 0x76, 0x61, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x1a, 0x37, 0x0a, 0x09, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x86, 0x01, 0x0a, 0x0f, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, - 0x05, 0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, - 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x61, 0x69, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x42, - 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 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, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, + 0x74, 0x6f, 0x1a, 0x1d, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2f, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xd5, 0x01, 0x0a, 0x0b, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, + 0x65, 0x12, 0x2c, 0x0a, 0x0b, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x1a, 0x06, 0x10, 0x80, 0x80, + 0x04, 0x20, 0x00, 0x52, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, + 0x2c, 0x0a, 0x12, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x70, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1b, 0x0a, + 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x50, 0x61, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x0d, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x73, 0x12, 0x3f, 0x0a, 0x04, 0x76, 0x61, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x61, 0x73, - 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x88, 0x01, 0x01, 0x12, 0x26, - 0x0a, 0x0c, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0b, 0x72, 0x61, 0x77, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x72, 0x61, 0x77, 0x42, 0x0f, - 0x0a, 0x0d, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x42, - 0xe2, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0e, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, 0x77, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, 0x68, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, - 0x44, 0x58, 0x58, 0xaa, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, - 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1e, - 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x13, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x70, 0x65, 0x63, 0x2e, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, + 0x76, 0x61, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x1a, + 0x37, 0x0a, 0x09, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x86, 0x01, 0x0a, 0x0f, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x70, 0x68, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x61, + 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x61, 0x69, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x42, 0x0a, + 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 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, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x22, 0xb9, 0x03, 0x0a, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, + 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x61, 0x73, 0x68, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x88, 0x01, 0x01, 0x12, 0x26, 0x0a, + 0x0c, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0b, 0x72, 0x61, 0x77, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x02, 0x52, 0x0f, 0x72, 0x61, 0x77, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x54, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, + 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x48, 0x03, 0x52, 0x0c, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, + 0x5f, 0x72, 0x61, 0x77, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x42, 0x10, 0x0a, 0x0e, 0x5f, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0xe2, 0x01, + 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, + 0x58, 0xaa, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x56, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1e, 0x44, 0x61, + 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x44, + 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -436,6 +465,7 @@ var file_dashboard_v1alpha1_workspace_proto_goTypes = []interface{}{ (*Workspace)(nil), // 3: dashboard.v1alpha1.Workspace nil, // 4: dashboard.v1alpha1.WorkspaceSpec.VarsEntry (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp + (DeletePolicy)(0), // 6: dashboard.v1alpha1.DeletePolicy } var file_dashboard_v1alpha1_workspace_proto_depIdxs = []int32{ 4, // 0: dashboard.v1alpha1.WorkspaceSpec.vars:type_name -> dashboard.v1alpha1.WorkspaceSpec.VarsEntry @@ -443,11 +473,12 @@ var file_dashboard_v1alpha1_workspace_proto_depIdxs = []int32{ 5, // 2: dashboard.v1alpha1.WorkspaceStatus.last_started_at:type_name -> google.protobuf.Timestamp 1, // 3: dashboard.v1alpha1.Workspace.spec:type_name -> dashboard.v1alpha1.WorkspaceSpec 2, // 4: dashboard.v1alpha1.Workspace.status:type_name -> dashboard.v1alpha1.WorkspaceStatus - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] 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 + 6, // 5: dashboard.v1alpha1.Workspace.delete_policy:type_name -> dashboard.v1alpha1.DeletePolicy + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] 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_dashboard_v1alpha1_workspace_proto_init() } @@ -455,6 +486,7 @@ func file_dashboard_v1alpha1_workspace_proto_init() { if File_dashboard_v1alpha1_workspace_proto != nil { return } + file_dashboard_v1alpha1_user_proto_init() if !protoimpl.UnsafeEnabled { file_dashboard_v1alpha1_workspace_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*NetworkRule); i { diff --git a/proto/gen/dashboard/v1alpha1/workspace.pb.validate.go b/proto/gen/dashboard/v1alpha1/workspace.pb.validate.go index 1c12902c..fd66d578 100644 --- a/proto/gen/dashboard/v1alpha1/workspace.pb.validate.go +++ b/proto/gen/dashboard/v1alpha1/workspace.pb.validate.go @@ -518,6 +518,25 @@ func (m *Workspace) validate(all bool) error { // no validation rules for RawInstance } + if m.RawIngressRoute != nil { + // no validation rules for RawIngressRoute + } + + if m.DeletePolicy != nil { + + if _, ok := DeletePolicy_name[int32(m.GetDeletePolicy())]; !ok { + err := WorkspaceValidationError{ + field: "DeletePolicy", + reason: "value must be one of the defined enum values", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + if len(errors) > 0 { return WorkspaceMultiError(errors) } diff --git a/proto/gen/dashboard/v1alpha1/workspace_service.pb.go b/proto/gen/dashboard/v1alpha1/workspace_service.pb.go index 760bb3be..00842980 100644 --- a/proto/gen/dashboard/v1alpha1/workspace_service.pb.go +++ b/proto/gen/dashboard/v1alpha1/workspace_service.pb.go @@ -266,10 +266,11 @@ type UpdateWorkspaceRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - UserName string `protobuf:"bytes,1,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` - WsName string `protobuf:"bytes,2,opt,name=ws_name,json=wsName,proto3" json:"ws_name,omitempty"` - Replicas *int64 `protobuf:"varint,3,opt,name=replicas,proto3,oneof" json:"replicas,omitempty"` - Vars map[string]string `protobuf:"bytes,4,rep,name=vars,proto3" json:"vars,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + UserName string `protobuf:"bytes,1,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + WsName string `protobuf:"bytes,2,opt,name=ws_name,json=wsName,proto3" json:"ws_name,omitempty"` + Replicas *int64 `protobuf:"varint,3,opt,name=replicas,proto3,oneof" json:"replicas,omitempty"` + Vars map[string]string `protobuf:"bytes,4,rep,name=vars,proto3" json:"vars,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + DeletePolicy *DeletePolicy `protobuf:"varint,5,opt,name=delete_policy,json=deletePolicy,proto3,enum=dashboard.v1alpha1.DeletePolicy,oneof" json:"delete_policy,omitempty"` } func (x *UpdateWorkspaceRequest) Reset() { @@ -332,6 +333,13 @@ func (x *UpdateWorkspaceRequest) GetVars() map[string]string { return nil } +func (x *UpdateWorkspaceRequest) GetDeletePolicy() DeletePolicy { + if x != nil && x.DeletePolicy != nil { + return *x.DeletePolicy + } + return DeletePolicy_delete +} + type UpdateWorkspaceResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -869,198 +877,206 @@ var file_dashboard_v1alpha1_workspace_service_proto_rawDesc = []byte{ 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x22, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x02, - 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x02, 0x0a, + 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, + 0x02, 0x10, 0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, + 0x07, 0x77, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x23, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x04, 0x76, 0x61, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, + 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x76, 0x61, 0x72, 0x73, 0x1a, 0x37, + 0x0a, 0x09, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x70, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x09, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x60, 0x0a, 0x16, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x07, 0x77, 0x73, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, + 0x02, 0x10, 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x79, 0x0a, 0x19, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x72, 0x75, + 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x22, 0xf9, 0x02, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x24, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x07, 0x77, 0x73, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x72, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x72, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x88, 0x01, 0x01, 0x12, 0x48, 0x0a, 0x04, 0x76, 0x61, + 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, + 0x76, 0x61, 0x72, 0x73, 0x12, 0x54, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x61, + 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x08, 0xfa, + 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x48, 0x01, 0x52, 0x0c, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x88, 0x01, 0x01, 0x1a, 0x37, 0x0a, 0x09, 0x56, 0x61, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, + 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x22, 0x70, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x73, + 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x22, 0x78, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x77, 0x73, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x1e, 0x0a, 0x08, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x77, 0x69, 0x74, 0x68, 0x52, 0x61, 0x77, 0x88, 0x01, + 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x61, 0x77, 0x22, 0x53, + 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x73, 0x68, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x22, 0x9d, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x08, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x77, + 0x69, 0x74, 0x68, 0x52, 0x61, 0x77, 0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x0d, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x48, 0x01, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, + 0x64, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x61, + 0x77, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x64, 0x22, 0x66, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0xbc, 0x01, 0x0a, 0x18, + 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x07, 0x77, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x23, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x74, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x04, 0x76, 0x61, 0x72, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, - 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x76, 0x61, 0x72, 0x73, 0x1a, - 0x37, 0x0a, 0x09, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x70, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, - 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x60, 0x0a, 0x16, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x07, 0x77, 0x73, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x79, 0x0a, 0x19, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x72, - 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x73, 0x68, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x91, 0x02, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x07, 0x77, 0x73, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, - 0x10, 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x72, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, - 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x88, 0x01, 0x01, 0x12, 0x48, 0x0a, 0x04, 0x76, - 0x61, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x64, 0x61, 0x73, 0x68, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x04, 0x76, 0x61, 0x72, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0b, - 0x0a, 0x09, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x22, 0x70, 0x0a, 0x17, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x3b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x78, 0x0a, - 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x17, 0x0a, 0x07, 0x77, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x08, 0x77, 0x69, - 0x74, 0x68, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, - 0x77, 0x69, 0x74, 0x68, 0x52, 0x61, 0x77, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, - 0x69, 0x74, 0x68, 0x5f, 0x72, 0x61, 0x77, 0x22, 0x53, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x3b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x9d, 0x01, 0x0a, - 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x08, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x77, 0x69, 0x74, 0x68, 0x52, 0x61, 0x77, 0x88, - 0x01, 0x01, 0x12, 0x29, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x0d, 0x69, 0x6e, 0x63, - 0x6c, 0x75, 0x64, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, - 0x09, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x72, 0x61, 0x77, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x22, 0x66, 0x0a, 0x15, - 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x33, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, - 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x22, 0xbc, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4e, + 0x12, 0x42, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x72, 0x75, 0x6c, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x79, 0x0a, 0x19, 0x55, 0x70, + 0x73, 0x65, 0x72, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x78, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x07, 0x77, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, - 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, - 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x22, 0x79, 0x0a, 0x19, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x78, - 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, - 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, - 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x20, 0x0a, 0x07, 0x77, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x70, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, - 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x32, 0x83, 0x06, 0x0a, 0x10, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x6a, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, - 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x0f, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2a, - 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x64, 0x61, 0x73, + 0x01, 0x52, 0x06, 0x77, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, + 0x70, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x32, 0x83, 0x06, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x73, 0x68, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2b, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, + 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0c, 0x47, 0x65, + 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x27, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2a, 0x2e, 0x64, 0x61, 0x73, - 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x27, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, + 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x64, - 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, - 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x29, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x11, - 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, - 0x65, 0x12, 0x2c, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, - 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, - 0x75, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x42, 0xe9, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x15, 0x57, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, - 0x2f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, 0xaa, 0x02, 0x12, 0x44, 0x61, - 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0xca, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1e, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, + 0x0d, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x28, + 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x11, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x73, 0x65, 0x72, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, + 0x72, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x70, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x64, 0x61, 0x73, + 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xe9, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, + 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x42, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, 0x68, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x44, + 0x58, 0x58, 0xaa, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1e, 0x44, + 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, + 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1095,37 +1111,39 @@ var file_dashboard_v1alpha1_workspace_service_proto_goTypes = []interface{}{ nil, // 15: dashboard.v1alpha1.UpdateWorkspaceRequest.VarsEntry (*Workspace)(nil), // 16: dashboard.v1alpha1.Workspace (*NetworkRule)(nil), // 17: dashboard.v1alpha1.NetworkRule + (DeletePolicy)(0), // 18: dashboard.v1alpha1.DeletePolicy } var file_dashboard_v1alpha1_workspace_service_proto_depIdxs = []int32{ 14, // 0: dashboard.v1alpha1.CreateWorkspaceRequest.vars:type_name -> dashboard.v1alpha1.CreateWorkspaceRequest.VarsEntry 16, // 1: dashboard.v1alpha1.CreateWorkspaceResponse.workspace:type_name -> dashboard.v1alpha1.Workspace 17, // 2: dashboard.v1alpha1.DeleteNetworkRuleResponse.network_rule:type_name -> dashboard.v1alpha1.NetworkRule 15, // 3: dashboard.v1alpha1.UpdateWorkspaceRequest.vars:type_name -> dashboard.v1alpha1.UpdateWorkspaceRequest.VarsEntry - 16, // 4: dashboard.v1alpha1.UpdateWorkspaceResponse.workspace:type_name -> dashboard.v1alpha1.Workspace - 16, // 5: dashboard.v1alpha1.GetWorkspaceResponse.workspace:type_name -> dashboard.v1alpha1.Workspace - 16, // 6: dashboard.v1alpha1.GetWorkspacesResponse.items:type_name -> dashboard.v1alpha1.Workspace - 17, // 7: dashboard.v1alpha1.UpsertNetworkRuleRequest.network_rule:type_name -> dashboard.v1alpha1.NetworkRule - 17, // 8: dashboard.v1alpha1.UpsertNetworkRuleResponse.network_rule:type_name -> dashboard.v1alpha1.NetworkRule - 16, // 9: dashboard.v1alpha1.DeleteWorkspaceResponse.workspace:type_name -> dashboard.v1alpha1.Workspace - 0, // 10: dashboard.v1alpha1.WorkspaceService.CreateWorkspace:input_type -> dashboard.v1alpha1.CreateWorkspaceRequest - 2, // 11: dashboard.v1alpha1.WorkspaceService.DeleteWorkspace:input_type -> dashboard.v1alpha1.DeleteWorkspaceRequest - 4, // 12: dashboard.v1alpha1.WorkspaceService.UpdateWorkspace:input_type -> dashboard.v1alpha1.UpdateWorkspaceRequest - 6, // 13: dashboard.v1alpha1.WorkspaceService.GetWorkspace:input_type -> dashboard.v1alpha1.GetWorkspaceRequest - 8, // 14: dashboard.v1alpha1.WorkspaceService.GetWorkspaces:input_type -> dashboard.v1alpha1.GetWorkspacesRequest - 10, // 15: dashboard.v1alpha1.WorkspaceService.UpsertNetworkRule:input_type -> dashboard.v1alpha1.UpsertNetworkRuleRequest - 12, // 16: dashboard.v1alpha1.WorkspaceService.DeleteNetworkRule:input_type -> dashboard.v1alpha1.DeleteNetworkRuleRequest - 1, // 17: dashboard.v1alpha1.WorkspaceService.CreateWorkspace:output_type -> dashboard.v1alpha1.CreateWorkspaceResponse - 13, // 18: dashboard.v1alpha1.WorkspaceService.DeleteWorkspace:output_type -> dashboard.v1alpha1.DeleteWorkspaceResponse - 5, // 19: dashboard.v1alpha1.WorkspaceService.UpdateWorkspace:output_type -> dashboard.v1alpha1.UpdateWorkspaceResponse - 7, // 20: dashboard.v1alpha1.WorkspaceService.GetWorkspace:output_type -> dashboard.v1alpha1.GetWorkspaceResponse - 9, // 21: dashboard.v1alpha1.WorkspaceService.GetWorkspaces:output_type -> dashboard.v1alpha1.GetWorkspacesResponse - 11, // 22: dashboard.v1alpha1.WorkspaceService.UpsertNetworkRule:output_type -> dashboard.v1alpha1.UpsertNetworkRuleResponse - 3, // 23: dashboard.v1alpha1.WorkspaceService.DeleteNetworkRule:output_type -> dashboard.v1alpha1.DeleteNetworkRuleResponse - 17, // [17:24] is the sub-list for method output_type - 10, // [10:17] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 18, // 4: dashboard.v1alpha1.UpdateWorkspaceRequest.delete_policy:type_name -> dashboard.v1alpha1.DeletePolicy + 16, // 5: dashboard.v1alpha1.UpdateWorkspaceResponse.workspace:type_name -> dashboard.v1alpha1.Workspace + 16, // 6: dashboard.v1alpha1.GetWorkspaceResponse.workspace:type_name -> dashboard.v1alpha1.Workspace + 16, // 7: dashboard.v1alpha1.GetWorkspacesResponse.items:type_name -> dashboard.v1alpha1.Workspace + 17, // 8: dashboard.v1alpha1.UpsertNetworkRuleRequest.network_rule:type_name -> dashboard.v1alpha1.NetworkRule + 17, // 9: dashboard.v1alpha1.UpsertNetworkRuleResponse.network_rule:type_name -> dashboard.v1alpha1.NetworkRule + 16, // 10: dashboard.v1alpha1.DeleteWorkspaceResponse.workspace:type_name -> dashboard.v1alpha1.Workspace + 0, // 11: dashboard.v1alpha1.WorkspaceService.CreateWorkspace:input_type -> dashboard.v1alpha1.CreateWorkspaceRequest + 2, // 12: dashboard.v1alpha1.WorkspaceService.DeleteWorkspace:input_type -> dashboard.v1alpha1.DeleteWorkspaceRequest + 4, // 13: dashboard.v1alpha1.WorkspaceService.UpdateWorkspace:input_type -> dashboard.v1alpha1.UpdateWorkspaceRequest + 6, // 14: dashboard.v1alpha1.WorkspaceService.GetWorkspace:input_type -> dashboard.v1alpha1.GetWorkspaceRequest + 8, // 15: dashboard.v1alpha1.WorkspaceService.GetWorkspaces:input_type -> dashboard.v1alpha1.GetWorkspacesRequest + 10, // 16: dashboard.v1alpha1.WorkspaceService.UpsertNetworkRule:input_type -> dashboard.v1alpha1.UpsertNetworkRuleRequest + 12, // 17: dashboard.v1alpha1.WorkspaceService.DeleteNetworkRule:input_type -> dashboard.v1alpha1.DeleteNetworkRuleRequest + 1, // 18: dashboard.v1alpha1.WorkspaceService.CreateWorkspace:output_type -> dashboard.v1alpha1.CreateWorkspaceResponse + 13, // 19: dashboard.v1alpha1.WorkspaceService.DeleteWorkspace:output_type -> dashboard.v1alpha1.DeleteWorkspaceResponse + 5, // 20: dashboard.v1alpha1.WorkspaceService.UpdateWorkspace:output_type -> dashboard.v1alpha1.UpdateWorkspaceResponse + 7, // 21: dashboard.v1alpha1.WorkspaceService.GetWorkspace:output_type -> dashboard.v1alpha1.GetWorkspaceResponse + 9, // 22: dashboard.v1alpha1.WorkspaceService.GetWorkspaces:output_type -> dashboard.v1alpha1.GetWorkspacesResponse + 11, // 23: dashboard.v1alpha1.WorkspaceService.UpsertNetworkRule:output_type -> dashboard.v1alpha1.UpsertNetworkRuleResponse + 3, // 24: dashboard.v1alpha1.WorkspaceService.DeleteNetworkRule:output_type -> dashboard.v1alpha1.DeleteNetworkRuleResponse + 18, // [18:25] is the sub-list for method output_type + 11, // [11:18] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_dashboard_v1alpha1_workspace_service_proto_init() } @@ -1134,6 +1152,7 @@ func file_dashboard_v1alpha1_workspace_service_proto_init() { return } file_dashboard_v1alpha1_workspace_proto_init() + file_dashboard_v1alpha1_user_proto_init() if !protoimpl.UnsafeEnabled { file_dashboard_v1alpha1_workspace_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateWorkspaceRequest); i { diff --git a/proto/gen/dashboard/v1alpha1/workspace_service.pb.validate.go b/proto/gen/dashboard/v1alpha1/workspace_service.pb.validate.go index 08888d13..ed08c6fd 100644 --- a/proto/gen/dashboard/v1alpha1/workspace_service.pb.validate.go +++ b/proto/gen/dashboard/v1alpha1/workspace_service.pb.validate.go @@ -612,6 +612,21 @@ func (m *UpdateWorkspaceRequest) validate(all bool) error { // no validation rules for Replicas } + if m.DeletePolicy != nil { + + if _, ok := DeletePolicy_name[int32(m.GetDeletePolicy())]; !ok { + err := UpdateWorkspaceRequestValidationError{ + field: "DeletePolicy", + reason: "value must be one of the defined enum values", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + if len(errors) > 0 { return UpdateWorkspaceRequestMultiError(errors) } diff --git a/proto/gen/index.md b/proto/gen/index.md index dcc02a69..30794401 100644 --- a/proto/gen/index.md +++ b/proto/gen/index.md @@ -21,6 +21,8 @@ - [UserAddon](#dashboard-v1alpha1-UserAddon) - [UserAddon.VarsEntry](#dashboard-v1alpha1-UserAddon-VarsEntry) + - [DeletePolicy](#dashboard-v1alpha1-DeletePolicy) + - [dashboard/v1alpha1/user_service.proto](#dashboard_v1alpha1_user_service-proto) - [CreateUserRequest](#dashboard-v1alpha1-CreateUserRequest) - [CreateUserResponse](#dashboard-v1alpha1-CreateUserResponse) @@ -34,6 +36,8 @@ - [GetUsersResponse](#dashboard-v1alpha1-GetUsersResponse) - [UpdateUserAddonsRequest](#dashboard-v1alpha1-UpdateUserAddonsRequest) - [UpdateUserAddonsResponse](#dashboard-v1alpha1-UpdateUserAddonsResponse) + - [UpdateUserDeletePolicyRequest](#dashboard-v1alpha1-UpdateUserDeletePolicyRequest) + - [UpdateUserDeletePolicyResponse](#dashboard-v1alpha1-UpdateUserDeletePolicyResponse) - [UpdateUserDisplayNameRequest](#dashboard-v1alpha1-UpdateUserDisplayNameRequest) - [UpdateUserDisplayNameResponse](#dashboard-v1alpha1-UpdateUserDisplayNameResponse) - [UpdateUserPasswordRequest](#dashboard-v1alpha1-UpdateUserPasswordRequest) @@ -299,6 +303,7 @@ | default_password | [string](#string) | | | | status | [string](#string) | | | | raw | [string](#string) | optional | | +| delete_policy | [DeletePolicy](#dashboard-v1alpha1-DeletePolicy) | optional | | @@ -340,6 +345,18 @@ + + + +### DeletePolicy + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| delete | 0 | | +| keep | 1 | | + + @@ -547,6 +564,38 @@ + + +### UpdateUserDeletePolicyRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| user_name | [string](#string) | | | +| delete_policy | [DeletePolicy](#dashboard-v1alpha1-DeletePolicy) | | | + + + + + + + + +### UpdateUserDeletePolicyResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| message | [string](#string) | | | +| user | [User](#dashboard-v1alpha1-User) | | | + + + + + + ### UpdateUserDisplayNameRequest @@ -665,6 +714,7 @@ | UpdateUserPassword | [UpdateUserPasswordRequest](#dashboard-v1alpha1-UpdateUserPasswordRequest) | [UpdateUserPasswordResponse](#dashboard-v1alpha1-UpdateUserPasswordResponse) | Update a single User password | | UpdateUserRole | [UpdateUserRoleRequest](#dashboard-v1alpha1-UpdateUserRoleRequest) | [UpdateUserRoleResponse](#dashboard-v1alpha1-UpdateUserRoleResponse) | Update a single User role | | UpdateUserAddons | [UpdateUserAddonsRequest](#dashboard-v1alpha1-UpdateUserAddonsRequest) | [UpdateUserAddonsResponse](#dashboard-v1alpha1-UpdateUserAddonsResponse) | Update a single User role | +| UpdateUserDeletePolicy | [UpdateUserDeletePolicyRequest](#dashboard-v1alpha1-UpdateUserDeletePolicyRequest) | [UpdateUserDeletePolicyResponse](#dashboard-v1alpha1-UpdateUserDeletePolicyResponse) | Update user delete policy | @@ -1148,6 +1198,8 @@ | status | [WorkspaceStatus](#dashboard-v1alpha1-WorkspaceStatus) | | | | raw | [string](#string) | optional | | | raw_instance | [string](#string) | optional | | +| raw_ingress_route | [string](#string) | optional | | +| delete_policy | [DeletePolicy](#dashboard-v1alpha1-DeletePolicy) | optional | | @@ -1413,6 +1465,7 @@ | ws_name | [string](#string) | | | | replicas | [int64](#int64) | optional | | | vars | [UpdateWorkspaceRequest.VarsEntry](#dashboard-v1alpha1-UpdateWorkspaceRequest-VarsEntry) | repeated | | +| delete_policy | [DeletePolicy](#dashboard-v1alpha1-DeletePolicy) | optional | | diff --git a/proto/proto/dashboard-apis/dashboard/v1alpha1/user.proto b/proto/proto/dashboard-apis/dashboard/v1alpha1/user.proto index 85f13554..76a177a3 100644 --- a/proto/proto/dashboard-apis/dashboard/v1alpha1/user.proto +++ b/proto/proto/dashboard-apis/dashboard/v1alpha1/user.proto @@ -18,6 +18,7 @@ message User { string default_password = 6; string status = 7; optional string raw = 8; + optional DeletePolicy delete_policy = 9 [(validate.rules).enum.defined_only = true]; } message UserAddon { @@ -26,3 +27,8 @@ message UserAddon { map vars = 3; optional string raw = 4; } + +enum DeletePolicy { + delete = 0; + keep = 1; +} \ No newline at end of file diff --git a/proto/proto/dashboard-apis/dashboard/v1alpha1/user_service.proto b/proto/proto/dashboard-apis/dashboard/v1alpha1/user_service.proto index ccac148a..79dfba6d 100644 --- a/proto/proto/dashboard-apis/dashboard/v1alpha1/user_service.proto +++ b/proto/proto/dashboard-apis/dashboard/v1alpha1/user_service.proto @@ -34,6 +34,9 @@ service UserService { rpc UpdateUserRole(UpdateUserRoleRequest) returns (UpdateUserRoleResponse); // Update a single User role rpc UpdateUserAddons(UpdateUserAddonsRequest) returns (UpdateUserAddonsResponse); + // Update user delete policy + rpc UpdateUserDeletePolicy(UpdateUserDeletePolicyRequest) + returns (UpdateUserDeletePolicyResponse); } message DeleteUserRequest { @@ -116,6 +119,15 @@ message UpdateUserAddonsResponse { User user = 2; } +message UpdateUserDeletePolicyRequest { + string user_name = 1 [(validate.rules).string = { min_len: 1 }]; + DeletePolicy delete_policy = 2 [(validate.rules).enum.defined_only = true]; +} + +message UpdateUserDeletePolicyResponse { + string message = 1; + User user = 2; +} message GetEventsRequest { string user_name = 1; optional google.protobuf.Timestamp from = 2; diff --git a/proto/proto/dashboard-apis/dashboard/v1alpha1/workspace.proto b/proto/proto/dashboard-apis/dashboard/v1alpha1/workspace.proto index 8a0dcf46..b16d9d82 100644 --- a/proto/proto/dashboard-apis/dashboard/v1alpha1/workspace.proto +++ b/proto/proto/dashboard-apis/dashboard/v1alpha1/workspace.proto @@ -8,6 +8,7 @@ syntax = "proto3"; package dashboard.v1alpha1; import "validate/validate.proto"; import "google/protobuf/timestamp.proto"; +import "dashboard/v1alpha1/user.proto"; message NetworkRule { int32 port_number = 1 [(validate.rules).int32 = { gt: 0, lt: 65536 }]; @@ -38,4 +39,6 @@ message Workspace { WorkspaceStatus status = 4; optional string raw = 5; optional string raw_instance = 6; + optional string raw_ingress_route = 7; + optional DeletePolicy delete_policy = 8 [(validate.rules).enum.defined_only = true]; } diff --git a/proto/proto/dashboard-apis/dashboard/v1alpha1/workspace_service.proto b/proto/proto/dashboard-apis/dashboard/v1alpha1/workspace_service.proto index d2d960a6..37dc964f 100644 --- a/proto/proto/dashboard-apis/dashboard/v1alpha1/workspace_service.proto +++ b/proto/proto/dashboard-apis/dashboard/v1alpha1/workspace_service.proto @@ -8,6 +8,7 @@ syntax = "proto3"; package dashboard.v1alpha1; import "dashboard/v1alpha1/workspace.proto"; +import "dashboard/v1alpha1/user.proto"; import "validate/validate.proto"; service WorkspaceService { @@ -56,6 +57,7 @@ message UpdateWorkspaceRequest { string ws_name = 2 [(validate.rules).string = { min_len: 1 }]; optional int64 replicas = 3; map vars = 4; + optional DeletePolicy delete_policy = 5 [(validate.rules).enum.defined_only = true]; } message UpdateWorkspaceResponse { diff --git a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_pb.ts b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_pb.ts index 05e51bb7..6c615328 100644 --- a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_pb.ts +++ b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_pb.ts @@ -10,6 +10,26 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; +/** + * @generated from enum dashboard.v1alpha1.DeletePolicy + */ +export enum DeletePolicy { + /** + * @generated from enum value: delete = 0; + */ + delete = 0, + + /** + * @generated from enum value: keep = 1; + */ + keep = 1, +} +// Retrieve enum metadata with: proto3.getEnumType(DeletePolicy) +proto3.util.setEnumType(DeletePolicy, "dashboard.v1alpha1.DeletePolicy", [ + { no: 0, name: "delete" }, + { no: 1, name: "keep" }, +]); + /** * @generated from message dashboard.v1alpha1.User */ @@ -54,6 +74,11 @@ export class User extends Message { */ raw?: string; + /** + * @generated from field: optional dashboard.v1alpha1.DeletePolicy delete_policy = 9; + */ + deletePolicy?: DeletePolicy; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -70,6 +95,7 @@ export class User extends Message { { no: 6, name: "default_password", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 7, name: "status", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 8, name: "raw", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 9, name: "delete_policy", kind: "enum", T: proto3.getEnumType(DeletePolicy), opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): User { diff --git a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_service_connectweb.ts b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_service_connectweb.ts index a782ca39..6f5b14f6 100644 --- a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_service_connectweb.ts +++ b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_service_connectweb.ts @@ -7,7 +7,7 @@ /* eslint-disable */ // @ts-nocheck -import { CreateUserRequest, CreateUserResponse, DeleteUserRequest, DeleteUserResponse, GetEventsRequest, GetEventsResponse, GetUserRequest, GetUserResponse, GetUsersRequest, GetUsersResponse, UpdateUserAddonsRequest, UpdateUserAddonsResponse, UpdateUserDisplayNameRequest, UpdateUserDisplayNameResponse, UpdateUserPasswordRequest, UpdateUserPasswordResponse, UpdateUserRoleRequest, UpdateUserRoleResponse } from "./user_service_pb.js"; +import { CreateUserRequest, CreateUserResponse, DeleteUserRequest, DeleteUserResponse, GetEventsRequest, GetEventsResponse, GetUserRequest, GetUserResponse, GetUsersRequest, GetUsersResponse, UpdateUserAddonsRequest, UpdateUserAddonsResponse, UpdateUserDeletePolicyRequest, UpdateUserDeletePolicyResponse, UpdateUserDisplayNameRequest, UpdateUserDisplayNameResponse, UpdateUserPasswordRequest, UpdateUserPasswordResponse, UpdateUserRoleRequest, UpdateUserRoleResponse } from "./user_service_pb.js"; import { MethodKind } from "@bufbuild/protobuf"; /** @@ -115,6 +115,17 @@ export const UserService = { O: UpdateUserAddonsResponse, kind: MethodKind.Unary, }, + /** + * Update user delete policy + * + * @generated from rpc dashboard.v1alpha1.UserService.UpdateUserDeletePolicy + */ + updateUserDeletePolicy: { + name: "UpdateUserDeletePolicy", + I: UpdateUserDeletePolicyRequest, + O: UpdateUserDeletePolicyResponse, + kind: MethodKind.Unary, + }, } } as const; diff --git a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_service_pb.ts b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_service_pb.ts index d9b7a47f..1f7acf15 100644 --- a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_service_pb.ts +++ b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/user_service_pb.ts @@ -9,7 +9,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3, Timestamp } from "@bufbuild/protobuf"; -import { User, UserAddon } from "./user_pb.js"; +import { DeletePolicy, User, UserAddon } from "./user_pb.js"; import { Event } from "./event_pb.js"; /** @@ -700,6 +700,92 @@ export class UpdateUserAddonsResponse extends Message } } +/** + * @generated from message dashboard.v1alpha1.UpdateUserDeletePolicyRequest + */ +export class UpdateUserDeletePolicyRequest extends Message { + /** + * @generated from field: string user_name = 1; + */ + userName = ""; + + /** + * @generated from field: dashboard.v1alpha1.DeletePolicy delete_policy = 2; + */ + deletePolicy = DeletePolicy.delete; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "dashboard.v1alpha1.UpdateUserDeletePolicyRequest"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "user_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "delete_policy", kind: "enum", T: proto3.getEnumType(DeletePolicy) }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): UpdateUserDeletePolicyRequest { + return new UpdateUserDeletePolicyRequest().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): UpdateUserDeletePolicyRequest { + return new UpdateUserDeletePolicyRequest().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): UpdateUserDeletePolicyRequest { + return new UpdateUserDeletePolicyRequest().fromJsonString(jsonString, options); + } + + static equals(a: UpdateUserDeletePolicyRequest | PlainMessage | undefined, b: UpdateUserDeletePolicyRequest | PlainMessage | undefined): boolean { + return proto3.util.equals(UpdateUserDeletePolicyRequest, a, b); + } +} + +/** + * @generated from message dashboard.v1alpha1.UpdateUserDeletePolicyResponse + */ +export class UpdateUserDeletePolicyResponse extends Message { + /** + * @generated from field: string message = 1; + */ + message = ""; + + /** + * @generated from field: dashboard.v1alpha1.User user = 2; + */ + user?: User; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "dashboard.v1alpha1.UpdateUserDeletePolicyResponse"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "message", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "user", kind: "message", T: User }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): UpdateUserDeletePolicyResponse { + return new UpdateUserDeletePolicyResponse().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): UpdateUserDeletePolicyResponse { + return new UpdateUserDeletePolicyResponse().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): UpdateUserDeletePolicyResponse { + return new UpdateUserDeletePolicyResponse().fromJsonString(jsonString, options); + } + + static equals(a: UpdateUserDeletePolicyResponse | PlainMessage | undefined, b: UpdateUserDeletePolicyResponse | PlainMessage | undefined): boolean { + return proto3.util.equals(UpdateUserDeletePolicyResponse, a, b); + } +} + /** * @generated from message dashboard.v1alpha1.GetEventsRequest */ diff --git a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/workspace_pb.ts b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/workspace_pb.ts index e05cbb51..f3fd009c 100644 --- a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/workspace_pb.ts +++ b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/workspace_pb.ts @@ -9,6 +9,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3, protoInt64, Timestamp } from "@bufbuild/protobuf"; +import { DeletePolicy } from "./user_pb.js"; /** * @generated from message dashboard.v1alpha1.NetworkRule @@ -215,6 +216,16 @@ export class Workspace extends Message { */ rawInstance?: string; + /** + * @generated from field: optional string raw_ingress_route = 7; + */ + rawIngressRoute?: string; + + /** + * @generated from field: optional dashboard.v1alpha1.DeletePolicy delete_policy = 8; + */ + deletePolicy?: DeletePolicy; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -229,6 +240,8 @@ export class Workspace extends Message { { no: 4, name: "status", kind: "message", T: WorkspaceStatus }, { no: 5, name: "raw", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, { no: 6, name: "raw_instance", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 7, name: "raw_ingress_route", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 8, name: "delete_policy", kind: "enum", T: proto3.getEnumType(DeletePolicy), opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): Workspace { diff --git a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/workspace_service_pb.ts b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/workspace_service_pb.ts index 0164dd2a..99feba9f 100644 --- a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/workspace_service_pb.ts +++ b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/workspace_service_pb.ts @@ -10,6 +10,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; import { NetworkRule, Workspace } from "./workspace_pb.js"; +import { DeletePolicy } from "./user_pb.js"; /** * @generated from message dashboard.v1alpha1.CreateWorkspaceRequest @@ -219,6 +220,11 @@ export class UpdateWorkspaceRequest extends Message { */ vars: { [key: string]: string } = {}; + /** + * @generated from field: optional dashboard.v1alpha1.DeletePolicy delete_policy = 5; + */ + deletePolicy?: DeletePolicy; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -231,6 +237,7 @@ export class UpdateWorkspaceRequest extends Message { { no: 2, name: "ws_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 3, name: "replicas", kind: "scalar", T: 3 /* ScalarType.INT64 */, opt: true }, { no: 4, name: "vars", kind: "map", K: 9 /* ScalarType.STRING */, V: {kind: "scalar", T: 9 /* ScalarType.STRING */} }, + { no: 5, name: "delete_policy", kind: "enum", T: proto3.getEnumType(DeletePolicy), opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): UpdateWorkspaceRequest { diff --git a/web/dashboard-ui/src/views/organisms/UserDeletePolicyChangeDialog.tsx b/web/dashboard-ui/src/views/organisms/UserDeletePolicyChangeDialog.tsx new file mode 100644 index 00000000..27fe1fd8 --- /dev/null +++ b/web/dashboard-ui/src/views/organisms/UserDeletePolicyChangeDialog.tsx @@ -0,0 +1,112 @@ +import { PersonOutlineTwoTone } from "@mui/icons-material"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + FormControlLabel, + Radio, + RadioGroup, + Stack, + Tooltip, +} from "@mui/material"; +import React from "react"; +import { Controller, useForm } from "react-hook-form"; +import { DialogContext } from "../../components/ContextProvider"; +import { DeletePolicy, User } from "../../proto/gen/dashboard/v1alpha1/user_pb"; +import { TextFieldLabel } from "../atoms/TextFieldLabel"; +import { useUserModule } from "./UserModule"; + +/** + * view + */ +interface Inputs { + deletePolicy: string; +} + +export const UserDeletePolicyChangeDialog: React.VFC<{ + onClose: () => void; + user: User; +}> = ({ onClose, user }) => { + console.log("UserDeletePolicyChangeDialog"); + const { updateDeletePolicy } = useUserModule(); + const { control, handleSubmit } = useForm({}); + + const onChangeDeletePolicy = async (data: Inputs) => { + const deletePolicy = + DeletePolicy[data.deletePolicy as keyof typeof DeletePolicy]; + console.log("deletePolicy", deletePolicy); + await updateDeletePolicy(user.name, deletePolicy); + onClose(); + }; + + return ( + + Change Delete Policy +
+ + + } + /> + ( + + } + label={ + + Delete + + } + /> + } + label={ + + Keep + + } + /> + + )} + /> + + + + + + +
+
+ ); +}; + +/** + * Context + */ +export const UserDeletePolicyChangeDialogContext = DialogContext<{ + user: User; +}>((props) => ); diff --git a/web/dashboard-ui/src/views/organisms/UserModule.tsx b/web/dashboard-ui/src/views/organisms/UserModule.tsx index 65b5ca39..23f02850 100644 --- a/web/dashboard-ui/src/views/organisms/UserModule.tsx +++ b/web/dashboard-ui/src/views/organisms/UserModule.tsx @@ -7,7 +7,11 @@ import { useHandleError, useLogin } from "../../components/LoginProvider"; import { useProgress } from "../../components/ProgressProvider"; import { Template } from "../../proto/gen/dashboard/v1alpha1/template_pb"; import { GetUserAddonTemplatesRequest } from "../../proto/gen/dashboard/v1alpha1/template_service_pb"; -import { User, UserAddon } from "../../proto/gen/dashboard/v1alpha1/user_pb"; +import { + DeletePolicy, + User, + UserAddon, +} from "../../proto/gen/dashboard/v1alpha1/user_pb"; import { useTemplateService, useUserService, @@ -309,6 +313,35 @@ const useUser = () => { } }; + /** + * updateDeletePolicy: Update delete policy + */ + const updateDeletePolicy = async ( + userName: string, + deletePolicy: DeletePolicy + ) => { + console.log("updateDeletePolicy", userName, deletePolicy); + setMask(); + try { + const result = await userService.updateUserDeletePolicy({ + userName, + deletePolicy, + }); + const newUser = result.user; + enqueueSnackbar(result.message, { variant: "success" }); + if (users && newUser) { + setUsers((prev) => + prev.map((us) => (us.name === newUser.name ? new User(newUser) : us)) + ); + } + return newUser; + } catch (error) { + handleError(error); + } finally { + releaseMask(); + } + }; + /** * DeleteDialog: Delete user */ @@ -343,6 +376,7 @@ const useUser = () => { updateName, updateRole, updateAddons, + updateDeletePolicy, deleteUser, }; }; diff --git a/web/dashboard-ui/src/views/organisms/WorkspaceActionDialog.tsx b/web/dashboard-ui/src/views/organisms/WorkspaceActionDialog.tsx index 4c857424..abdca9c6 100644 --- a/web/dashboard-ui/src/views/organisms/WorkspaceActionDialog.tsx +++ b/web/dashboard-ui/src/views/organisms/WorkspaceActionDialog.tsx @@ -131,6 +131,35 @@ export const WorkspaceStopDialog: React.VFC<{ ); }; +/** + * WorkspaceChangeDeletePolicy + */ +export const WorkspaceChangeDeletePolicyDialog: React.VFC<{ + workspace: Workspace; + onClose: () => void; +}> = (props) => { + console.log("WorkspaceChangeDeletePolicyDialog"); + const { workspace, onClose } = props; + const hooks = useWorkspaceModule(); + return ( + { + hooks.stopWorkspace(workspace).then(() => onClose()); + }} + > + Stop + + } + /> + ); +}; + /** * Delete */ diff --git a/web/dashboard-ui/src/views/organisms/WorkspaceDeletePolicyChangeDialo.tsx b/web/dashboard-ui/src/views/organisms/WorkspaceDeletePolicyChangeDialo.tsx new file mode 100644 index 00000000..7c10bf44 --- /dev/null +++ b/web/dashboard-ui/src/views/organisms/WorkspaceDeletePolicyChangeDialo.tsx @@ -0,0 +1,119 @@ +import { PersonOutlineTwoTone, WebTwoTone } from "@mui/icons-material"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + FormControlLabel, + Radio, + RadioGroup, + Stack, + Tooltip, +} from "@mui/material"; +import React from "react"; +import { Controller, useForm } from "react-hook-form"; +import { DialogContext } from "../../components/ContextProvider"; +import { DeletePolicy } from "../../proto/gen/dashboard/v1alpha1/user_pb"; +import { Workspace } from "../../proto/gen/dashboard/v1alpha1/workspace_pb"; +import { TextFieldLabel } from "../atoms/TextFieldLabel"; +import { useWorkspaceModule } from "./WorkspaceModule"; + +/** + * view + */ +interface Inputs { + deletePolicy: string; +} + +export const WorkspaceDeletePolicyChangeDialog: React.VFC<{ + onClose: () => void; + workspace: Workspace; +}> = ({ onClose, workspace }) => { + console.log("WorkspaceDeletePolicyChangeDialog"); + const { updateDeletePolicy } = useWorkspaceModule(); + const { control, handleSubmit } = useForm({}); + + const onChangeDeletePolicy = async (data: Inputs) => { + const deletePolicy = + DeletePolicy[data.deletePolicy as keyof typeof DeletePolicy]; + console.log("deletePolicy", deletePolicy); + await updateDeletePolicy(workspace, deletePolicy); + onClose(); + }; + + return ( + + Change Delete Policy +
+ + + } + /> + } + /> + ( + + } + label={ + + Delete + + } + /> + } + label={ + + Keep + + } + /> + + )} + /> + + + + + + +
+
+ ); +}; + +/** + * Context + */ +export const WorkspaceDeletePolicyChangeDialogContext = DialogContext<{ + workspace: Workspace; +}>((props) => ); diff --git a/web/dashboard-ui/src/views/organisms/WorkspaceInfoDialog.tsx b/web/dashboard-ui/src/views/organisms/WorkspaceInfoDialog.tsx index f639dbca..0f93404f 100644 --- a/web/dashboard-ui/src/views/organisms/WorkspaceInfoDialog.tsx +++ b/web/dashboard-ui/src/views/organisms/WorkspaceInfoDialog.tsx @@ -25,7 +25,10 @@ const WorkspaceInfoDialog: React.FC<{ const [yaml, setYAML] = useState(""); const [instance, setInstance] = useState(""); - const [showTab, setShowTab] = useState<"yaml" | "instance">("yaml"); + const [ingressroute, setIngressRoute] = useState(""); + const [showTab, setShowTab] = useState<"yaml" | "instance" | "ingressroute">( + "yaml" + ); useEffect(() => { wsService @@ -37,6 +40,9 @@ const WorkspaceInfoDialog: React.FC<{ .then((res) => { setYAML(res.workspace?.raw || "No yaml"); setInstance(res.workspace?.rawInstance || "No instance yaml"); + setIngressRoute( + res.workspace?.rawIngressRoute || "No ingress route yaml" + ); }) .catch((error) => { handleError(error); @@ -75,10 +81,14 @@ const WorkspaceInfoDialog: React.FC<{ > + {showTab === "yaml" && } {showTab === "instance" && } + {showTab === "ingressroute" && ( + + )} ); diff --git a/web/dashboard-ui/src/views/organisms/WorkspaceModule.tsx b/web/dashboard-ui/src/views/organisms/WorkspaceModule.tsx index 1a4c8f18..b8714afe 100644 --- a/web/dashboard-ui/src/views/organisms/WorkspaceModule.tsx +++ b/web/dashboard-ui/src/views/organisms/WorkspaceModule.tsx @@ -8,7 +8,7 @@ import { useProgress } from "../../components/ProgressProvider"; import { Event } from "../../proto/gen/dashboard/v1alpha1/event_pb"; import { Template } from "../../proto/gen/dashboard/v1alpha1/template_pb"; import { GetWorkspaceTemplatesRequest } from "../../proto/gen/dashboard/v1alpha1/template_service_pb"; -import { User } from "../../proto/gen/dashboard/v1alpha1/user_pb"; +import { DeletePolicy, User } from "../../proto/gen/dashboard/v1alpha1/user_pb"; import { NetworkRule, Workspace, @@ -184,8 +184,8 @@ const useWorkspace = () => { const wsEventMap: { [key: string]: Event[] } = {}; for (const event of events) { if (event.regardingWorkspace) { - wsEventMap[event.regardingWorkspace] = [ - ...(wsEventMap[event.regardingWorkspace] || []), + wsEventMap[`${event.regardingWorkspace}-${userName}`] = [ + ...(wsEventMap[`${event.regardingWorkspace}-${userName}`] || []), event, ].sort((a, b) => latestTime(a) - latestTime(b)); } @@ -399,6 +399,32 @@ const useWorkspace = () => { } }; + /** + * Update delete policy + */ + const updateDeletePolicy = async ( + workspace: Workspace, + deletePolicy: DeletePolicy + ) => { + console.log("updateDeletePolicy", workspace.name, deletePolicy); + setMask(); + try { + const result = await workspaceService.updateWorkspace({ + userName: workspace.ownerName!, + wsName: workspace.name, + deletePolicy: deletePolicy, + }); + const newWs = result.workspace; + enqueueSnackbar(result.message, { variant: "success" }); + newWs && upsertWorkspace(newWs); + return newWs; + } catch (error) { + handleError(error); + } finally { + releaseMask(); + } + }; + /** * DestroyDialog: Destroy workspace */ @@ -438,6 +464,7 @@ const useWorkspace = () => { getWorkspaces, createWorkspace, deleteWorkspace, + updateDeletePolicy, runWorkspace, stopWorkspace, pollingWorkspace, diff --git a/web/dashboard-ui/src/views/pages/UserPage.tsx b/web/dashboard-ui/src/views/pages/UserPage.tsx index 50d570e2..e37cfcab 100644 --- a/web/dashboard-ui/src/views/pages/UserPage.tsx +++ b/web/dashboard-ui/src/views/pages/UserPage.tsx @@ -3,13 +3,17 @@ import { AdminPanelSettingsTwoTone, Badge as BadgeIcon, DeleteOutlined, + DeleteSweepOutlined, Edit, ExpandLess, ExpandMore, FilterListOff, + LockOpenOutlined, + LockOutlined, MoreVert, Notifications, OpenInNewTwoTone, + PushPinOutlined, RefreshTwoTone, Settings, Web, @@ -43,7 +47,11 @@ import { } from "@mui/x-data-grid"; import React, { useEffect } from "react"; import { useLogin } from "../../components/LoginProvider"; -import { User, UserAddon } from "../../proto/gen/dashboard/v1alpha1/user_pb"; +import { + DeletePolicy, + User, + UserAddon, +} from "../../proto/gen/dashboard/v1alpha1/user_pb"; import { EllipsisTypography } from "../atoms/EllipsisTypography"; import { NameAvatar } from "../atoms/NameAvatar"; import { SearchTextField } from "../atoms/SearchTextField"; @@ -56,6 +64,7 @@ import { UserDeleteDialogContext, } from "../organisms/UserActionDialog"; import { UserAddonChangeDialogContext } from "../organisms/UserAddonsChangeDialog"; +import { UserDeletePolicyChangeDialogContext } from "../organisms/UserDeletePolicyChangeDialog"; import { UserInfoDialogContext } from "../organisms/UserInfoDialog"; import { isAdminRole, @@ -85,6 +94,8 @@ const UserMenu: React.VFC<{ user: User }> = ({ user: us }) => { const userDeleteDialogDispatch = UserDeleteDialogContext.useDispatch(); const userNameChangeDispatch = UserNameChangeDialogContext.useDispatch(); const userAddonChangeDispatch = UserAddonChangeDialogContext.useDispatch(); + const userDeletePolicyChangeDispatch = + UserDeletePolicyChangeDialogContext.useDispatch(); return ( <> @@ -171,11 +182,29 @@ const UserMenu: React.VFC<{ user: User }> = ({ user: us }) => { Change Addons... + + { + userDeletePolicyChangeDispatch(true, { user: us }); + setAnchorEl(null); + }} + > + + {us.deletePolicy === DeletePolicy.keep ? ( + + ) : ( + + )} + + Manage Delete Policy... + + { userDeleteDialogDispatch(true, { user: us }); setAnchorEl(null); }} + disabled={us.deletePolicy === DeletePolicy.keep} > @@ -197,6 +226,8 @@ export const UserDataGrid: React.FC = ({ users }) => { const roleChangeDialogDispatch = RoleChangeDialogContext.useDispatch(); const userAddonChangeDispatch = UserAddonChangeDialogContext.useDispatch(); const userInfoDispatch = UserInfoDialogContext.useDispatch(); + const userDeletePolicyChangeDispatch = + UserDeletePolicyChangeDialogContext.useDispatch(); const theme = useTheme(); const isUpSM = useMediaQuery(theme.breakpoints.up("sm"), { noSsr: true }); @@ -241,6 +272,52 @@ export const UserDataGrid: React.FC = ({ users }) => { ), }, { field: "authType", headerName: "Auth Type", flex: 0.8 }, + { + field: "deletePolicy", + headerName: "Delete Policy", + flex: 0.5, + renderCell: (params: GridRenderCellParams) => ( + <> + {params.hasFocus ? ( + + + ) : ( + + ) + } + /> + + userDeletePolicyChangeDispatch(true, { user: params.row }) + } + > + + + + ) : ( + + ) : ( + + ) + } + /> + )} + + ), + }, { field: "displayName", headerName: "Display Name", @@ -409,7 +486,8 @@ export const UserDataGrid: React.FC = ({ users }) => { roles: isUpSM, addons: isUpSM, displayName: isUpSM, - authType: isUpSM, + authType: false, + deletePolicy: false, }, }, pagination: { paginationModel: { pageSize: 10 } }, @@ -577,11 +655,13 @@ export const UserPage: React.VFC = () => { - - - - - + + + + + + + diff --git a/web/dashboard-ui/src/views/pages/WorkspacePage.tsx b/web/dashboard-ui/src/views/pages/WorkspacePage.tsx index a08b1e85..5b9e8a2a 100644 --- a/web/dashboard-ui/src/views/pages/WorkspacePage.tsx +++ b/web/dashboard-ui/src/views/pages/WorkspacePage.tsx @@ -12,6 +12,7 @@ import { InfoOutlined, KeyboardArrowDownTwoTone, KeyboardArrowUpTwoTone, + LockOpenOutlined, LockOutlined, MoreVertTwoTone, OpenInNewTwoTone, @@ -35,6 +36,7 @@ import { CardHeader, Chip, CircularProgress, + Divider, Fab, Grid, IconButton, @@ -62,7 +64,7 @@ import { useSnackbar } from "notistack"; import React, { useRef, useState } from "react"; import { useLogin } from "../../components/LoginProvider"; import { Event } from "../../proto/gen/dashboard/v1alpha1/event_pb"; -import { User } from "../../proto/gen/dashboard/v1alpha1/user_pb"; +import { DeletePolicy, User } from "../../proto/gen/dashboard/v1alpha1/user_pb"; import { EventsDataGrid } from "../atoms/EventsDataGrid"; import { NameAvatar } from "../atoms/NameAvatar"; import { SearchTextField } from "../atoms/SearchTextField"; @@ -78,6 +80,7 @@ import { WorkspaceStartDialogContext, WorkspaceStopDialogContext, } from "../organisms/WorkspaceActionDialog"; +import { WorkspaceDeletePolicyChangeDialogContext } from "../organisms/WorkspaceDeletePolicyChangeDialo"; import { WorkspaceInfoDialogContext } from "../organisms/WorkspaceInfoDialog"; import { WorkspaceContext, @@ -170,6 +173,8 @@ const WorkspaceMenu: React.VFC<{ workspace: WorkspaceWrapper; user: User }> = ({ const startDialogDispatch = WorkspaceStartDialogContext.useDispatch(); const stopDialogDispatch = WorkspaceStopDialogContext.useDispatch(); const deleteDialogDispatch = WorkspaceDeleteDialogContext.useDispatch(); + const changeDeletePolicyDispatch = + WorkspaceDeletePolicyChangeDialogContext.useDispatch(); return ( <> @@ -191,7 +196,7 @@ const WorkspaceMenu: React.VFC<{ workspace: WorkspaceWrapper; user: User }> = ({ { setAnchorEl(null); - startDialogDispatch(true, { workspace: workspace }); + startDialogDispatch(true, { workspace }); }} disabled={!Boolean(workspace.name)} > @@ -203,7 +208,7 @@ const WorkspaceMenu: React.VFC<{ workspace: WorkspaceWrapper; user: User }> = ({ { setAnchorEl(null); - stopDialogDispatch(true, { workspace: workspace }); + stopDialogDispatch(true, { workspace }); }} disabled={!Boolean(workspace.name)} > @@ -212,12 +217,34 @@ const WorkspaceMenu: React.VFC<{ workspace: WorkspaceWrapper; user: User }> = ({ Stop workspace... + { setAnchorEl(null); - deleteDialogDispatch(true, { workspace: workspace }); + changeDeletePolicyDispatch(true, { workspace }); }} disabled={!Boolean(workspace.name) || workspace.isSharedFor(user)} + > + + {workspace.deletePolicy === DeletePolicy.keep ? ( + + ) : ( + + )} + + Manage Delete Policy... + + + { + setAnchorEl(null); + deleteDialogDispatch(true, { workspace }); + }} + disabled={ + !Boolean(workspace.name) || + workspace.isSharedFor(user) || + workspace.deletePolicy === DeletePolicy.keep + } > @@ -821,13 +848,15 @@ export const WorkspacePage: React.VFC = () => { - - - - - - - + + + + + + + + +