Skip to content

Commit

Permalink
ensure proper region in lb create
Browse files Browse the repository at this point in the history
  • Loading branch information
uzaxirr committed Nov 22, 2024
1 parent 26c787b commit 4347614
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 deletions.
13 changes: 11 additions & 2 deletions cmd/loadbalancer/loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ var LoadBalancerCmd = &cobra.Command{
}

func init() {
lbBackendExample := `Define backend configurations for the load balancer.
Use this format:
--backend "ip=10.0.0.1|protocol=http|source-port=80|target-port=8080|health-check-port=8080"
Each field is separated by '|'`

lbInstancePoolExample := `Define instance pool configurations for the load balancer.
Use this format:
--instance-pool "tags=web,db|names=frontend,backend|protocol=http|source-port=80|target-port=8080|health-check.port=8080|health-check.path=/health"
Each field is separated by '|'`

LoadBalancerCmd.AddCommand(loadBalancerListCmd)
LoadBalancerCmd.AddCommand(loadBalancerShowCmd)
Expand All @@ -38,8 +47,8 @@ func init() {
loadBalancerCreateCmd.Flags().IntVarP(&lbSessionAffinityConfigTimeout, "session-affinity-config-timeout", "t", 0, "optional, Specify the session affinity config timeout for the load balancer")
loadBalancerCreateCmd.Flags().StringVarP(&lbExistingFirewall, "existing-firewall", "v", "", "optional, ID of existing firewall to use")
loadBalancerCreateCmd.Flags().StringVarP(&lbCreateFirewall, "create-firewall", "c", "", "optional, semicolon-separated list of ports to open - leave blank for default (80;443) or you can use \"all\"")
loadBalancerCreateCmd.Flags().StringArrayVar(&lbBackends, "backend", []string{}, "Define backend configuration (e.g., 'ip=10.0.0.1;source-port=80;target-port=8080;protocol=http;health-check-port=8080')")
loadBalancerCreateCmd.Flags().StringSliceVar(&lbInstancePools, "instance-pool", []string{}, "Instance pool configurations for the load balancer")
loadBalancerCreateCmd.Flags().StringArrayVar(&lbBackends, "backend", []string{}, lbBackendExample)
loadBalancerCreateCmd.Flags().StringSliceVar(&lbInstancePools, "instance-pool", []string{}, lbInstancePoolExample)

// Balancer update subcommand
loadBalancerUpdateCmd.Flags().StringVarP(&lbNameUpdate, "name", "", "", "New name of the load balancer to be update")
Expand Down
56 changes: 44 additions & 12 deletions cmd/loadbalancer/loadbalancer_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,15 @@ Example with instance pools:
check, region, err := utility.CheckAvailability("iaas", common.RegionSet)
handleAvailabilityCheck(check, region, err)

client := getCivoClient()
configLoadBalancer := &civogo.LoadBalancerConfig{}
client, err := config.CivoAPIClient()
if common.RegionSet != "" {
client.Region = common.RegionSet
}
if err != nil {
utility.Error("Creating the connection to Civo's API failed with %s", err)
os.Exit(1)
}
configLoadBalancer := &civogo.LoadBalancerConfig{Region: client.Region}

setLoadBalancerName(configLoadBalancer, args)
setLoadBalancerNetwork(client, configLoadBalancer)
Expand Down Expand Up @@ -199,8 +206,8 @@ func setLoadBalancerBackends(configLoadBalancer *civogo.LoadBalancerConfig) erro
var configLoadBalancerBackend []civogo.LoadBalancerBackendConfig

for _, backend := range lbBackends {
// Replace semicolons with colons to match expected format
backend = strings.ReplaceAll(backend, ";", ":")
// Replace pipes with commas to match expected format
backend = strings.ReplaceAll(backend, "|", ",")

// Parse backend string into a key-value map
data, err := parseBackendString(backend)
Expand Down Expand Up @@ -254,16 +261,12 @@ func setLoadBalancerInstancePools(configLoadBalancer *civogo.LoadBalancerConfig)
var configLoadBalancerInstancePools []civogo.LoadBalancerInstancePoolConfig

for _, pool := range lbInstancePools {
// Replace semicolons with colons for consistency with GetStringMap's expected format
pool = strings.ReplaceAll(pool, ";", ":")

// Ensure that pool is non-empty
if pool == "" {
return fmt.Errorf("instance pool configuration cannot be empty")
// Parse the pool string using parseInstancePool
data, err := parseInstancePool(pool)
if err != nil {
return fmt.Errorf("failed to parse instance pool: %v\nInput was: %q", err, pool)
}

data, _ := SetStringMap(pool)

instancePoolConfig := civogo.LoadBalancerInstancePoolConfig{}

// Parse tags
Expand Down Expand Up @@ -312,9 +315,11 @@ func setLoadBalancerInstancePools(configLoadBalancer *civogo.LoadBalancerConfig)
instancePoolConfig.HealthCheck.Path = healthCheckPath
}

// Append the parsed configuration
configLoadBalancerInstancePools = append(configLoadBalancerInstancePools, instancePoolConfig)
}

// Assign the parsed instance pools to the load balancer configuration
configLoadBalancer.InstancePools = configLoadBalancerInstancePools
return nil
}
Expand Down Expand Up @@ -369,6 +374,33 @@ func parseBackendString(backend string) (map[string]string, error) {
return data, nil
}

func parseInstancePool(input string) (map[string]string, error) {
// Split the input by "|"
entries := strings.Split(input, "|")
result := make(map[string]string)

for _, entry := range entries {
// Split each entry into key and value by the first "="
parts := strings.SplitN(entry, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid field format: %s", entry)
}

key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])

// Ensure key and value are non-empty
if key == "" || value == "" {
return nil, fmt.Errorf("key or value missing in field: %s", entry)
}

// Assign to result map
result[key] = value
}

return result, nil
}

func getIntField(data map[string]string, key string) (int, error) {
value, exists := data[key]
if !exists {
Expand Down
4 changes: 2 additions & 2 deletions cmd/loadbalancer/loadbalancer_show.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ If you wish to use a custom format, the available fields are:
if len(lb.Backends) > 0 {
fmt.Println("\nBackends:")
for _, backend := range lb.Backends {
fmt.Printf("- IP: %s, Protocol: %s, Source Port: %d, Target Port: %d\n",
backend.IP, backend.Protocol, backend.SourcePort, backend.TargetPort)
fmt.Printf("- IP: %s, Protocol: %s, Source Port: %d, Target Port: %d, Health Check Port: %d\n",
backend.IP, backend.Protocol, backend.SourcePort, backend.TargetPort, backend.HealthCheckPort)
}
} else {
fmt.Println("\nNo Backends Configured")
Expand Down

0 comments on commit 4347614

Please sign in to comment.