Skip to content
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

Add short_names.yml when init and sync api resources #13

Merged
merged 1 commit into from
Nov 6, 2024
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
105 changes: 34 additions & 71 deletions cmd/apiResources.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// apiResources.go

package cmd

import (
Expand All @@ -20,11 +22,12 @@ import (
"google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/descriptorpb"
"gopkg.in/yaml.v2"
)

var endpoints string

func fetchServiceResources(service, endpoint string) ([][]string, error) {
func fetchServiceResources(service, endpoint string, shortNamesMap map[string]string) ([][]string, error) {
// Configure gRPC connection based on TLS usage
parts := strings.Split(endpoint, "://")
if len(parts) != 2 {
Expand Down Expand Up @@ -79,7 +82,8 @@ func fetchServiceResources(service, endpoint string) ([][]string, error) {
}
resourceName := s.Name[strings.LastIndex(s.Name, ".")+1:]
verbs := getServiceMethods(client, s.Name)
data = append(data, []string{service, resourceName, "", strings.Join(verbs, ", ")})
shortName := shortNamesMap[fmt.Sprintf("%s.%s", service, resourceName)]
data = append(data, []string{service, resourceName, shortName, strings.Join(verbs, ", ")})
}

return data, nil
Expand Down Expand Up @@ -127,29 +131,6 @@ func getServiceMethods(client grpc_reflection_v1alpha.ServerReflectionClient, se
return methods
}

func splitIntoLinesWithComma(text string, maxWidth int) []string {
words := strings.Split(text, ", ")
var lines []string
var currentLine string

for _, word := range words {
if len(currentLine)+len(word)+2 > maxWidth { // +2 accounts for the ", " separator
lines = append(lines, currentLine+",")
currentLine = word
} else {
if currentLine != "" {
currentLine += ", "
}
currentLine += word
}
}
if currentLine != "" {
lines = append(lines, currentLine)
}

return lines
}

var apiResourcesCmd = &cobra.Command{
Use: "api-resources",
Short: "Displays supported API resources",
Expand All @@ -171,6 +152,22 @@ var apiResourcesCmd = &cobra.Command{

endpointsMap := viper.GetStringMapString("endpoints")

// Load short names configuration
shortNamesFile := filepath.Join(getConfigDirectory(), "short_names.yml")
shortNamesMap := make(map[string]string)
if _, err := os.Stat(shortNamesFile); err == nil {
file, err := os.Open(shortNamesFile)
if err != nil {
log.Fatalf("Failed to open short_names.yml file: %v", err)
}
defer file.Close()

err = yaml.NewDecoder(file).Decode(&shortNamesMap)
if err != nil {
log.Fatalf("Failed to decode short_names.yml: %v", err)
}
}

// Process endpoints provided via flag
if endpoints != "" {
selectedEndpoints := strings.Split(endpoints, ",")
Expand All @@ -187,7 +184,7 @@ var apiResourcesCmd = &cobra.Command{
continue
}

result, err := fetchServiceResources(endpointName, serviceEndpoint)
result, err := fetchServiceResources(endpointName, serviceEndpoint, shortNamesMap)
if err != nil {
log.Printf("Error processing service %s: %v", endpointName, err)
continue
Expand All @@ -213,7 +210,7 @@ var apiResourcesCmd = &cobra.Command{
wg.Add(1)
go func(service, endpoint string) {
defer wg.Done()
result, err := fetchServiceResources(service, endpoint)
result, err := fetchServiceResources(service, endpoint, shortNamesMap)
if err != nil {
errorChan <- fmt.Errorf("Error processing service %s: %v", service, err)
return
Expand Down Expand Up @@ -245,58 +242,24 @@ var apiResourcesCmd = &cobra.Command{
},
}

func renderTable(data [][]string) {
// Calculate the dynamic width for the "Verb" column
terminalWidth := pterm.GetTerminalWidth()
usedWidth := 30 + 20 + 15 // Estimated widths for Service, Resource, and Short Names
verbColumnWidth := terminalWidth - usedWidth
if verbColumnWidth < 20 {
verbColumnWidth = 20 // Minimum width for Verb column
}

// Use unique colors for each service and its associated data
serviceColors := []pterm.Color{
pterm.FgLightGreen, pterm.FgLightYellow, pterm.FgLightBlue,
pterm.FgLightMagenta, pterm.FgLightCyan, pterm.FgWhite,
func getConfigDirectory() string {
home, err := os.UserHomeDir()
if err != nil {
log.Fatalf("Unable to find home directory: %v", err)
}
return filepath.Join(home, ".spaceone")
}

serviceColorMap := make(map[string]pterm.Color)
colorIndex := 0

func renderTable(data [][]string) {
// Render the table using pterm
table := pterm.TableData{{"Service", "Resource", "Short Names", "Verb"}}

for _, row := range data {
service := row[0]
// Assign a unique color to each service if not already assigned
if _, exists := serviceColorMap[service]; !exists {
serviceColorMap[service] = serviceColors[colorIndex]
colorIndex = (colorIndex + 1) % len(serviceColors)
}

// Get the color for this service
color := serviceColorMap[service]
coloredStyle := pterm.NewStyle(color)

// Color the entire row (Service, Resource, Short Names, Verb)
serviceColored := coloredStyle.Sprint(service)
resourceColored := coloredStyle.Sprint(row[1])
shortNamesColored := coloredStyle.Sprint(row[2])

verbs := splitIntoLinesWithComma(row[3], verbColumnWidth)
for i, line := range verbs {
if i == 0 {
table = append(table, []string{serviceColored, resourceColored, shortNamesColored, coloredStyle.Sprint(line)})
} else {
table = append(table, []string{"", "", "", coloredStyle.Sprint(line)})
}
}
table = append(table, row)
}

// Render the table using pterm
pterm.DefaultTable.WithHasHeader().WithData(table).Render()
}

func init() {
rootCmd.AddCommand(apiResourcesCmd)
apiResourcesCmd.Flags().StringVarP(&endpoints, "endpoint", "e", "", "Specify the endpoints to connect to, separated by commas (e.g., 'identity,inventory')")
apiResourcesCmd.Flags().StringVarP(&endpoints, "service", "s", "", "Specify the services to connect to, separated by commas (e.g., 'identity', 'identity,inventory')")
}
22 changes: 18 additions & 4 deletions cmd/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
*/
// config.go

package cmd

Expand All @@ -27,7 +25,7 @@ var configCmd = &cobra.Command{
Use: "config",
Short: "Manage cfctl configuration files",
Long: `Manage configuration files for cfctl. You can initialize,
switch environments, and display the current configuration.`,
switch environments, and display the current configuration.`,
}

// initCmd initializes a new environment configuration
Expand Down Expand Up @@ -103,6 +101,22 @@ var initCmd = &cobra.Command{
log.Fatalf("Failed to update environment.yml file: %v", err)
}

// Create short_names.yml if it doesn't exist
shortNamesFile := filepath.Join(getConfigDir(), "short_names.yml")
if _, err := os.Stat(shortNamesFile); os.IsNotExist(err) {
file, err := os.Create(shortNamesFile)
if err != nil {
log.Fatalf("Failed to create short_names.yml file: %v", err)
}
defer file.Close()
yamlContent := "# Define your short names here\n# Example:\n# identity.User: 'iu'\n"
_, err = file.WriteString(yamlContent)
if err != nil {
log.Fatalf("Failed to write to short_names.yml file: %v", err)
}
pterm.Success.Println("short_names.yml file created successfully.")
}

// Update the global config file with the new environment command only if not overwriting
if !overwrite {
updateGlobalConfigWithEnvironment(environment)
Expand Down
Loading