From 33eb84610497a450ff6dcee484a9ef65863374e1 Mon Sep 17 00:00:00 2001 From: Youngjin Jo Date: Wed, 15 Jan 2025 10:04:28 +0900 Subject: [PATCH 1/5] chore: add current environment Signed-off-by: Youngjin Jo --- cmd/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index dbc9058..3858e08 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -270,7 +270,7 @@ func addDynamicServiceCommands() error { pterm.DefaultBox.WithTitle("Local gRPC Server Not Found"). WithTitleTopCenter(). WithBoxStyle(pterm.NewStyle(pterm.FgYellow)). - Printfln("Unable to connect to local gRPC server.\nPlease make sure your gRPC server is running on %s", config.Endpoint) + Printfln("Current environment: %s\nUnable to connect to local gRPC server.\nPlease make sure your gRPC server is running on %s", config.Environment, config.Endpoint) return nil } defer func(conn *grpc.ClientConn) { From b8efbb3936ba6761c0ae212124b8d86b4b6e49bd Mon Sep 17 00:00:00 2001 From: Youngjin Jo Date: Wed, 15 Jan 2025 10:09:00 +0900 Subject: [PATCH 2/5] chore: remove grpc:// for checking identity endpoint Signed-off-by: Youngjin Jo --- cmd/other/setting.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/other/setting.go b/cmd/other/setting.go index f38c16d..93b5c01 100644 --- a/cmd/other/setting.go +++ b/cmd/other/setting.go @@ -1372,7 +1372,7 @@ func updateSetting(envName, endpoint, envSuffix string) { v.Set(envKey, endpoint) proxyKey := fmt.Sprintf("environments.%s.proxy", envName) - if strings.HasPrefix(endpoint, "grpc://") || strings.HasPrefix(endpoint, "grpc+ssl://") { + if strings.HasPrefix(endpoint, "grpc+ssl://") { isProxy, err := transport.CheckIdentityProxyAvailable(endpoint) if err != nil { pterm.Warning.Printf("Failed to check gRPC endpoint: %v\n", err) From 70b5db50ed3ec20ae8b1fd85a76d387c431382b1 Mon Sep 17 00:00:00 2001 From: Youngjin Jo Date: Wed, 15 Jan 2025 10:17:55 +0900 Subject: [PATCH 3/5] refactor: get endpoint dynamically Signed-off-by: Youngjin Jo --- pkg/transport/service.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/transport/service.go b/pkg/transport/service.go index 41335ef..e90fde5 100644 --- a/pkg/transport/service.go +++ b/pkg/transport/service.go @@ -230,11 +230,12 @@ func FetchService(serviceName string, verb string, resourceName string, options // Configure gRPC connection var conn *grpc.ClientConn - if config.Environment == "local" { + if strings.HasPrefix(config.Environments[config.Environment].Endpoint, "grpc://") { + hostPort := strings.TrimPrefix(config.Environments[config.Environment].Endpoint, "grpc://") // For local environment, use insecure connection - conn, err = grpc.Dial("localhost:50051", grpc.WithInsecure()) + conn, err = grpc.Dial(hostPort, grpc.WithInsecure()) if err != nil { - pterm.Error.Printf("Cannot connect to local gRPC server (localhost:50051)\n") + pterm.Error.Printf("Cannot connect to local gRPC server (%s)\n", hostPort) pterm.Info.Println("Please check if your gRPC server is running") return nil, fmt.Errorf("failed to connect to local server: %v", err) } @@ -492,8 +493,9 @@ func fetchJSONResponse(config *Config, serviceName string, verb string, resource fmt.Sprintf("page_size=%d", options.PageSize)) } - if config.Environment == "local" { - conn, err = grpc.Dial("localhost:50051", grpc.WithInsecure(), + if strings.HasPrefix(config.Environments[config.Environment].Endpoint, "grpc://") { + hostPort = strings.TrimPrefix(config.Environments[config.Environment].Endpoint, "grpc://") + conn, err = grpc.Dial(hostPort, grpc.WithInsecure(), grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(10*1024*1024), grpc.MaxCallSendMsgSize(10*1024*1024), From a03b08a2448b8494e6661054df48d54b9bd52e3f Mon Sep 17 00:00:00 2001 From: Youngjin Jo Date: Wed, 15 Jan 2025 10:35:35 +0900 Subject: [PATCH 4/5] refactor: remove unnecessary functions Signed-off-by: Youngjin Jo --- pkg/configs/settings.go | 51 ++++------------------------------------- 1 file changed, 5 insertions(+), 46 deletions(-) diff --git a/pkg/configs/settings.go b/pkg/configs/settings.go index d17e15d..e6868b9 100644 --- a/pkg/configs/settings.go +++ b/pkg/configs/settings.go @@ -9,25 +9,17 @@ import ( "github.com/spf13/viper" ) -// Environment represents a single environment configuration -type Environment struct { - Endpoint string `yaml:"endpoint"` // gRPC or HTTP endpoint URL - Proxy string `yaml:"proxy"` // Proxy server address if required - Token string `yaml:"token"` // Authentication token - URL string `yaml:"url"` // Web console URL -} - // Setting represents the complete configuration structure type Setting struct { Environment string `yaml:"environment"` // Current active environment Environments map[string]Environment `yaml:"environments"` // Map of available environments } -// SettingPaths contains all setting related paths -type SettingPaths struct { - CacheDir string // ~/.cfctl/cache - SettingDir string // ~/.cfctl - SettingFile string // ~/.cfctl/setting.yaml +// Environment represents a single environment configuration +type Environment struct { + Endpoint string `yaml:"endpoint"` // gRPC or HTTP endpoint URL + Proxy string `yaml:"proxy"` // Proxy server address if required + Token string `yaml:"token"` // Authentication token } // LoadSetting loads the setting from the default location (~/.cfctl/setting.yaml) @@ -56,15 +48,6 @@ func LoadSetting() (*Setting, error) { }, nil } -// GetCachePath returns the path to environment-specific cache directory -func GetCachePath(env string) (string, error) { - paths, err := GetSettingPaths() - if err != nil { - return "", err - } - return filepath.Join(paths.CacheDir, env), nil -} - // GetSettingPath returns the path to the main setting file func GetSettingPath() (string, error) { home, err := os.UserHomeDir() @@ -74,29 +57,6 @@ func GetSettingPath() (string, error) { return filepath.Join(home, ".cfctl", "setting.yaml"), nil } -// GetSettingPaths returns all setting related paths -func GetSettingPaths() (*SettingPaths, error) { - home, err := os.UserHomeDir() - if err != nil { - return nil, fmt.Errorf("failed to get home directory: %v", err) - } - - return &SettingPaths{ - CacheDir: filepath.Join(home, ".cfctl", "cache"), - SettingDir: filepath.Join(home, ".cfctl"), - SettingFile: filepath.Join(home, ".cfctl", "setting.yaml"), - }, nil -} - -// GetTokenPath returns the path to environment-specific token file -func GetTokenPath(env string) (string, error) { - cachePath, err := GetCachePath(env) - if err != nil { - return "", err - } - return filepath.Join(cachePath, "access_token"), nil -} - // loadMainSetting loads the main setting file using viper func loadMainSetting(settingPath string) (*Setting, error) { v := viper.New() @@ -134,7 +94,6 @@ func loadEnvironmentSetting(env string) (*Environment, error) { envSetting := &Environment{ Endpoint: v.GetString(fmt.Sprintf("environments.%s.endpoint", env)), Proxy: v.GetString(fmt.Sprintf("environments.%s.proxy", env)), - URL: v.GetString(fmt.Sprintf("environments.%s.url", env)), } if err := loadToken(env, envSetting); err != nil { From f968a5d3f6d8ee6f1b16c65b0d56e08e64d74ca4 Mon Sep 17 00:00:00 2001 From: Youngjin Jo Date: Wed, 15 Jan 2025 12:38:59 +0900 Subject: [PATCH 5/5] refactor: set setting file to get environments Signed-off-by: Youngjin Jo --- cmd/common/api_resources.go | 4 +- cmd/root.go | 2 +- pkg/configs/endpoint.go | 2 +- pkg/configs/{settings.go => setting_file.go} | 86 ++++++++++---------- 4 files changed, 49 insertions(+), 45 deletions(-) rename pkg/configs/{settings.go => setting_file.go} (61%) diff --git a/cmd/common/api_resources.go b/cmd/common/api_resources.go index badc0bf..4692f25 100644 --- a/cmd/common/api_resources.go +++ b/cmd/common/api_resources.go @@ -35,7 +35,7 @@ func FetchApiResourcesCmd(serviceName string) *cobra.Command { } func ListAPIResources(serviceName string) error { - setting, err := configs.LoadSetting() + setting, err := configs.SetSettingFile() if err != nil { return fmt.Errorf("failed to load setting: %v", err) } @@ -87,7 +87,7 @@ func loadShortNames() (map[string]string, error) { return shortNamesMap, nil } -func FetchServiceResources(serviceName, endpoint string, shortNamesMap map[string]string, config *configs.Setting) ([][]string, error) { +func FetchServiceResources(serviceName, endpoint string, shortNamesMap map[string]string, config *configs.Environments) ([][]string, error) { parts := strings.Split(endpoint, "://") if len(parts) != 2 { return nil, fmt.Errorf("invalid endpoint format: %s", endpoint) diff --git a/cmd/root.go b/cmd/root.go index 3858e08..b9430b8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -376,7 +376,7 @@ func addDynamicServiceCommands() error { // If no cached endpoints, show progress with detailed messages progressbar, _ := pterm.DefaultProgressbar. WithTotal(4). - WithTitle(fmt.Sprintf("Setting up %s environment", config.Environment)). + WithTitle(fmt.Sprintf("Environments up %s environment", config.Environment)). Start() progressbar.UpdateTitle("Fetching available service endpoints from the API server") diff --git a/pkg/configs/endpoint.go b/pkg/configs/endpoint.go index dfdbd25..ae52e04 100644 --- a/pkg/configs/endpoint.go +++ b/pkg/configs/endpoint.go @@ -126,7 +126,7 @@ func GetIdentityEndpoint(apiEndpoint string) (string, bool, error) { return "", false, nil } -func GetServiceEndpoint(config *Setting, serviceName string) (string, error) { +func GetServiceEndpoint(config *Environments, serviceName string) (string, error) { envConfig := config.Environments[config.Environment] if envConfig.Endpoint == "" { return "", fmt.Errorf("endpoint not found in environment config") diff --git a/pkg/configs/settings.go b/pkg/configs/setting_file.go similarity index 61% rename from pkg/configs/settings.go rename to pkg/configs/setting_file.go index e6868b9..6c119be 100644 --- a/pkg/configs/settings.go +++ b/pkg/configs/setting_file.go @@ -9,8 +9,8 @@ import ( "github.com/spf13/viper" ) -// Setting represents the complete configuration structure -type Setting struct { +// Environments represents the complete configuration structure +type Environments struct { Environment string `yaml:"environment"` // Current active environment Environments map[string]Environment `yaml:"environments"` // Map of available environments } @@ -22,49 +22,46 @@ type Environment struct { Token string `yaml:"token"` // Authentication token } -// LoadSetting loads the setting from the default location (~/.cfctl/setting.yaml) -// and handles environment-specific token loading. -func LoadSetting() (*Setting, error) { - settingPath, err := GetSettingPath() +// SetSettingFile loads the setting from the default location (~/.cfctl/setting.yaml) +func SetSettingFile() (*Environments, error) { + settingPath, err := GetSettingFilePath() if err != nil { return nil, err } - setting, err := loadMainSetting(settingPath) + currentEnvName, err := getCurrentEnvName(settingPath) if err != nil { return nil, err } - envSetting, err := loadEnvironmentSetting(setting.Environment) + currentEnvValues, err := getCurrentEnvValues(currentEnvName.Environment) if err != nil { return nil, err } - return &Setting{ - Environment: setting.Environment, + return &Environments{ + Environment: currentEnvName.Environment, Environments: map[string]Environment{ - setting.Environment: *envSetting, + currentEnvName.Environment: *currentEnvValues, }, }, nil } -// GetSettingPath returns the path to the main setting file -func GetSettingPath() (string, error) { +// GetSettingFilePath returns the path to the setting file in the .cfctl directory +func GetSettingFilePath() (string, error) { home, err := os.UserHomeDir() if err != nil { return "", fmt.Errorf("failed to get home directory: %v", err) } + return filepath.Join(home, ".cfctl", "setting.yaml"), nil } -// loadMainSetting loads the main setting file using viper -func loadMainSetting(settingPath string) (*Setting, error) { - v := viper.New() - v.SetConfigFile(settingPath) - v.SetConfigType("yaml") - - if err := v.ReadInConfig(); err != nil { - return nil, fmt.Errorf("failed to read config file: %v", err) +// getCurrentEnvName loads the main setting file using viper +func getCurrentEnvName(settingPath string) (*Environments, error) { + v, err := setViperWithSetting(settingPath) + if err != nil { + return nil, err } currentEnv := v.GetString("environment") @@ -72,23 +69,19 @@ func loadMainSetting(settingPath string) (*Setting, error) { return nil, fmt.Errorf("no environment set in settings.yaml") } - return &Setting{Environment: currentEnv}, nil + return &Environments{Environment: currentEnv}, nil } -// loadEnvironmentSetting loads environment-specific setting -func loadEnvironmentSetting(env string) (*Environment, error) { - home, err := os.UserHomeDir() +// getCurrentEnvValues loads environment-specific setting +func getCurrentEnvValues(env string) (*Environment, error) { + settingPath, err := GetSettingFilePath() if err != nil { - return nil, fmt.Errorf("failed to get home directory: %v", err) + return nil, err } - v := viper.New() - settingPath := filepath.Join(home, ".cfctl", "setting.yaml") - v.SetConfigFile(settingPath) - v.SetConfigType("yaml") - - if err := v.ReadInConfig(); err != nil { - return nil, fmt.Errorf("failed to read settings.yaml: %v", err) + v, err := setViperWithSetting(settingPath) + if err != nil { + return nil, err } envSetting := &Environment{ @@ -108,6 +101,7 @@ func loadToken(env string, envSetting *Environment) error { if strings.HasSuffix(env, "-user") { return loadUserToken(env, envSetting) } + return loadAppToken(env, envSetting) } @@ -123,25 +117,35 @@ func loadUserToken(env string, envSetting *Environment) error { if err == nil { envSetting.Token = strings.TrimSpace(string(tokenBytes)) } + return nil } // loadAppToken loads token for app environments from main setting func loadAppToken(env string, envSetting *Environment) error { - v := viper.New() - home, err := os.UserHomeDir() + settingPath, err := GetSettingFilePath() if err != nil { - return fmt.Errorf("failed to get home directory: %v", err) + return err } - settingPath := filepath.Join(home, ".cfctl", "setting.yaml") + v, err := setViperWithSetting(settingPath) + if err != nil { + return err + } + + envSetting.Token = v.GetString(fmt.Sprintf("environments.%s.token", env)) + + return nil +} + +// setViperWithSetting creates a new viper instance with the given config file +func setViperWithSetting(settingPath string) (*viper.Viper, error) { + v := viper.New() v.SetConfigFile(settingPath) v.SetConfigType("yaml") - if err := v.ReadInConfig(); err != nil { - return fmt.Errorf("failed to read setting file: %v", err) + return nil, fmt.Errorf("failed to read config file: %v", err) } - envSetting.Token = v.GetString(fmt.Sprintf("environments.%s.token", env)) - return nil + return v, nil }