Skip to content

Implement a no-paging flag and get port dynamically #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,14 +511,16 @@ func createServiceCommand(serviceName string) *cobra.Command {

sortBy := ""
columns := ""
limit := 0
pageSize := 100 // 기본 페이지 크기
rows := 0
pageSize := 100
noPaging := false

if verb == "list" {
sortBy, _ = cmd.Flags().GetString("sort")
columns, _ = cmd.Flags().GetString("columns")
limit, _ = cmd.Flags().GetInt("limit")
pageSize, _ = cmd.Flags().GetInt("page-size")
rows, _ = cmd.Flags().GetInt("rows")
pageSize, _ = cmd.Flags().GetInt("rows-per-page")
noPaging, _ = cmd.Flags().GetBool("no-paging")
}

options := &transport.FetchOptions{
Expand All @@ -531,8 +533,9 @@ func createServiceCommand(serviceName string) *cobra.Command {
SortBy: sortBy,
MinimalColumns: verb == "list" && cmd.Flag("minimal") != nil && cmd.Flag("minimal").Changed,
Columns: columns,
Limit: limit,
Rows: rows,
PageSize: pageSize,
NoPaging: noPaging,
}

if verb == "list" && !cmd.Flags().Changed("output") {
Expand Down Expand Up @@ -561,8 +564,9 @@ func createServiceCommand(serviceName string) *cobra.Command {
cmd.Flags().StringP("sort", "s", "", "Sort by field (e.g. 'name', 'created_at')")
cmd.Flags().BoolP("minimal", "m", false, "Show minimal columns")
cmd.Flags().StringP("columns", "c", "", "Specific columns (-c id,name)")
cmd.Flags().IntP("limit", "l", 0, "Number of rows")
cmd.Flags().IntP("page-size", "n", 15, "Number of items per page")
cmd.Flags().IntP("rows", "r", 0, "Number of rows")
cmd.Flags().IntP("rows-per-page", "n", 15, "Number of rows per page")
cmd.Flags().BoolP("no-paging", "", false, "Disable pagination and show all results")

// Add existing flags
cmd.Flags().StringArrayP("parameter", "p", []string{}, "Input Parameter (-p <key>=<value> -p ...)")
Expand Down
37 changes: 30 additions & 7 deletions pkg/configs/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,45 @@ func RemoveAlias(service, key string) error {
return fmt.Errorf("alias '%s' not found in service '%s'", key, service)
}

// Delete the specific alias
delete(serviceAliases, key)

// If service has no more aliases, remove the service
if len(serviceAliases) == 0 {
delete(aliases, service)
} else {
aliases[service] = serviceAliases
}

config["aliases"] = aliases
// Only remove aliases section if there are no services left
if len(aliases) == 0 {
delete(config, "aliases")
newData, err := yaml.Marshal(config)
if err != nil {
return fmt.Errorf("failed to encode config: %v", err)
}
if err := os.WriteFile(settingPath, newData, 0644); err != nil {
return fmt.Errorf("failed to write config: %v", err)
}
} else {
// Keep aliases and write at the end
delete(config, "aliases")
newData, err := yaml.Marshal(config)
if err != nil {
return fmt.Errorf("failed to encode config: %v", err)
}

newData, err := yaml.Marshal(config)
if err != nil {
return fmt.Errorf("failed to encode config: %v", err)
}
aliasData, err := yaml.Marshal(map[string]interface{}{
"aliases": aliases,
})
if err != nil {
return fmt.Errorf("failed to encode aliases: %v", err)
}

if err := os.WriteFile(settingPath, newData, 0644); err != nil {
return fmt.Errorf("failed to write config: %v", err)
finalData := append(newData, aliasData...)
if err := os.WriteFile(settingPath, finalData, 0644); err != nil {
return fmt.Errorf("failed to write config: %v", err)
}
}

return nil
Expand Down
4 changes: 2 additions & 2 deletions pkg/configs/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
// GetAPIEndpoint fetches the actual API endpoint from the config endpoint
func GetAPIEndpoint(endpoint string) (string, error) {
// Handle gRPC+SSL protocol
if strings.HasPrefix(endpoint, "grpc+ssl://") {
if strings.HasPrefix(endpoint, "grpc+ssl://") || strings.HasPrefix(endpoint, "grpc://") {
// For gRPC+SSL endpoints, return as is since it's already in the correct format
return endpoint, nil
}
Expand Down Expand Up @@ -66,7 +66,7 @@ func GetAPIEndpoint(endpoint string) (string, error) {
// GetIdentityEndpoint fetches the identity service endpoint from the API endpoint
func GetIdentityEndpoint(apiEndpoint string) (string, bool, error) {
// If the endpoint is already gRPC+SSL
if strings.HasPrefix(apiEndpoint, "grpc+ssl://") {
if strings.HasPrefix(apiEndpoint, "grpc+ssl://") || strings.HasPrefix(apiEndpoint, "grpc://") {
// Check if it contains 'identity'
containsIdentity := strings.Contains(apiEndpoint, "identity")

Expand Down
68 changes: 48 additions & 20 deletions pkg/transport/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ type Environment struct {
Endpoint string `yaml:"endpoint"`
Proxy string `yaml:"proxy"`
Token string `yaml:"token"`
URL string `yaml:"url"`
}

type Config struct {
Expand All @@ -58,9 +57,10 @@ type FetchOptions struct {
SortBy string
MinimalColumns bool
Columns string
Limit int
Rows int
Page int
PageSize int
NoPaging bool
}

// FetchService handles the execution of gRPC commands for all services
Expand Down Expand Up @@ -205,12 +205,16 @@ func FetchService(serviceName string, verb string, resourceName string, options
}

domainParts := strings.Split(urlParts[1], ".")
if len(domainParts) < 4 {
return nil, fmt.Errorf("invalid domain format in API endpoint: %s", apiEndpoint)
}
if len(domainParts) > 0 {
port := extractPortFromParts(domainParts)
if strings.Contains(domainParts[len(domainParts)-1], ":") {
parts := strings.Split(domainParts[len(domainParts)-1], ":")
domainParts[len(domainParts)-1] = parts[0]
}

domainParts[0] = format.ConvertServiceName(serviceName)
hostPort = strings.Join(domainParts, ".") + ":443"
domainParts[0] = format.ConvertServiceName(serviceName)
hostPort = strings.Join(domainParts, ".") + port
}
} else {
trimmedEndpoint := strings.TrimPrefix(identityEndpoint, "grpc+ssl://")
parts := strings.Split(trimmedEndpoint, ".")
Expand Down Expand Up @@ -349,11 +353,10 @@ func FetchService(serviceName string, verb string, resourceName string, options
}
}

// Apply limit if specified
if options.Limit > 0 && verb == "list" {
if options.Rows > 0 && verb == "list" {
if results, ok := respMap["results"].([]interface{}); ok {
if len(results) > options.Limit {
respMap["results"] = results[:options.Limit]
if len(results) > options.Rows {
respMap["results"] = results[:options.Rows]
}
}
}
Expand Down Expand Up @@ -397,6 +400,22 @@ func extractParameterName(errMsg string) string {
return ""
}

func extractPortFromParts(parts []string) string {
if len(parts) == 0 {
return ":443"
}

lastPart := parts[len(parts)-1]
if strings.Contains(lastPart, ":") {
portParts := strings.Split(lastPart, ":")
if len(portParts) == 2 {
return ":" + portParts[1]
}
}

return ":443"
}

// promptForParameter prompts the user to enter a value for the given parameter
func promptForParameter(paramName string) (string, error) {
prompt := fmt.Sprintf("Please enter value for '%s'", paramName)
Expand Down Expand Up @@ -431,7 +450,7 @@ func loadConfig() (*Config, error) {
envConfig := &Environment{
Endpoint: mainV.GetString(fmt.Sprintf("environments.%s.endpoint", currentEnv)),
Proxy: mainV.GetString(fmt.Sprintf("environments.%s.proxy", currentEnv)),
URL: mainV.GetString(fmt.Sprintf("environments.%s.url", currentEnv)),
Token: mainV.GetString(fmt.Sprintf("environments.%s.token", currentEnv)),
}

// Handle token based on environment type
Expand Down Expand Up @@ -510,12 +529,16 @@ func fetchJSONResponse(config *Config, serviceName string, verb string, resource
}

domainParts := strings.Split(urlParts[1], ".")
if len(domainParts) < 4 {
return nil, fmt.Errorf("invalid domain format in API endpoint: %s", apiEndpoint)
}
if len(domainParts) > 0 {
port := extractPortFromParts(domainParts)
if strings.Contains(domainParts[len(domainParts)-1], ":") {
parts := strings.Split(domainParts[len(domainParts)-1], ":")
domainParts[len(domainParts)-1] = parts[0]
}

domainParts[0] = format.ConvertServiceName(serviceName)
hostPort = strings.Join(domainParts, ".") + ":443"
domainParts[0] = format.ConvertServiceName(serviceName)
hostPort = strings.Join(domainParts, ".") + port
}
}
} else {
trimmedEndpoint := strings.TrimPrefix(identityEndpoint, "grpc+ssl://")
Expand Down Expand Up @@ -985,9 +1008,14 @@ func getMinimalFields(serviceName, resourceName string, refClient *grpcreflect.C

func printTable(data map[string]interface{}, options *FetchOptions, serviceName, verbName, resourceName string, refClient *grpcreflect.Client) string {
if results, ok := data["results"].([]interface{}); ok {
// Set default page size if not specified
if options.PageSize == 0 {
options.PageSize = 10
// Set default page size if not specified and paging is enabled
if !options.NoPaging {
if options.PageSize == 0 {
options.PageSize = 15
}
} else {
// Show all results when no-paging is true
options.PageSize = len(results)
}

// Initialize keyboard
Expand Down
Loading