Skip to content

Commit

Permalink
Merge pull request #80 from yjinjo/master
Browse files Browse the repository at this point in the history
Add local environment
  • Loading branch information
yjinjo authored Dec 10, 2024
2 parents 2495ec1 + dbfb96d commit bcc571c
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 149 deletions.
98 changes: 55 additions & 43 deletions cmd/common/fetchService.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,22 +163,25 @@ func FetchService(serviceName string, verb string, resourceName string, options
hostPort := fmt.Sprintf("%s.api.%s.spaceone.dev:443", serviceName, envPrefix)

// Configure gRPC connection
tlsConfig := &tls.Config{
InsecureSkipVerify: false,
}
creds := credentials.NewTLS(tlsConfig)
opts := []grpc.DialOption{
grpc.WithTransportCredentials(creds),
grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(10*1024*1024), // 10MB
grpc.MaxCallSendMsgSize(10*1024*1024), // 10MB
),
}

// Establish the connection
conn, err := grpc.Dial(hostPort, opts...)
if err != nil {
return nil, fmt.Errorf("connection failed: unable to connect to %s: %v", hostPort, err)
var conn *grpc.ClientConn
if strings.HasPrefix(config.Environment, "local-") {
// For local environment, use insecure connection
conn, err = grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
pterm.Error.Printf("Cannot connect to local gRPC server (localhost:50051)\n")
pterm.Info.Println("Please check if your gRPC server is running")
return nil, fmt.Errorf("failed to connect to local server: %v", err)
}
} else {
// Existing SSL connection logic for non-local environments
tlsConfig := &tls.Config{
InsecureSkipVerify: false,
}
creds := credentials.NewTLS(tlsConfig)
conn, err = grpc.Dial(hostPort, grpc.WithTransportCredentials(creds))
if err != nil {
return nil, fmt.Errorf("connection failed: %v", err)
}
}
defer conn.Close()

