package permissions import ( "fmt" "strings" "xcecli/common/request" "xcecli/config" "xcecli/models" "github.com/spf13/cobra" ) var ( resp models.PermsResponse ) const ( minIDWidth = 7 // Length of "PERM_ID" minNameWidth = 9 // Length of "PERM_NAME" padding = 2 maxNameWidth = 60 ) type PermsQuerier struct { configManager *config.ConfigManager noHeader bool fields []string } func NewPermsQuerier(configManager *config.ConfigManager) *PermsQuerier { return &PermsQuerier{ configManager: configManager, } } func NewListPermsCmd(configManager *config.ConfigManager) *cobra.Command { permsQuerier := NewPermsQuerier(configManager) listCmd := &cobra.Command{ Use: "list", Short: "Query permissions info", Long: `Query permissions detail info. Example: xce permissions list # list all permissions`, RunE: func(cmd *cobra.Command, args []string) error { if err := permsQuerier.ParseCmdArgs(cmd, args); err != nil { fmt.Println(strings.ToLower(err.Error())) return nil } if err := permsQuerier.RunPermsList(); err != nil { fmt.Println(strings.ToLower(err.Error())) return nil } return nil }, } flags := listCmd.Flags() flags.BoolVarP(&permsQuerier.noHeader, "noheader", "n", false, "output no header") return listCmd } func (pq *PermsQuerier) ParseCmdArgs(cmd *cobra.Command, args []string) error { // No additional processing needed, all parameters are bound in flags if len(args) > 0 { return fmt.Errorf("too many arguments") } return nil } func (pq *PermsQuerier) RunPermsList() error { // Get server information serverInfo, err := pq.configManager.GetServerInfo() if err != nil { return fmt.Errorf("failed to get server info: %w", err) } // create API client apiClient := request.NewAPIClient(serverInfo.URL) // Build query parameters params := make(map[string]string) pq.fields = []string{} // Make API request err = apiClient.GetRequestFromAPIServer(serverInfo.Token, "", "/xce/v1/permissions", &resp, params) if err != nil { return err } data := resp.Data if len(data) == 0 { fmt.Println("no permissions found") return nil } // Calculate column widths for proper alignment permIDWidth := minIDWidth + padding permNameWidth := minNameWidth + padding // Get the maximum ID width (last item) if len(data) > 0 { lastIDStr := fmt.Sprintf("%d", len(data)) if len(lastIDStr) > permIDWidth-padding { permIDWidth = len(lastIDStr) + padding } } // Get maximum permission name width for _, permStr := range data { if len(permStr) > permNameWidth-padding { permNameWidth = len(permStr) + padding } } // Apply max width limit if permNameWidth > maxNameWidth { permNameWidth = maxNameWidth } // Add headers with proper alignment if !pq.noHeader { fmt.Printf("%-*s %-*s\n", permIDWidth, "PERM_ID", permNameWidth, "PERM_NAME") } // Print permissions with auto-incrementing IDs and aligned columns for i, permStr := range data { // Truncate long permission names displayPermStr := permStr if len(permStr) > permNameWidth-padding { displayPermStr = permStr[:permNameWidth-padding] + ".." } fmt.Printf("%-*d %-*s\n", permIDWidth, i+1, permNameWidth, displayPermStr) } return nil }