diff --git a/internal/admin/enterprise_handler.go b/internal/admin/enterprise_handler.go index a398355484..45c6a21151 100644 --- a/internal/admin/enterprise_handler.go +++ b/internal/admin/enterprise_handler.go @@ -108,15 +108,15 @@ func (h *Handler) UpdateRole(c *gin.Context) { success(c, role, "") } -// DeleteRole handle delete role -func (h *Handler) DeleteRole(c *gin.Context) { +// DropRole handle drop role +func (h *Handler) DropRole(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { errorResponse(c, "Role name is required", 400) return } - role, err := h.service.DeleteRole(roleName) + role, err := h.service.DropRole(roleName) if err != nil { errorResponse(c, "Role not found", 404) return @@ -688,6 +688,112 @@ func (h *Handler) ListUserFiles(c *gin.Context) { success(c, files, "") } +// ListUserProviders handle show user providers +func (h *Handler) ListUserProviders(c *gin.Context) { + encodedUsername := c.Param("username") + username, err := common.DecodeEmail(encodedUsername) + if err != nil { + errorResponse(c, err.Error(), 400) + return + } + if username == "" { + errorResponse(c, "Username is required", 400) + return + } + + providers, err := h.service.ListUserProviders(username) + if err != nil { + errorResponse(c, err.Error(), 500) + return + } + + success(c, providers, "") +} + +// ListUserProviderInstances handle show user provider instances +func (h *Handler) ListUserProviderInstances(c *gin.Context) { + encodedUsername := c.Param("username") + userName, err := common.DecodeEmail(encodedUsername) + if err != nil { + errorResponse(c, err.Error(), 400) + return + } + if userName == "" { + errorResponse(c, "Username is required", 400) + return + } + + providerName := c.Param("provider_name") + if providerName == "" { + errorResponse(c, "Provider name is required", 400) + return + } + + instances, err := h.service.ListUserProviderInstances(userName, providerName) + if err != nil { + errorResponse(c, err.Error(), 500) + return + } + + success(c, instances, "") +} + +// ListUserProviderInstanceModels handle show user provider instance models +func (h *Handler) ListUserProviderInstanceModels(c *gin.Context) { + encodedUsername := c.Param("username") + userName, err := common.DecodeEmail(encodedUsername) + if err != nil { + errorResponse(c, err.Error(), 400) + return + } + if userName == "" { + errorResponse(c, "Username is required", 400) + return + } + + providerName := c.Param("provider_name") + if providerName == "" { + errorResponse(c, "Provider name is required", 400) + return + } + + instanceName := c.Param("instance_name") + if instanceName == "" { + errorResponse(c, "Instance name is required", 400) + return + } + + models, err := h.service.ListUserProviderInstanceModels(userName, providerName, instanceName) + if err != nil { + errorResponse(c, err.Error(), 500) + return + } + + success(c, models, "") +} + +// ListUserDefaultModels handle show user default models +func (h *Handler) ListUserDefaultModels(c *gin.Context) { + encodedUsername := c.Param("username") + userName, err := common.DecodeEmail(encodedUsername) + if err != nil { + errorResponse(c, err.Error(), 400) + return + } + if userName == "" { + errorResponse(c, "Username is required", 400) + return + } + + models, err := h.service.ListUserDefaultModels(userName) + if err != nil { + errorResponse(c, err.Error(), 500) + return + } + + success(c, models, "") +} + // ShowUsersSummary handle show users summary func (h *Handler) ShowUsersSummary(c *gin.Context) { usersSummary, err := h.service.ShowUsersSummary() diff --git a/internal/admin/enterprise_service.go b/internal/admin/enterprise_service.go index a46b1a78bb..5a43e2c7cb 100644 --- a/internal/admin/enterprise_service.go +++ b/internal/admin/enterprise_service.go @@ -74,12 +74,12 @@ func (s *Service) UpdateRole(roleName, description string) (map[string]interface return result, nil } -// DeleteRole delete role -func (s *Service) DeleteRole(roleName string) (map[string]interface{}, error) { +// DropRole drop role +func (s *Service) DropRole(roleName string) (map[string]interface{}, error) { result := map[string]interface{}{ - "command": "delete_role", + "command": "drop_role", "role_name": roleName, - "error": "'delete role' is implemented in enterprise edition", + "error": "'drop role' is implemented in enterprise edition", } return result, nil @@ -469,6 +469,93 @@ func (s *Service) ListUserFiles(email string) ([]map[string]interface{}, error) return result, nil } +// ListUserProviders show user providers for enterprise edition +func (s *Service) ListUserProviders(email string) ([]map[string]interface{}, error) { + // Query user by email + var user entity.User + err := dao.DB.Where("email = ?", email).First(&user).Error + if err != nil { + return nil, common.ErrUserNotFound + } + + result := []map[string]interface{}{ + { + "command": "list_user_providers", + "email": user.Email, + "nickname": user.Nickname, + "error": "'list user providers' is implemented in enterprise edition", + }, + } + + return result, nil +} + +// ListUserProviderInstances show user provider instances for enterprise edition +func (s *Service) ListUserProviderInstances(email, providerName string) ([]map[string]interface{}, error) { + // Query user by email + var user entity.User + err := dao.DB.Where("email = ?", email).First(&user).Error + if err != nil { + return nil, common.ErrUserNotFound + } + + result := []map[string]interface{}{ + { + "command": "list_user_provider_instances", + "email": user.Email, + "nickname": user.Nickname, + "provider_name": providerName, + "error": "'list user provider instances' is implemented in enterprise edition", + }, + } + + return result, nil +} + +// ListUserProviderInstanceModels show user provider instance models for enterprise edition +func (s *Service) ListUserProviderInstanceModels(email, providerName, instanceName string) ([]map[string]interface{}, error) { + // Query user by email + var user entity.User + err := dao.DB.Where("email = ?", email).First(&user).Error + if err != nil { + return nil, common.ErrUserNotFound + } + + result := []map[string]interface{}{ + { + "command": "list_user_provider_instance_models", + "email": user.Email, + "nickname": user.Nickname, + "provider_name": providerName, + "instance_name": instanceName, + "error": "'list user provider instance models' is implemented in enterprise edition", + }, + } + + return result, nil +} + +// ListUserDefaultModels show user default models for enterprise edition +func (s *Service) ListUserDefaultModels(email string) ([]map[string]interface{}, error) { + // Query user by email + var user entity.User + err := dao.DB.Where("email = ?", email).First(&user).Error + if err != nil { + return nil, common.ErrUserNotFound + } + + result := []map[string]interface{}{ + { + "command": "list_user_default_models", + "email": user.Email, + "nickname": user.Nickname, + "error": "'list user default models' is implemented in enterprise edition", + }, + } + + return result, nil +} + // ShowUsersSummary show users summary for enterprise edition func (s *Service) ShowUsersSummary() (map[string]interface{}, error) { result := map[string]interface{}{ diff --git a/internal/admin/handler.go b/internal/admin/handler.go index 7d8ceb7ddd..923e22a168 100644 --- a/internal/admin/handler.go +++ b/internal/admin/handler.go @@ -748,13 +748,12 @@ func (h *Handler) ShowModel(c *gin.Context) { }) } -// GetVariables handle get variables -// Python logic: if request body is empty, list all variables; otherwise get single variable by var_name from body -func (h *Handler) GetVariables(c *gin.Context) { +// ListVariables handle list variables +func (h *Handler) ListVariables(c *gin.Context) { // Check if request has body content if c.Request.ContentLength == 0 || c.Request.ContentLength == -1 { // List all variables - variables, err := h.service.GetAllVariables() + variables, err := h.service.ListAllVariables() if err != nil { errorResponse(c, err.Error(), 500) return @@ -829,16 +828,10 @@ func (h *Handler) SetVariable(c *gin.Context) { successNoData(c, "Set variable successfully") } -// GetConfigs handle get configs -// Python logic: return all service configurations -func (h *Handler) GetConfigs(c *gin.Context) { - configs, err := h.service.GetAllConfigs() +// ListConfigs handle list configs +func (h *Handler) ListConfigs(c *gin.Context) { + configs, err := h.service.ListAllConfigs() if err != nil { - // Check if it's an AdminException - if adminErr, ok := err.(*AdminException); ok { - errorResponse(c, adminErr.Message, 400) - return - } errorResponse(c, err.Error(), 500) return } @@ -846,16 +839,10 @@ func (h *Handler) GetConfigs(c *gin.Context) { success(c, configs, "") } -// GetEnvironments handle get environments -// Python logic: return important environment variables -func (h *Handler) GetEnvironments(c *gin.Context) { - environments, err := h.service.GetAllEnvironments() +// ListEnvironments handle list environments +func (h *Handler) ListEnvironments(c *gin.Context) { + environments, err := h.service.ListEnvironments() if err != nil { - // Check if it's an AdminException - if adminErr, ok := err.(*AdminException); ok { - errorResponse(c, adminErr.Message, 400) - return - } errorResponse(c, err.Error(), 500) return } diff --git a/internal/admin/router.go b/internal/admin/router.go index 0e262bee02..bbf66f3661 100644 --- a/internal/admin/router.go +++ b/internal/admin/router.go @@ -77,14 +77,14 @@ func (r *Router) Setup(engine *gin.Engine) { protected.PUT("/services/:service_id", r.handler.RestartService) // Variables/Settings - protected.GET("/variables", r.handler.GetVariables) + protected.GET("/variables", r.handler.ListVariables) protected.PUT("/variables", r.handler.SetVariable) // Configs - protected.GET("/configs", r.handler.GetConfigs) + protected.GET("/configs", r.handler.ListConfigs) // Environments - protected.GET("/environments", r.handler.GetEnvironments) + protected.GET("/environments", r.handler.ListEnvironments) // Version protected.GET("/version", r.handler.GetVersion) @@ -134,6 +134,10 @@ func (r *Router) Setup(engine *gin.Engine) { protected.GET("/users/:username/searches", r.handler.ListUserSearches) protected.GET("/users/:username/models", r.handler.ListUserModels) protected.GET("/users/:username/files", r.handler.ListUserFiles) + protected.GET("/users/:username/providers", r.handler.ListUserProviders) + protected.GET("/users/:username/providers/:provider_name/instances", r.handler.ListUserProviderInstances) + protected.GET("/users/:username/providers/:provider_name/instances/:instance_name/models", r.handler.ListUserProviderInstanceModels) + protected.GET("/users/:username/default-models", r.handler.ListUserDefaultModels) protected.GET("/users/summary", r.handler.ShowUsersSummary) protected.GET("/users/activity", r.handler.ShowUsersActivity) protected.GET("/users/reports", r.handler.ListUsersReports) @@ -166,7 +170,7 @@ func (r *Router) Setup(engine *gin.Engine) { protected.POST("/roles", r.handler.CreateRole) protected.GET("/roles/:role_name", r.handler.ShowRole) protected.PUT("/roles/:role_name", r.handler.UpdateRole) - protected.DELETE("/roles/:role_name", r.handler.DeleteRole) + protected.DELETE("/roles/:role_name", r.handler.DropRole) protected.GET("/roles/:role_name/permission", r.handler.GetRolePermission) protected.POST("/roles/:role_name/permission", r.handler.GrantRolePermission) protected.DELETE("/roles/:role_name/permission", r.handler.RevokeRolePermission) diff --git a/internal/admin/service.go b/internal/admin/service.go index c80c591cfc..831b432744 100644 --- a/internal/admin/service.go +++ b/internal/admin/service.go @@ -1516,9 +1516,9 @@ func (s *Service) GetVariable(varName string) ([]map[string]interface{}, error) return formatSystemSettings(settings), nil } -// GetAllVariables get all variables +// ListAllVariables list all variables // Returns all system settings from database -func (s *Service) GetAllVariables() ([]map[string]interface{}, error) { +func (s *Service) ListAllVariables() ([]map[string]interface{}, error) { settings, err := s.systemSettingsDAO.GetAll() if err != nil { return nil, err @@ -1562,18 +1562,17 @@ func (s *Service) SetVariable(varName, varValue string) error { // Config methods -// GetAllConfigs get all configs +// ListAllConfigs list all configs // Returns all service configurations from the config file -func (s *Service) GetAllConfigs() ([]map[string]interface{}, error) { +func (s *Service) ListAllConfigs() ([]map[string]interface{}, error) { result := server.GetAllConfigs() return result, nil } // Environment methods -// GetAllEnvironments get all environments -// Returns important environment variables -func (s *Service) GetAllEnvironments() ([]map[string]interface{}, error) { +// ListEnvironments list all environments +func (s *Service) ListEnvironments() ([]map[string]interface{}, error) { result := make([]map[string]interface{}, 0) // DOC_ENGINE diff --git a/internal/cli/admin_command.go b/internal/cli/admin_command.go index 09f0f1865a..be86f3327a 100644 --- a/internal/cli/admin_command.go +++ b/internal/cli/admin_command.go @@ -191,8 +191,8 @@ func (c *CLI) AdminCreateRoleCommand(cmd *Command) (ResponseIf, error) { return &result, nil } -// DropRole deletes the role (admin mode only) -func (c *CLI) DropRole(cmd *Command) (ResponseIf, error) { +// AdminDropRoleCommand deletes the role (admin mode only) +func (c *CLI) AdminDropRoleCommand(cmd *Command) (ResponseIf, error) { if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") } @@ -211,7 +211,7 @@ func (c *CLI) DropRole(cmd *Command) (ResponseIf, error) { return nil, fmt.Errorf("failed to drop role: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) } - var result SimpleResponse + var result CommonDataResponse if err = json.Unmarshal(resp.Body, &result); err != nil { return nil, fmt.Errorf("drop role failed: invalid JSON (%w)", err) @@ -224,8 +224,8 @@ func (c *CLI) DropRole(cmd *Command) (ResponseIf, error) { return &result, nil } -// AlterRole alters the role rights (admin mode only) -func (c *CLI) AlterRole(cmd *Command) (ResponseIf, error) { +// AdminAlterRole alters the role rights (admin mode only) +func (c *CLI) AdminAlterRole(cmd *Command) (ResponseIf, error) { if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") } @@ -428,8 +428,8 @@ func (c *CLI) AdminCreateUserAPIKeyCommand(cmd *Command) (ResponseIf, error) { return &result, nil } -// ActivateUser activates or deactivates a user (admin mode only) -func (c *CLI) ActivateUser(cmd *Command) (ResponseIf, error) { +// AdminActivateUser activates or deactivates a user (admin mode only) +func (c *CLI) AdminActivateUser(cmd *Command) (ResponseIf, error) { if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") } @@ -478,8 +478,8 @@ func (c *CLI) ActivateUser(cmd *Command) (ResponseIf, error) { return &result, nil } -// AlterUserPassword changes a user's password (admin mode only) -func (c *CLI) AlterUserPassword(cmd *Command) (ResponseIf, error) { +// AdminAlterUserPassword changes a user's password (admin mode only) +func (c *CLI) AdminAlterUserPassword(cmd *Command) (ResponseIf, error) { if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") } @@ -619,8 +619,8 @@ func normalizeVariableRows(rows []map[string]interface{}) { } } -// AdminListVariables lists all system variables (admin mode only). -func (c *CLI) AdminListVariables(cmd *Command) (ResponseIf, error) { +// AdminListVariablesCommand lists all system variables (admin mode only). +func (c *CLI) AdminListVariablesCommand(cmd *Command) (ResponseIf, error) { if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") } @@ -648,6 +648,63 @@ func (c *CLI) AdminListVariables(cmd *Command) (ResponseIf, error) { return &result, nil } +// AdminListConfigsCommand lists all system configs (admin mode only). +func (c *CLI) AdminListConfigsCommand(cmd *Command) (ResponseIf, error) { + if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { + return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") + } + + resp, err := c.AdminServerClient.Request("GET", "/admin/configs", "admin", nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to list configs: %w", err) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to list configs: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) + } + + var result CommonResponse + if err = json.Unmarshal(resp.Body, &result); err != nil { + return nil, fmt.Errorf("list configs failed: invalid JSON (%w)", err) + } + + if result.Code != 0 { + return nil, fmt.Errorf("%s", result.Message) + } + + normalizeVariableRows(result.Data) + result.Duration = resp.Duration + return &result, nil +} + +// AdminListEnvironmentsCommand lists all system environments (admin mode only). +func (c *CLI) AdminListEnvironmentsCommand(cmd *Command) (ResponseIf, error) { + if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { + return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") + } + + resp, err := c.AdminServerClient.Request("GET", "/admin/environments", "admin", nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to list configs: %w", err) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to list configs: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) + } + + var result CommonResponse + if err = json.Unmarshal(resp.Body, &result); err != nil { + return nil, fmt.Errorf("list configs failed: invalid JSON (%w)", err) + } + + if result.Code != 0 { + return nil, fmt.Errorf("%s", result.Message) + } + + result.Duration = resp.Duration + return &result, nil +} + // AdminShowVariable shows system variables by exact name or name prefix (admin mode only). func (c *CLI) AdminShowVariable(cmd *Command) (ResponseIf, error) { if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { @@ -933,157 +990,6 @@ func (c *CLI) ListUserDatasets(cmd *Command) (ResponseIf, error) { return nil, nil } -// GrantPermission grants permission to a role (admin mode only) -func (c *CLI) GrantPermission(cmd *Command) (ResponseIf, error) { - if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { - return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") - } - - userName, ok := cmd.Params["user_name"].(string) - if !ok { - return nil, fmt.Errorf("user_name not provided") - } - - encodedUserName := common.EncodeEmail(userName) - apiURL := fmt.Sprintf("/admin/users/%s/keys", encodedUserName) - - resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil) - if err != nil { - return nil, fmt.Errorf("failed to list tokens: %w", err) - } - - if resp.StatusCode != 200 { - return nil, fmt.Errorf("failed to list tokens: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) - } - - var result CommonResponse - if err = json.Unmarshal(resp.Body, &result); err != nil { - return nil, fmt.Errorf("list tokens failed: invalid JSON (%w)", err) - } - - if result.Code != 0 { - return nil, fmt.Errorf("%s", result.Message) - } - - // Remove extra field from data - for _, item := range result.Data { - delete(item, "extra") - } - - result.Duration = resp.Duration - return &result, nil -} - -// RevokePermission revokes permission from a role (admin mode only) -func (c *CLI) RevokePermission(cmd *Command) (ResponseIf, error) { - if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { - return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") - } - - roleName, ok := cmd.Params["role_name"].(string) - if !ok { - return nil, fmt.Errorf("role_name not provided") - } - - resource, ok := cmd.Params["resource"].(string) - if !ok { - return nil, fmt.Errorf("resource not provided") - } - - actionsRaw, ok := cmd.Params["actions"].([]interface{}) - if !ok { - return nil, fmt.Errorf("actions not provided") - } - - actions := make([]string, 0, len(actionsRaw)) - for _, action := range actionsRaw { - if actionStr, ok := action.(string); ok { - actions = append(actions, actionStr) - } - } - - payload := map[string]interface{}{ - "resource": resource, - "actions": actions, - } - - resp, err := c.AdminServerClient.Request("DELETE", fmt.Sprintf("/admin/roles/%s/permission", roleName), "admin", nil, payload) - if err != nil { - return nil, fmt.Errorf("failed to revoke permission: %w", err) - } - - if resp.StatusCode != 200 { - return nil, fmt.Errorf("failed to revoke permission: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) - } - - var result CommonResponse - if err = json.Unmarshal(resp.Body, &result); err != nil { - return nil, fmt.Errorf("revoke permission failed: invalid JSON (%w)", err) - } - - if result.Code != 0 { - return nil, fmt.Errorf("%s", result.Message) - } - - // Remove extra field from data - for _, item := range result.Data { - delete(item, "extra") - } - - result.Duration = resp.Duration - return &result, nil -} - -// AlterUserRole alters user's role (admin mode only) -func (c *CLI) AlterUserRole(cmd *Command) (ResponseIf, error) { - if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { - return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") - } - - userName, ok := cmd.Params["user_name"].(string) - if !ok { - return nil, fmt.Errorf("user_name not provided") - } - - roleName, ok := cmd.Params["role_name"].(string) - if !ok { - return nil, fmt.Errorf("role_name not provided") - } - - payload := map[string]interface{}{ - "role_name": roleName, - } - - encodedUserName := common.EncodeEmail(userName) - apiURL := fmt.Sprintf("/admin/users/%s/role", encodedUserName) - - resp, err := c.AdminServerClient.Request("PUT", apiURL, "admin", nil, payload) - if err != nil { - return nil, fmt.Errorf("failed to alter user role: %w", err) - } - - if resp.StatusCode != 200 { - return nil, fmt.Errorf("failed to alter user role: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) - } - - var result CommonResponse - if err = json.Unmarshal(resp.Body, &result); err != nil { - return nil, fmt.Errorf("alter user role failed: invalid JSON (%w)", err) - } - - if result.Code != 0 { - return nil, fmt.Errorf("%s", result.Message) - } - - // Remove extra field from data - for _, item := range result.Data { - delete(item, "extra") - } - - result.Duration = resp.Duration - return &result, nil -} - // ShowUserPermission shows user's permissions (admin mode only) func (c *CLI) ShowUserPermission(cmd *Command) (ResponseIf, error) { if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { @@ -1165,51 +1071,6 @@ func (c *CLI) GenerateAdminToken(cmd *Command) (ResponseIf, error) { return &result, nil } -// ListAdminTokens lists all API tokens for a user (admin mode only) -func (c *CLI) ListAdminTokens(cmd *Command) (ResponseIf, error) { - if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { - return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") - } - - userName, ok := cmd.Params["user_name"].(string) - if !ok { - return nil, fmt.Errorf("user_name not provided") - } - - encodedUserName := common.EncodeEmail(userName) - apiURL := fmt.Sprintf("/admin/users/%s/keys", encodedUserName) - - resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil) - if err != nil { - return nil, fmt.Errorf("failed to list tokens: %w", err) - } - - if resp.StatusCode != 200 { - return nil, fmt.Errorf("failed to list tokens: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) - } - - var result CommonResponse - if err = json.Unmarshal(resp.Body, &result); err != nil { - return nil, fmt.Errorf("list tokens failed: invalid JSON (%w)", err) - } - - if result.Code != 0 { - return nil, fmt.Errorf("%s", result.Message) - } - - // Remove extra field from data - for _, item := range result.Data { - delete(item, "dialog_id") - delete(item, "source") - delete(item, "update_date") - delete(item, "update_time") - delete(item, "create_time") - } - - result.Duration = resp.Duration - return &result, nil -} - func (c *CLI) ListAdminTasks(cmd *Command) (ResponseIf, error) { if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") @@ -2799,6 +2660,172 @@ func (c *CLI) AdminListUserKeysCommand(cmd *Command) (ResponseIf, error) { return nil, fmt.Errorf("%s", result.Message) } + // Remove extra field from data + for _, item := range result.Data { + delete(item, "dialog_id") + delete(item, "source") + delete(item, "update_date") + delete(item, "update_time") + delete(item, "create_time") + } + + result.Duration = resp.Duration + return &result, nil +} + +func (c *CLI) AdminListUserProvidersCommand(cmd *Command) (ResponseIf, error) { + + if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { + return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") + } + + userName, ok := cmd.Params["user_name"].(string) + if !ok { + return nil, fmt.Errorf("user_name not provided") + } + + encodedUserName := common.EncodeEmail(userName) + apiURL := fmt.Sprintf("/admin/users/%s/providers", encodedUserName) + + resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to list user %s providers: %w", userName, err) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to list user %s providers: HTTP %d, body: %s", userName, resp.StatusCode, string(resp.Body)) + } + + var result CommonResponse + if err = json.Unmarshal(resp.Body, &result); err != nil { + return nil, fmt.Errorf("list user %s providers failed: invalid JSON (%w)", userName, err) + } + + if result.Code != 0 { + return nil, fmt.Errorf("%s", result.Message) + } + + result.Duration = resp.Duration + return &result, nil +} + +func (c *CLI) AdminListUserProviderInstancesCommand(cmd *Command) (ResponseIf, error) { + + if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { + return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") + } + + userName, ok := cmd.Params["user_name"].(string) + if !ok { + return nil, fmt.Errorf("user_name not provided") + } + + providerName, ok := cmd.Params["provider_name"].(string) + if !ok { + return nil, fmt.Errorf("provider_name not provided") + } + + encodedUserName := common.EncodeEmail(userName) + apiURL := fmt.Sprintf("/admin/users/%s/providers/%s/instances", encodedUserName, providerName) + + resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to list user %s providers: %w", userName, err) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to list user %s providers: HTTP %d, body: %s", userName, resp.StatusCode, string(resp.Body)) + } + + var result CommonResponse + if err = json.Unmarshal(resp.Body, &result); err != nil { + return nil, fmt.Errorf("list user %s providers failed: invalid JSON (%w)", userName, err) + } + + if result.Code != 0 { + return nil, fmt.Errorf("%s", result.Message) + } + + result.Duration = resp.Duration + return &result, nil +} + +func (c *CLI) AdminListUserProviderInstanceModelsCommand(cmd *Command) (ResponseIf, error) { + + if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { + return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") + } + + userName, ok := cmd.Params["user_name"].(string) + if !ok { + return nil, fmt.Errorf("user_name not provided") + } + providerName, ok := cmd.Params["provider_name"].(string) + if !ok { + return nil, fmt.Errorf("provider_name not provided") + } + instanceName, ok := cmd.Params["instance_name"].(string) + if !ok { + return nil, fmt.Errorf("instance_name not provided") + } + + encodedUserName := common.EncodeEmail(userName) + apiURL := fmt.Sprintf("/admin/users/%s/providers/%s/instances/%s/models", encodedUserName, providerName, instanceName) + + resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to list user %s provider instance models: %w", userName, err) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to list user %s provider instance models: HTTP %d, body: %s", userName, resp.StatusCode, string(resp.Body)) + } + + var result CommonResponse + if err = json.Unmarshal(resp.Body, &result); err != nil { + return nil, fmt.Errorf("list user %s provider instance models failed: invalid JSON (%w)", userName, err) + } + + if result.Code != 0 { + return nil, fmt.Errorf("%s", result.Message) + } + + result.Duration = resp.Duration + return &result, nil +} + +func (c *CLI) AdminListUserDefaultModelsCommand(cmd *Command) (ResponseIf, error) { + + if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { + return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") + } + + userName, ok := cmd.Params["user_name"].(string) + if !ok { + return nil, fmt.Errorf("user_name not provided") + } + + encodedUserName := common.EncodeEmail(userName) + apiURL := fmt.Sprintf("/admin/users/%s/default-models", encodedUserName) + + resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to list user %s default models: %w", userName, err) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to list user %s default models: HTTP %d, body: %s", userName, resp.StatusCode, string(resp.Body)) + } + + var result CommonResponse + if err = json.Unmarshal(resp.Body, &result); err != nil { + return nil, fmt.Errorf("list user %s default models failed: invalid JSON (%w)", userName, err) + } + + if result.Code != 0 { + return nil, fmt.Errorf("%s", result.Message) + } + result.Duration = resp.Duration return &result, nil } diff --git a/internal/cli/admin_parser.go b/internal/cli/admin_parser.go index 15b84806f2..5fc5b385bd 100644 --- a/internal/cli/admin_parser.go +++ b/internal/cli/admin_parser.go @@ -96,42 +96,17 @@ func (p *Parser) parseAdminListCommand() (*Command, error) { case TokenVars: return p.parseAdminListVariables() case TokenConfigs: - p.nextToken() - // Semicolon is optional for SHOW TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return NewCommand("list_configs"), nil + return p.parseAdminListConfigs() case TokenEnvs: - p.nextToken() - // Semicolon is optional for SHOW TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return NewCommand("list_environments"), nil + return p.parseAdminListEnvironments() case TokenAvailable: - return p.parseCommonListProviders() + return p.parseListAvailableProviders() case TokenProvider: - return p.parseAdminListProvider() + return p.parseAdminListProviderModels() case TokenModels: return p.parseAdminListModels() case TokenUser: return p.parseAdminListUserCommand() - case TokenTokens: - return p.parseAdminListTokens() - case TokenModel: - return p.parseAdminListModelProviders() - case TokenDefault: - return p.parseAdminListDefaultModels() - case TokenChats: - p.nextToken() - // Semicolon is optional for SHOW TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return NewCommand("list_user_chats"), nil - case TokenFiles: - return p.parseAdminListFiles() case TokenIngestors: return p.parseAdminListIngestors() case TokenIngestion: @@ -183,51 +158,34 @@ func (p *Parser) parseAdminListVariables() (*Command, error) { return NewCommand("admin_list_variables"), nil } -func (p *Parser) parseAdminListTokens() (*Command, error) { - p.nextToken() // consume TOKENS - cmd := NewCommand("list_tokens") +func (p *Parser) parseAdminListConfigs() (*Command, error) { + p.nextToken() // consume CONFIGS - // Semicolon is optional for UNSET TOKEN + // Semicolon is optional if p.curToken.Type == TokenSemicolon { p.nextToken() } - return cmd, nil + return NewCommand("admin_list_configs"), nil } -func (p *Parser) parseAdminListModelProviders() (*Command, error) { - p.nextToken() // consume MODEL - if p.curToken.Type != TokenProviders { - return nil, fmt.Errorf("expected PROVIDERS") - } - p.nextToken() - // Semicolon is optional for UNSET TOKEN +func (p *Parser) parseAdminListEnvironments() (*Command, error) { + p.nextToken() // consume ENVIRONMENTS + + // Semicolon is optional if p.curToken.Type == TokenSemicolon { p.nextToken() } - return NewCommand("list_user_model_providers"), nil + return NewCommand("admin_list_environments"), nil } -func (p *Parser) parseAdminListDefaultModels() (*Command, error) { - p.nextToken() // consume DEFAULT - if p.curToken.Type != TokenModels { - return nil, fmt.Errorf("expected MODELS") - } - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return NewCommand("list_user_default_models"), nil -} - -func (p *Parser) parseCommonListProviders() (*Command, error) { +func (p *Parser) parseListAvailableProviders() (*Command, error) { p.nextToken() // consume AVAILABLE if p.curToken.Type != TokenProviders { return nil, fmt.Errorf("expected PROVIDERS") } - return NewCommand("list_available_providers"), nil + return NewCommand("admin_list_available_providers"), nil } func (p *Parser) parseAdminListFiles() (*Command, error) { @@ -283,7 +241,7 @@ func (p *Parser) parseAdminListIngestionTasks() (*Command, error) { } // LIST PROVIDER 'provider_name' MODELS; -func (p *Parser) parseAdminListProvider() (*Command, error) { +func (p *Parser) parseAdminListProviderModels() (*Command, error) { p.nextToken() // consume PROVIDER providerName, err := p.parseQuotedString() @@ -349,13 +307,13 @@ func (p *Parser) parseAdminShowCommand() (*Command, error) { case TokenAPI: return p.parseUserShowAPI() case TokenUsers: - return p.parseAdminShowUsersCommand() + return p.parseAdminShowUsersCommands() case TokenData: - return p.parseAdminShowDataCommand() + return p.parseAdminShowData() case TokenQuota: - return p.parseAdminShowQuotaCommand() + return p.parseAdminShowQuota() case TokenTasks: - return p.parseAdminShowTasksCommand() + return p.parseAdminShowTasks() default: return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value) } @@ -772,20 +730,20 @@ func (p *Parser) parseCommonShowPoolModel() (*Command, error) { // endregion SHOW commands -// parseAdminCheckCommand -func (p *Parser) parseAdminCheckCommand() (*Command, error) { +// parseAdminCheck +func (p *Parser) parseAdminCheck() (*Command, error) { p.nextToken() // consume CHECK switch p.curToken.Type { case TokenLicense: - return p.parseAdminCheckLicenseCommand() + return p.parseAdminCheckLicense() default: return nil, fmt.Errorf("unknown CHECK target: %s", p.curToken.Value) } } -func (p *Parser) parseAdminCheckLicenseCommand() (*Command, error) { +func (p *Parser) parseAdminCheckLicense() (*Command, error) { p.nextToken() // consume LICENSE - cmd := NewCommand("admin_check_license_command") + cmd := NewCommand("admin_check_license") // Semicolon is optional if p.curToken.Type == TokenSemicolon { @@ -864,23 +822,15 @@ func (p *Parser) parseAdminCreateCommand() (*Command, error) { switch p.curToken.Type { case TokenUser: - return p.parseAdminCreateUserCommand() + return p.parseAdminCreateUser() case TokenRole: - return p.parseAdminCreateRoleCommand() - case TokenModel: - return p.parseCreateModelProvider() - case TokenDataset: - return p.parseCreateDataset() - case TokenChat: - return p.parseCreateChat() - case TokenToken: - return p.parseCreateToken() + return p.parseAdminCreateRole() default: return nil, fmt.Errorf("unknown CREATE target: %s", p.curToken.Value) } } -func (p *Parser) parseAdminCreateUserCommand() (*Command, error) { +func (p *Parser) parseAdminCreateUser() (*Command, error) { p.nextToken() // consume USER userName, err := p.parseQuotedString() if err != nil { @@ -898,7 +848,7 @@ func (p *Parser) parseAdminCreateUserCommand() (*Command, error) { } p.nextToken() - cmd = NewCommand("admin_create_user_command") + cmd = NewCommand("admin_create_user") cmd.Params["user_name"] = userName cmd.Params["password"] = password cmd.Params["role"] = "user" @@ -925,20 +875,20 @@ func (p *Parser) parseAdminCreateUserAPIKeyCommand(userName string) (*Command, e p.nextToken() } - cmd := NewCommand("admin_create_user_api_key_command") + cmd := NewCommand("admin_create_user_api_key") cmd.Params["user_name"] = userName return cmd, nil } -func (p *Parser) parseAdminCreateRoleCommand() (*Command, error) { +func (p *Parser) parseAdminCreateRole() (*Command, error) { p.nextToken() // consume ROLE roleName, err := p.parseQuotedString() if err != nil { return nil, err } - cmd := NewCommand("admin_create_role_command") + cmd := NewCommand("admin_create_role") cmd.Params["role_name"] = roleName p.nextToken() @@ -960,125 +910,23 @@ func (p *Parser) parseAdminCreateRoleCommand() (*Command, error) { return cmd, nil } -func (p *Parser) parseAdminCreateModelProvider() (*Command, error) { - p.nextToken() // consume MODEL - if p.curToken.Type != TokenProvider { - return nil, fmt.Errorf("expected PROVIDER") - } - p.nextToken() - - providerName, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - p.nextToken() - providerKey, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - cmd := NewCommand("create_model_provider") - cmd.Params["provider_name"] = providerName - cmd.Params["provider_key"] = providerKey - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - -func (p *Parser) parseAdminCreateDataset() (*Command, error) { - p.nextToken() // consume DATASET - datasetName, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - p.nextToken() - if p.curToken.Type != TokenWith { - return nil, fmt.Errorf("expected WITH") - } - p.nextToken() - if p.curToken.Type != TokenEmbedding { - return nil, fmt.Errorf("expected EMBEDDING") - } - p.nextToken() - - embedding, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - p.nextToken() - cmd := NewCommand("create_user_dataset") - cmd.Params["dataset_name"] = datasetName - cmd.Params["embedding"] = embedding - - if p.curToken.Type == TokenParser { - p.nextToken() - parserType, err := p.parseQuotedString() - if err != nil { - return nil, err - } - cmd.Params["parser_type"] = parserType - p.nextToken() - } else if p.curToken.Type == TokenPipeline { - p.nextToken() - pipeline, err := p.parseQuotedString() - if err != nil { - return nil, err - } - cmd.Params["pipeline"] = pipeline - p.nextToken() - } else { - return nil, fmt.Errorf("expected PARSER or PIPELINE") - } - - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - -func (p *Parser) parseAdminCreateChat() (*Command, error) { - p.nextToken() // consume CHAT - chatName, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - cmd := NewCommand("create_user_chat") - cmd.Params["chat_name"] = chatName - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - // endregion CREATE commands // region DROP commands -func (p *Parser) parseAdminDropCommand() (*Command, error) { +func (p *Parser) parseAdminDropCommands() (*Command, error) { p.nextToken() // consume DROP switch p.curToken.Type { case TokenUser: - return p.parseAdminDropUserCommand() + return p.parseAdminDropUser() case TokenRole: - return p.parseAdminDropRoleCommand() + return p.parseAdminDropRole() default: return nil, fmt.Errorf("unknown DROP target: %s", p.curToken.Value) } } -func (p *Parser) parseAdminDropUserCommand() (*Command, error) { +func (p *Parser) parseAdminDropUser() (*Command, error) { p.nextToken() // consume USER if p.curToken.Type != TokenQuotedString { @@ -1093,17 +941,17 @@ func (p *Parser) parseAdminDropUserCommand() (*Command, error) { switch p.curToken.Type { case TokenKey: - return p.parseAdminDropUserAPIKeyCommand(userName) + return p.parseAdminDropUserAPIKey(userName) default: p.nextToken() } - cmd := NewCommand("admin_drop_user_command") + cmd := NewCommand("admin_drop_user") cmd.Params["user_name"] = userName return cmd, nil } -func (p *Parser) parseAdminDropUserAPIKeyCommand(userName string) (*Command, error) { +func (p *Parser) parseAdminDropUserAPIKey(userName string) (*Command, error) { p.nextToken() // consume KEY apiKey, err := p.parseQuotedString() @@ -1116,21 +964,21 @@ func (p *Parser) parseAdminDropUserAPIKeyCommand(userName string) (*Command, err p.nextToken() } - cmd := NewCommand("admin_drop_user_api_key_command") + cmd := NewCommand("admin_drop_user_api_key") cmd.Params["user_name"] = userName cmd.Params["api_key"] = apiKey return cmd, nil } -func (p *Parser) parseAdminDropRoleCommand() (*Command, error) { +func (p *Parser) parseAdminDropRole() (*Command, error) { p.nextToken() // consume ROLE - roleName, err := p.parseIdentifier() + roleName, err := p.parseQuotedString() if err != nil { return nil, err } - cmd := NewCommand("drop_role") + cmd := NewCommand("admin_drop_role") cmd.Params["role_name"] = roleName p.nextToken() @@ -1203,14 +1051,14 @@ func (p *Parser) parseAdminDropChat() (*Command, error) { // endregion DROP commands // region ALTER commands -func (p *Parser) parseAdminAlterCommand() (*Command, error) { +func (p *Parser) parseAdminAlterCommands() (*Command, error) { p.nextToken() // consume ALTER switch p.curToken.Type { case TokenUser: - return p.parseAlterUser() + return p.parseAdminAlterUser() case TokenRole: - return p.parseAlterRole() + return p.parseAdminAlterRole() default: return nil, fmt.Errorf("unknown ALTER target: %s", p.curToken.Value) } @@ -1220,7 +1068,7 @@ func (p *Parser) parseAdminAlterUser() (*Command, error) { p.nextToken() // consume USER if p.curToken.Type == TokenActive { - return p.parseActivateUser() + return p.parseAdminActivateUser() } if p.curToken.Type == TokenPassword { @@ -1236,7 +1084,7 @@ func (p *Parser) parseAdminAlterUser() (*Command, error) { return nil, err } - cmd := NewCommand("alter_user") + cmd := NewCommand("admin_alter_user") cmd.Params["user_name"] = userName cmd.Params["password"] = password @@ -1329,7 +1177,7 @@ func (p *Parser) parseAdminActivateUser() (*Command, error) { return nil, fmt.Errorf("expected 'on' or 'off', got %s", p.curToken.Value) } - cmd := NewCommand("activate_user") + cmd := NewCommand("admin_activate_user") cmd.Params["user_name"] = userName cmd.Params["activate_status"] = status @@ -1345,10 +1193,10 @@ func (p *Parser) parseAdminGrantCommand() (*Command, error) { p.nextToken() // consume GRANT if p.curToken.Type == TokenAdmin { - return p.parseGrantAdmin() + return p.parseAdminGrantAdmin() } - return p.parseGrantPermission() + return p.parseAdminGrantPermission() } func (p *Parser) parseAdminGrantAdmin() (*Command, error) { @@ -1417,10 +1265,10 @@ func (p *Parser) parseAdminRevokeCommand() (*Command, error) { p.nextToken() // consume REVOKE if p.curToken.Type == TokenAdmin { - return p.parseRevokeAdmin() + return p.parseAdminRevokeAdmin() } - return p.parseRevokePermission() + return p.parseAdminRevokePermission() } func (p *Parser) parseAdminRevokeAdmin() (*Command, error) { @@ -2241,7 +2089,7 @@ func (p *Parser) parseAdminRemoveCommand() (*Command, error) { // SHOW USERS SUMMARY; // SHOW USERS ACTIVITY; -func (p *Parser) parseAdminShowUsersCommand() (*Command, error) { +func (p *Parser) parseAdminShowUsersCommands() (*Command, error) { p.nextToken() // consume USERS switch p.curToken.Type { @@ -2250,14 +2098,14 @@ func (p *Parser) parseAdminShowUsersCommand() (*Command, error) { cmd := NewCommand("admin_show_users_summary_command") return cmd, nil case TokenActivity: - return p.parseAdminShowUsersActivityCommand() + return p.parseAdminShowUsersActivity() default: return nil, fmt.Errorf("invalid command") } } // SHOW USERS ACTIVITY WINDOW 2 DAYS 30; -func (p *Parser) parseAdminShowUsersActivityCommand() (*Command, error) { +func (p *Parser) parseAdminShowUsersActivity() (*Command, error) { p.nextToken() // consume ACTIVITY var days int @@ -2434,25 +2282,25 @@ commandLoop: // SHOW DATA ORPHAN; // SHOW DATA STORAGE; // SHOW DATA INDEX; -func (p *Parser) parseAdminShowDataCommand() (*Command, error) { - p.nextToken() // consume ALL +func (p *Parser) parseAdminShowData() (*Command, error) { + p.nextToken() // consume DATA var cmd *Command switch p.curToken.Type { case TokenSummary: p.nextToken() - cmd = NewCommand("admin_show_data_summary_command") + cmd = NewCommand("admin_show_data_summary") case TokenOrphan: p.nextToken() - cmd = NewCommand("admin_show_data_orphan_command") + cmd = NewCommand("admin_show_data_orphan") case TokenStorage: p.nextToken() - cmd = NewCommand("admin_show_data_storage_command") + cmd = NewCommand("admin_show_data_storage") case TokenIndex: p.nextToken() - cmd = NewCommand("admin_show_data_index_command") + cmd = NewCommand("admin_show_data_index") default: - return nil, fmt.Errorf("expected SUMMARY, ORPHAN, STORAGE, INDEX, TASKS, QUOTA_SUMMARY after ALL") + return nil, fmt.Errorf("expected SUMMARY, ORPHAN, STORAGE, INDEX after DATA") } // Semicolon is optional @@ -2463,14 +2311,14 @@ func (p *Parser) parseAdminShowDataCommand() (*Command, error) { } // SHOW QUOTA SUMMARY; -func (p *Parser) parseAdminShowQuotaCommand() (*Command, error) { +func (p *Parser) parseAdminShowQuota() (*Command, error) { p.nextToken() // consume QUOTA var cmd *Command switch p.curToken.Type { case TokenSummary: p.nextToken() - cmd = NewCommand("admin_show_quota_summary_command") + cmd = NewCommand("admin_show_quota_summary") default: return nil, fmt.Errorf("expected SUMMARY after QUOTA") } @@ -2483,14 +2331,14 @@ func (p *Parser) parseAdminShowQuotaCommand() (*Command, error) { } // SHOW TASKS SUMMARY; -func (p *Parser) parseAdminShowTasksCommand() (*Command, error) { +func (p *Parser) parseAdminShowTasks() (*Command, error) { p.nextToken() // consume TASKS var cmd *Command switch p.curToken.Type { case TokenSummary: p.nextToken() - cmd = NewCommand("admin_show_tasks_summary_command") + cmd = NewCommand("admin_show_tasks_summary") default: return nil, fmt.Errorf("expected SUMMARY after TASKS") } @@ -2632,6 +2480,13 @@ commandLoop: } // LIST USER 'user@example.com' INGESTION TASKS; +// LIST USER 'user@example.com' DATASETS; +// LIST USER 'user@example.com' AGENTS; +// LIST USER 'user@example.com' CHATS; +// LIST USER 'user@example.com' SEARCHES; +// LIST USER 'user@example.com' MODELS; // all added models +// LIST USER 'user@example.com' FILES; +// LIST USER 'user@example.com' KEYS; // LIST USER 'user_name' PROVIDER 'provider_name' INSTANCE 'instance_name' MODELS; func (p *Parser) parseAdminListUserCommand() (*Command, error) { p.nextToken() // consume USER @@ -2646,44 +2501,37 @@ func (p *Parser) parseAdminListUserCommand() (*Command, error) { switch p.curToken.Type { case TokenIngestion: - p.nextToken() - if p.curToken.Type != TokenTasks { - return nil, fmt.Errorf("expected TASKS after INGESTION") - } - p.nextToken() - cmd = NewCommand("admin_list_user_ingestion_tasks_command") - if p.curToken.Type == TokenQuotedString { - var status string - status, err = p.parseQuotedString() - if err != nil { - return nil, err - } - cmd.Params["status"] = status - p.nextToken() - } + return p.parseAdminListUserIngestionTasks(userName) case TokenDatasets: p.nextToken() - cmd = NewCommand("admin_list_user_datasets_command") + cmd = NewCommand("admin_list_user_datasets") case TokenAgents: p.nextToken() - cmd = NewCommand("admin_list_user_agents_command") + cmd = NewCommand("admin_list_user_agents") case TokenChats: p.nextToken() - cmd = NewCommand("admin_list_user_chats_command") + cmd = NewCommand("admin_list_user_chats") case TokenSearches: p.nextToken() - cmd = NewCommand("admin_list_user_searches_command") + cmd = NewCommand("admin_list_user_searches") case TokenModels: p.nextToken() - cmd = NewCommand("admin_list_user_models_command") + cmd = NewCommand("admin_list_user_models") case TokenFiles: p.nextToken() - cmd = NewCommand("admin_list_user_files_command") + cmd = NewCommand("admin_list_user_files") case TokenKeys: p.nextToken() - cmd = NewCommand("admin_list_user_keys_command") + cmd = NewCommand("admin_list_user_keys") + case TokenProvider: + return p.parseAdminListUserProviderInstanceModels(userName) + case TokenProviders: + p.nextToken() + cmd = NewCommand("admin_list_user_providers") + case TokenDefault: + return p.parseAdminListUserDefaultModels(userName) default: - return nil, fmt.Errorf("expected INGESTION or DATASETS or AGENTS or CHATS or SEARCHES or MODELS or FILES after USER") + return nil, fmt.Errorf("expected INGESTION or DATASETS or AGENTS or CHATS or SEARCHES or MODELS or FILES or KEYS after USER") } // Semicolon is optional @@ -2695,6 +2543,99 @@ func (p *Parser) parseAdminListUserCommand() (*Command, error) { return cmd, nil } +// LIST USER 'user@example.com' INGESTION TASKS 'status'; +func (p *Parser) parseAdminListUserIngestionTasks(userName string) (*Command, error) { + p.nextToken() // consume INGESTION + + if p.curToken.Type != TokenTasks { + return nil, fmt.Errorf("expected TASKS after INGESTION") + } + p.nextToken() + + cmd := NewCommand("admin_list_user_ingestion_tasks") + cmd.Params["user_name"] = userName + + if p.curToken.Type == TokenQuotedString { + var status string + var err error + status, err = p.parseQuotedString() + if err != nil { + return nil, err + } + cmd.Params["status"] = status + p.nextToken() + } + return cmd, nil +} + +// LIST USER 'user_name' PROVIDER 'provider_name' INSTANCES; +// LIST USER 'user_name' PROVIDER 'provider_name' INSTANCE 'instance_name' MODELS; +func (p *Parser) parseAdminListUserProviderInstanceModels(userName string) (*Command, error) { + p.nextToken() // consume PROVIDER + + providerName, err := p.parseQuotedString() + if err != nil { + return nil, err + } + p.nextToken() + + if p.curToken.Type == TokenInstances { + p.nextToken() + cmd := NewCommand("admin_list_user_provider_instances") + cmd.Params["user_name"] = userName + cmd.Params["provider_name"] = providerName + + if p.curToken.Type == TokenSemicolon { + p.nextToken() + } + return cmd, nil + } + + if p.curToken.Type != TokenInstance { + return nil, fmt.Errorf("expected INSTANCE after PROVIDER") + } + p.nextToken() + + instanceName, err := p.parseQuotedString() + if err != nil { + return nil, err + } + p.nextToken() + + if p.curToken.Type != TokenModels { + return nil, fmt.Errorf("expected MODELS after INSTANCE") + } + p.nextToken() + + cmd := NewCommand("admin_list_user_provider_instance_models") + cmd.Params["user_name"] = userName + cmd.Params["provider_name"] = providerName + cmd.Params["instance_name"] = instanceName + + if p.curToken.Type == TokenSemicolon { + p.nextToken() + } + return cmd, nil +} + +// LIST USER 'user_name' DEFAULT MODELS; +func (p *Parser) parseAdminListUserDefaultModels(userName string) (*Command, error) { + p.nextToken() // consume DEFAULT + + if p.curToken.Type != TokenModels { + return nil, fmt.Errorf("expected MODELS after INSTANCE") + } + p.nextToken() + + cmd := NewCommand("admin_list_user_default_models") + cmd.Params["user_name"] = userName + + if p.curToken.Type == TokenSemicolon { + p.nextToken() + } + return cmd, nil +} + // STOP USER 'user@example.com' INGESTION TASKS 'created'; func (p *Parser) parseAdminStopUserCommand() (*Command, error) { p.nextToken() // consume USER diff --git a/internal/cli/cli_http.go b/internal/cli/cli_http.go index ea875047f0..0c176d6b7f 100644 --- a/internal/cli/cli_http.go +++ b/internal/cli/cli_http.go @@ -51,20 +51,24 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) { return c.GrantAdmin(cmd) case "revoke_admin": return c.RevokeAdmin(cmd) - case "admin_create_user_command": + case "admin_create_user": return c.AdminCreateUserCommand(cmd) - case "admin_create_user_api_key_command": + case "admin_create_user_api_key": return c.AdminCreateUserAPIKeyCommand(cmd) - case "admin_create_role_command": + case "admin_create_role": return c.AdminCreateRoleCommand(cmd) - case "activate_user": - return c.ActivateUser(cmd) - case "alter_user": - return c.AlterUserPassword(cmd) - case "admin_drop_user_command": + case "admin_activate_user": + return c.AdminActivateUser(cmd) + case "admin_alter_user": + return c.AdminAlterUserPassword(cmd) + case "admin_alter_role": + return c.AdminAlterRole(cmd) + case "admin_drop_user": return c.AdminDropUserCommand(cmd) - case "admin_drop_user_api_key_command": + case "admin_drop_user_api_key": return c.AdminDropUserAPIKeyCommand(cmd) + case "admin_drop_role": + return c.AdminDropRoleCommand(cmd) case "admin_show_service": return c.AdminShowService(cmd) case "admin_show_version_command": @@ -72,7 +76,11 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) { case "admin_show_current": return c.CommonShowCurrent(cmd) case "admin_list_variables": - return c.AdminListVariables(cmd) + return c.AdminListVariablesCommand(cmd) + case "admin_list_configs": + return c.AdminListConfigsCommand(cmd) + case "admin_list_environments": + return c.AdminListEnvironmentsCommand(cmd) case "admin_show_variable": return c.AdminShowVariable(cmd) case "admin_set_license_command": @@ -89,10 +97,8 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) { return c.AdminListRolesCommand(cmd) case "generate_token": return c.GenerateAdminToken(cmd) - case "list_tokens": - return c.ListAdminTokens(cmd) - case "list_available_providers": - return c.ListAvailableProviders(cmd) + case "admin_list_available_providers": + return c.CommonAvailableProvidersCommand(cmd) case "admin_show_provider": return c.CommonShowProviderCommand(cmd) case "admin_show_provider_model": @@ -129,7 +135,7 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) { return c.UserShowMessageQueueCommand(cmd) case "admin_remove_service_command": return c.AdminRemoveServiceCommand(cmd) - case "admin_check_license_command": + case "admin_check_license": return c.AdminCheckLicenseCommand(cmd) case "admin_show_fingerprint": return c.AdminShowFingerprintCommand(cmd) @@ -161,17 +167,17 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) { return c.AdminListUsersCommand(cmd) case "admin_list_users_condition_command": return c.AdminListUsersConditionCommand(cmd) - case "admin_show_quota_summary_command": + case "admin_show_quota_summary": return c.AdminShowQuotaSummaryCommand(cmd) - case "admin_show_tasks_summary_command": + case "admin_show_tasks_summary": return c.AdminShowTasksSummaryCommand(cmd) - case "admin_show_data_summary_command": + case "admin_show_data_summary": return c.AdminShowDataSummaryCommand(cmd) - case "admin_show_data_orphan_command": + case "admin_show_data_orphan": return c.AdminShowDataOrphanCommand(cmd) - case "admin_show_data_storage_command": + case "admin_show_data_storage": return c.AdminShowDataStorageCommand(cmd) - case "admin_show_data_index_command": + case "admin_show_data_index": return c.AdminShowDataIndexCommand(cmd) case "admin_purge_orphan_command": return c.AdminPurgeOrphanCommand(cmd) @@ -179,22 +185,30 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) { return c.AdminPurgeUserCommand(cmd) case "admin_purge_users_command": return c.AdminPurgeUsersCommand(cmd) - case "admin_list_user_ingestion_tasks_command": + case "admin_list_user_ingestion_tasks": return c.AdminListUserIngestionTasksCommand(cmd) - case "admin_list_user_datasets_command": + case "admin_list_user_datasets": return c.AdminListUserDatasetsCommand(cmd) - case "admin_list_user_agents_command": + case "admin_list_user_agents": return c.AdminListUserAgentsCommand(cmd) - case "admin_list_user_chats_command": + case "admin_list_user_chats": return c.AdminListUserChatsCommand(cmd) - case "admin_list_user_searches_command": + case "admin_list_user_searches": return c.AdminListUserSearchesCommand(cmd) - case "admin_list_user_models_command": + case "admin_list_user_models": return c.AdminListUserModelsCommand(cmd) - case "admin_list_user_files_command": + case "admin_list_user_files": return c.AdminListUserFilesCommand(cmd) - case "admin_list_user_keys_command": + case "admin_list_user_keys": return c.AdminListUserKeysCommand(cmd) + case "admin_list_user_providers": + return c.AdminListUserProvidersCommand(cmd) + case "admin_list_user_provider_instances": + return c.AdminListUserProviderInstancesCommand(cmd) + case "admin_list_user_provider_instance_models": + return c.AdminListUserProviderInstanceModelsCommand(cmd) + case "admin_list_user_default_models": + return c.AdminListUserDefaultModelsCommand(cmd) case "admin_stop_user_ingestion_tasks_command": return c.AdminStopUserIngestionTasksCommand(cmd) case "admin_remove_user_ingestion_tasks_command": @@ -267,7 +281,7 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) { case "show_current": return c.CommonShowCurrent(cmd) case "list_available_providers": - return c.ListAvailableProviders(cmd) + return c.CommonAvailableProvidersCommand(cmd) case "show_provider": return c.CommonShowProviderCommand(cmd) case "list_provider_models": diff --git a/internal/cli/common_command.go b/internal/cli/common_command.go index 097da23eb3..1fb646b94a 100644 --- a/internal/cli/common_command.go +++ b/internal/cli/common_command.go @@ -250,7 +250,7 @@ func (c *CLI) Logout() (ResponseIf, error) { return &result, nil } -func (c *CLI) ListAvailableProviders(cmd *Command) (ResponseIf, error) { +func (c *CLI) CommonAvailableProvidersCommand(cmd *Command) (ResponseIf, error) { var resp *Response var err error diff --git a/internal/cli/parser.go b/internal/cli/parser.go index 0ddfb7711e..4c6bc911b0 100644 --- a/internal/cli/parser.go +++ b/internal/cli/parser.go @@ -91,13 +91,13 @@ func (p *Parser) parseAdminCommand() (*Command, error) { case TokenShow: return p.parseAdminShowCommand() case TokenCheck: - return p.parseAdminCheckCommand() + return p.parseAdminCheck() case TokenCreate: return p.parseAdminCreateCommand() case TokenDrop: - return p.parseAdminDropCommand() + return p.parseAdminDropCommands() case TokenAlter: - return p.parseAdminAlterCommand() + return p.parseAdminAlterCommands() case TokenGrant: return p.parseAdminGrantCommand() case TokenRevoke: @@ -169,10 +169,6 @@ func (p *Parser) parseUserCommand() (*Command, error) { return p.parseDeleteCommand() case TokenAlter: return p.parseAlterCommand() - case TokenGrant: - return p.parseGrantCommand() - case TokenRevoke: - return p.parseRevokeCommand() case TokenSet: return p.parseSetCommand() case TokenUnset: diff --git a/internal/cli/user_parser.go b/internal/cli/user_parser.go index 63ca079a30..573965cc13 100644 --- a/internal/cli/user_parser.go +++ b/internal/cli/user_parser.go @@ -170,7 +170,7 @@ func (p *Parser) parseListCommand() (*Command, error) { case TokenDefault: return p.parseListDefaultModels() case TokenAvailable: - return p.parseCommonListProviders() + return p.parseListAvailableProviders() case TokenChats: p.nextToken() // Semicolon is optional for SHOW TOKEN @@ -561,10 +561,6 @@ func (p *Parser) parseCreateCommand() (*Command, error) { p.nextToken() // consume CREATE switch p.curToken.Type { - case TokenUser: - return p.parseAdminCreateUserCommand() - case TokenRole: - return p.parseCreateRole() case TokenModel: return p.parseCreateModelProvider() case TokenDataset: @@ -1496,10 +1492,6 @@ func (p *Parser) parseAlterCommand() (*Command, error) { p.nextToken() // consume ALTER switch p.curToken.Type { - case TokenUser: - return p.parseAlterUser() - case TokenRole: - return p.parseAlterRole() case TokenProvider: return p.parseAlterProvider() case TokenInstance: @@ -1509,130 +1501,6 @@ func (p *Parser) parseAlterCommand() (*Command, error) { } } -func (p *Parser) parseAlterUser() (*Command, error) { - p.nextToken() // consume USER - - if p.curToken.Type == TokenActive { - return p.parseActivateUser() - } - - if p.curToken.Type == TokenPassword { - p.nextToken() - userName, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - p.nextToken() - password, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - cmd := NewCommand("alter_user") - cmd.Params["user_name"] = userName - cmd.Params["password"] = password - - p.nextToken() - // Semicolon is optional for SHOW TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil - } - - userName, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - p.nextToken() - if p.curToken.Type != TokenSet { - return nil, fmt.Errorf("expected SET") - } - p.nextToken() - if p.curToken.Type != TokenRole { - return nil, fmt.Errorf("expected ROLE") - } - p.nextToken() - - roleName, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - cmd := NewCommand("alter_user_role") - cmd.Params["user_name"] = userName - cmd.Params["role_name"] = roleName - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - -func (p *Parser) parseActivateUser() (*Command, error) { - p.nextToken() // consume ACTIVE - userName, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - p.nextToken() - // Accept 'on' or 'off' as identifier - status := p.curToken.Value - if status != "on" && status != "off" { - return nil, fmt.Errorf("expected 'on' or 'off', got %s", p.curToken.Value) - } - - cmd := NewCommand("activate_user") - cmd.Params["user_name"] = userName - cmd.Params["activate_status"] = status - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - -func (p *Parser) parseAlterRole() (*Command, error) { - p.nextToken() // consume ROLE - roleName, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - p.nextToken() - if p.curToken.Type != TokenSet { - return nil, fmt.Errorf("expected SET") - } - p.nextToken() - if p.curToken.Type != TokenDescription { - return nil, fmt.Errorf("expected DESCRIPTION") - } - p.nextToken() - - description, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - cmd := NewCommand("alter_role") - cmd.Params["role_name"] = roleName - cmd.Params["description"] = description - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - // parseAlterProvider parses ALTER PROVIDER NAME command func (p *Parser) parseAlterProvider() (*Command, error) { p.nextToken() // consume PROVIDER @@ -1990,150 +1858,6 @@ func (p *Parser) parseDropInstanceModel() (*Command, error) { return cmd, nil } -func (p *Parser) parseGrantCommand() (*Command, error) { - p.nextToken() // consume GRANT - - if p.curToken.Type == TokenAdmin { - return p.parseGrantAdmin() - } - - return p.parseGrantPermission() -} - -func (p *Parser) parseGrantAdmin() (*Command, error) { - p.nextToken() // consume ADMIN - userName, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - cmd := NewCommand("grant_admin") - cmd.Params["user_name"] = userName - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - -func (p *Parser) parseGrantPermission() (*Command, error) { - actions, err := p.parseIdentifierList() - if err != nil { - return nil, err - } - - if p.curToken.Type != TokenOn { - return nil, fmt.Errorf("expected ON") - } - p.nextToken() - - resource, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - p.nextToken() - if p.curToken.Type != TokenTo { - return nil, fmt.Errorf("expected TO") - } - p.nextToken() - if p.curToken.Type != TokenRole { - return nil, fmt.Errorf("expected ROLE") - } - p.nextToken() - - roleName, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - cmd := NewCommand("grant_permission") - cmd.Params["actions"] = actions - cmd.Params["resource"] = resource - cmd.Params["role_name"] = roleName - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - -func (p *Parser) parseRevokeCommand() (*Command, error) { - p.nextToken() // consume REVOKE - - if p.curToken.Type == TokenAdmin { - return p.parseRevokeAdmin() - } - - return p.parseRevokePermission() -} - -func (p *Parser) parseRevokeAdmin() (*Command, error) { - p.nextToken() // consume ADMIN - userName, err := p.parseQuotedString() - if err != nil { - return nil, err - } - - cmd := NewCommand("revoke_admin") - cmd.Params["user_name"] = userName - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - -func (p *Parser) parseRevokePermission() (*Command, error) { - actions, err := p.parseIdentifierList() - if err != nil { - return nil, err - } - - if p.curToken.Type != TokenOn { - return nil, fmt.Errorf("expected ON") - } - p.nextToken() - - resource, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - p.nextToken() - if p.curToken.Type != TokenFrom { - return nil, fmt.Errorf("expected FROM") - } - p.nextToken() - if p.curToken.Type != TokenRole { - return nil, fmt.Errorf("expected ROLE") - } - p.nextToken() - - roleName, err := p.parseIdentifier() - if err != nil { - return nil, err - } - - cmd := NewCommand("revoke_permission") - cmd.Params["actions"] = actions - cmd.Params["resource"] = resource - cmd.Params["role_name"] = roleName - - p.nextToken() - // Semicolon is optional for UNSET TOKEN - if p.curToken.Type == TokenSemicolon { - p.nextToken() - } - return cmd, nil -} - func (p *Parser) parseIdentifierList() ([]string, error) { var list []string