Expand Down Expand Up @@ -271,7 +274,7 @@ func FetchService(serviceName string, verb string, resourceName string, options
if results, ok := respMap["results"].([]interface{}); ok {
columns := strings.Split(options.Columns, ",")
filteredResults := make([]interface{}, len(results))

for i, result := range results {
if resultMap, ok := result.(map[string]interface{}); ok {
filteredMap := make(map[string]interface{})
Expand Down Expand Up @@ -353,7 +356,7 @@ func FetchService(serviceName string, verb string, resourceName string, options
if results, ok := respMap["results"].([]interface{}); ok {
columns := strings.Split(options.Columns, ",")
filteredResults := make([]interface{}, len(results))

for i, result := range results {
if resultMap, ok := result.(map[string]interface{}); ok {
filteredMap := make(map[string]interface{})
Expand Down Expand Up @@ -449,32 +452,42 @@ func loadConfig() (*Config, error) {
}

func fetchJSONResponse(config *Config, serviceName string, verb string, resourceName string, options *FetchOptions) ([]byte, error) {
var envPrefix string
if strings.HasPrefix(config.Environment, "dev-") {
envPrefix = "dev"
} else if strings.HasPrefix(config.Environment, "stg-") {
envPrefix = "stg"
}
hostPort := fmt.Sprintf("%s.api.%s.spaceone.dev:443", serviceName, envPrefix)

// Configure gRPC connection
var opts []grpc.DialOption
tlsConfig := &tls.Config{
InsecureSkipVerify: false,
var conn *grpc.ClientConn
var err error

if strings.HasPrefix(config.Environment, "local-") {
conn, err = grpc.Dial("localhost:50051", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(10*1024*1024),
grpc.MaxCallSendMsgSize(10*1024*1024),
))
if err != nil {
return nil, fmt.Errorf("connection failed: unable to connect to local server: %v", err)
}
} else {
var envPrefix string
if strings.HasPrefix(config.Environment, "dev-") {
envPrefix = "dev"
} else if strings.HasPrefix(config.Environment, "stg-") {
envPrefix = "stg"
}
hostPort := fmt.Sprintf("%s.api.%s.spaceone.dev:443", serviceName, envPrefix)
tlsConfig := &tls.Config{
InsecureSkipVerify: false,
}
creds := credentials.NewTLS(tlsConfig)

conn, err = grpc.Dial(hostPort,
grpc.WithTransportCredentials(creds),
grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(10*1024*1024),
grpc.MaxCallSendMsgSize(10*1024*1024),
))
if err != nil {
return nil, fmt.Errorf("connection failed: unable to connect to %s: %v", hostPort, err)
}
}
creds := credentials.NewTLS(tlsConfig)
opts = append(opts, grpc.WithTransportCredentials(creds))

opts = append(opts, grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(10*1024*1024), // 10MB
grpc.MaxCallSendMsgSize(10*1024*1024), // 10MB
))

// Establish the connection
conn, err := grpc.Dial(hostPort, opts...)
if err != nil {
return nil, fmt.Errorf("connection failed: unable to connect to %s: %v", hostPort, err)
}
defer conn.Close()

ctx := metadata.AppendToOutgoingContext(context.Background(), "token", config.Environments[config.Environment].Token)
Expand Down Expand Up @@ -991,4 +1004,3 @@ func formatCSVValue(val interface{}) string {
return fmt.Sprintf("%v", v)
}
}

55 changes: 28 additions & 27 deletions cmd/common/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,39 +34,42 @@ func BuildVerbResourceMap(serviceName string) (map[string][]string, error) {
return nil, fmt.Errorf("failed to load config: %v", err)
}

var envPrefix string
if strings.HasPrefix(config.Environment, "dev-") {
envPrefix = "dev"
} else if strings.HasPrefix(config.Environment, "stg-") {
envPrefix = "stg"
var conn *grpc.ClientConn
var refClient *grpcreflect.Client

if strings.HasPrefix(config.Environment, "local-") {
conn, err = grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
return nil, fmt.Errorf("local connection failed: %v", err)
}
} else {
return nil, fmt.Errorf("unsupported environment prefix")
}
var envPrefix string
if strings.HasPrefix(config.Environment, "dev-") {
envPrefix = "dev"
} else if strings.HasPrefix(config.Environment, "stg-") {
envPrefix = "stg"
} else {
return nil, fmt.Errorf("unsupported environment prefix")
}

// Convert service name to endpoint format
endpointServiceName := convertServiceNameToEndpoint(serviceName)
hostPort := fmt.Sprintf("%s.api.%s.spaceone.dev:443", endpointServiceName, envPrefix)
endpointServiceName := convertServiceNameToEndpoint(serviceName)
hostPort := fmt.Sprintf("%s.api.%s.spaceone.dev:443", endpointServiceName, envPrefix)

// Configure gRPC connection
var opts []grpc.DialOption
tlsConfig := &tls.Config{
InsecureSkipVerify: false,
}
creds := credentials.NewTLS(tlsConfig)
opts = append(opts, grpc.WithTransportCredentials(creds))

// Establish the connection
conn, err := grpc.Dial(hostPort, opts...)
if err != nil {
return nil, fmt.Errorf("connection failed: unable to connect to %s: %v", hostPort, err)
tlsConfig := &tls.Config{
InsecureSkipVerify: false,
}
creds := credentials.NewTLS(tlsConfig)
conn, err = grpc.Dial(hostPort, grpc.WithTransportCredentials(creds))
if err != nil {
return nil, fmt.Errorf("connection failed: %v", err)
}
}
defer conn.Close()

ctx := metadata.AppendToOutgoingContext(context.Background(), "token", config.Environments[config.Environment].Token)
refClient := grpcreflect.NewClient(ctx, grpc_reflection_v1alpha.NewServerReflectionClient(conn))
refClient = grpcreflect.NewClient(ctx, grpc_reflection_v1alpha.NewServerReflectionClient(conn))
defer refClient.Reset()

// List all services
services, err := refClient.ListServices()
if err != nil {
return nil, fmt.Errorf("failed to list services: %v", err)
Expand All @@ -88,7 +91,6 @@ func BuildVerbResourceMap(serviceName string) (map[string][]string, error) {
continue
}

// Extract the resource name from the service name
parts := strings.Split(s, ".")
resourceName := parts[len(parts)-1]

Expand All @@ -101,10 +103,9 @@ func BuildVerbResourceMap(serviceName string) (map[string][]string, error) {
}
}

// Convert the map of resources to slices
result := make(map[string][]string)
for verb, resourcesSet := range verbResourceMap {
resources := []string{}
resources := make([]string, 0, len(resourcesSet))
for resource := range resourcesSet {
resources = append(resources, resource)
}
Expand Down
63 changes: 30 additions & 33 deletions cmd/other/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,15 @@ var settingInitLocalCmd = &cobra.Command{
Short: "Initialize configuration with a local environment",
Long: `Specify a local environment name to initialize the configuration.`,
Args: cobra.NoArgs,
Example: ` cfctl setting init local -n local-cloudone --app
or
cfctl setting init local -n local-cloudone --user`,
Example: ` cfctl setting init local -n [domain] --app --dev
or
cfctl setting init local -n [domain] --user --stg`,
Run: func(cmd *cobra.Command, args []string) {
localEnv, _ := cmd.Flags().GetString("name")
appFlag, _ := cmd.Flags().GetBool("app")
userFlag, _ := cmd.Flags().GetBool("user")
devFlag, _ := cmd.Flags().GetBool("dev")
stgFlag, _ := cmd.Flags().GetBool("stg")

if localEnv == "" {
pterm.Error.Println("The --name flag is required.")
Expand All @@ -139,6 +141,11 @@ var settingInitLocalCmd = &cobra.Command{
cmd.Help()
return
}
if !devFlag && !stgFlag {
pterm.Error.Println("You must specify either --dev or --stg flag.")
cmd.Help()
return
}

// Create setting directory if it doesn't exist
settingDir := GetSettingDir()
Expand All @@ -158,12 +165,23 @@ var settingInitLocalCmd = &cobra.Command{
}
}

envPrefix := ""
if devFlag {
envPrefix = "dev"
} else if stgFlag {
envPrefix = "stg"
}

var envName string
if appFlag {
envName = fmt.Sprintf("%s-app", localEnv)
envName = fmt.Sprintf("local-%s-%s-app", envPrefix, localEnv)
} else {
envName = fmt.Sprintf("local-%s-%s-user", envPrefix, localEnv)
}

if appFlag {
updateLocalSetting(envName, "app", mainSettingPath)
} else {
envName = fmt.Sprintf("%s-user", localEnv)
updateLocalSetting(envName, "user", filepath.Join(settingDir, "cache", "setting.toml"))
}

Expand Down Expand Up @@ -226,24 +244,16 @@ var envCmd = &cobra.Command{
// Set paths for app and user configurations
settingDir := GetSettingDir()
appSettingPath := filepath.Join(settingDir, "setting.toml")
userSettingPath := filepath.Join(settingDir, "cache", "setting.toml")

// Create separate Viper instances
appV := viper.New()
userV := viper.New()

// Load app configuration
if err := loadSetting(appV, appSettingPath); err != nil {
pterm.Error.Println(err)
return
}

// Load user configuration
if err := loadSetting(userV, userSettingPath); err != nil {
pterm.Error.Println(err)
return
}

// Get current environment (from app setting only)
currentEnv := getCurrentEnvironment(appV)

Expand All @@ -255,20 +265,17 @@ var envCmd = &cobra.Command{
if switchEnv != "" {
// Check environment in both app and user settings
appEnvMap := appV.GetStringMap("environments")
userEnvMap := userV.GetStringMap("environments")

if currentEnv == switchEnv {
pterm.Info.Printf("Already in '%s' environment.\n", currentEnv)
return
}

if _, existsApp := appEnvMap[switchEnv]; !existsApp {
if _, existsUser := userEnvMap[switchEnv]; !existsUser {
home, _ := os.UserHomeDir()
pterm.Error.Printf("Environment '%s' not found in %s/.cfctl/setting.toml",
switchEnv, home)
return
}
home, _ := os.UserHomeDir()
pterm.Error.Printf("Environment '%s' not found in %s/.cfctl/setting.toml",
switchEnv, home)
return
}

// Update only the environment field in app setting
Expand All @@ -290,14 +297,10 @@ var envCmd = &cobra.Command{
var targetViper *viper.Viper
var targetSettingPath string
envMapApp := appV.GetStringMap("environments")
envMapUser := userV.GetStringMap("environments")

if _, exists := envMapApp[removeEnv]; exists {
targetViper = appV
targetSettingPath = appSettingPath
} else if _, exists := envMapUser[removeEnv]; exists {
targetViper = userV
targetSettingPath = userSettingPath
} else {
home, _ := os.UserHomeDir()
pterm.Error.Printf("Environment '%s' not found in %s/.cfctl/setting.toml",
Expand Down Expand Up @@ -348,7 +351,6 @@ var envCmd = &cobra.Command{
if listOnly {
// Get environment maps from both app and user settings
appEnvMap := appV.GetStringMap("environments")
userEnvMap := userV.GetStringMap("environments")

// Map to store all unique environments
allEnvs := make(map[string]bool)
Expand All @@ -358,11 +360,6 @@ var envCmd = &cobra.Command{
allEnvs[envName] = true
}

// Add user environments
for envName := range userEnvMap {
allEnvs[envName] = true
}

if len(allEnvs) == 0 {
pterm.Println("No environments found in setting file")
return
Expand All @@ -377,8 +374,6 @@ var envCmd = &cobra.Command{
} else {
if _, isApp := appEnvMap[envName]; isApp {
pterm.Printf("%s\n", envName)
} else {
pterm.Printf("%s\n", envName)
}
}
}
Expand Down Expand Up @@ -874,7 +869,7 @@ func loadSetting(v *viper.Viper, settingPath string) error {
// Initialize with default values if file doesn't exist
defaultSettings := map[string]interface{}{
"environments": map[string]interface{}{},
"environment": "",
"environment": "",
}

// Convert to TOML
Expand Down Expand Up @@ -1118,6 +1113,8 @@ func init() {
settingInitLocalCmd.Flags().StringP("name", "n", "", "Local environment name for the environment")
settingInitLocalCmd.Flags().Bool("app", false, "Initialize as application configuration")
settingInitLocalCmd.Flags().Bool("user", false, "Initialize as user-specific configuration")
settingInitLocalCmd.Flags().Bool("dev", false, "Initialize as development environment")
settingInitLocalCmd.Flags().Bool("stg", false, "Initialize as staging environment")

envCmd.Flags().StringP("switch", "s", "", "Switch to a different environment")
envCmd.Flags().StringP("remove", "r", "", "Remove an environment")
Expand Down
Loading

0 comments on commit bcc571c

Please sign in to comment.