Skip to content

Commit

Permalink
loxilb-io/loxilb#877 support for egress config
Browse files Browse the repository at this point in the history
  • Loading branch information
TrekkieCoder committed Dec 21, 2024
1 parent 45aeab7 commit 8a7ae83
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 29 deletions.
6 changes: 5 additions & 1 deletion cmd/create/create_firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ type CreateFirewallOptions struct {
Drop bool
Trap bool
Record bool
Egress bool
Mark uint32
}

func NewCreateFirewallCmd(restOptions *api.RESTOptions) *cobra.Command {
o := CreateFirewallOptions{}

var createFirewallCmd = &cobra.Command{
Use: "firewall --firewallRule=<ruleKey>:<ruleValue>, [--allow] [--drop] [--trap] [--record] [--redirect=<PortName>] [--setmark=<FwMark>]",
Use: "firewall --firewallRule=<ruleKey>:<ruleValue>, [--allow] [--drop] [--trap] [--record] [--egress] [--redirect=<PortName>] [--setmark=<FwMark>]",
Short: "Create a Firewall",
Long: `Create a Firewall using LoxiLB
Expand All @@ -68,6 +69,7 @@ ex) loxicmd create firewall --firewallRule="sourceIP:1.2.3.2/32,destinationIP:2.
loxicmd create firewall --firewallRule="sourceIP:1.2.3.2/32,destinationIP:2.3.1.2/32,preference:200" --redirect=hs1
loxicmd create firewall --firewallRule="sourceIP:1.2.3.2/32,destinationIP:2.3.1.2/32,preference:200" --snat=10.10.10.1,3030
loxicmd create firewall --firewallRule="sourceIP:1.2.3.2/32,destinationIP:2.3.1.2/32,preference:200" --snat=10.10.10.1 (Do not change sourceport)
loxicmd create firewall --firewallRule="sourceIP:1.2.3.2/32,destinationIP:2.3.1.2/32,preference:200" --snat=10.10.10.1,3030 --egress (Egress rules match for non-k8s traffic)
`,
Aliases: []string{"Firewall", "fw", "firewalls"},
PreRun: func(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -112,6 +114,7 @@ ex) loxicmd create firewall --firewallRule="sourceIP:1.2.3.2/32,destinationIP:2.
createFirewallCmd.Flags().BoolVarP(&o.Trap, "trap", "", false, " Trap anything matching rule")
createFirewallCmd.Flags().Uint32VarP(&o.Mark, "setmark", "", 0, " Add a fw mark")
createFirewallCmd.Flags().StringSliceVar(&o.SnatArgs, "snat", o.SnatArgs, "SNAT any matching rule")
createFirewallCmd.Flags().BoolVarP(&o.Egress, "egress", "", false, "Specify that this an egress rule (to be used with snat)")
createFirewallCmd.MarkFlagRequired("firewallRule")
return createFirewallCmd
}
Expand Down Expand Up @@ -195,6 +198,7 @@ func GetFWOptionPairList(FirewallMods *api.FwRuleMod, o CreateFirewallOptions) e
} else {
FirewallMods.Opts.ToPort = 0
}
FirewallMods.Opts.OnDefault = o.Egress
}
FirewallMods.Opts.Record = o.Record
FirewallMods.Opts.Mark = uint32(o.Mark)
Expand Down
80 changes: 57 additions & 23 deletions cmd/create/create_loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type CreateLoadBalancerOptions struct {
Host string
AllowedSources []string
PPv2En bool
Egress bool
}

type CreateLoadBalancerResult struct {
Expand Down Expand Up @@ -140,7 +141,7 @@ func NewCreateLoadBalancerCmd(restOptions *api.RESTOptions) *cobra.Command {
o := CreateLoadBalancerOptions{}

var createLbCmd = &cobra.Command{
Use: "lb IP [--select=<rr|hash|priority|persist>] [--tcp=<port>:<targetPort>] [--udp=<port>:<targetPort>] [--sctp=<port>:<targetPort>] [--icmp] [--mark=<val>] [--secips=<ip>,] [--sources=<ip>,] [--endpoints=<ip>:<weight>,] [--mode=<onearm|fullnat>] [--bgp] [--monitor] [--inatimeout=<to>] [--name=<service-name>] [--attachEP] [--detachEP] [--security=<https|e2ehttps|none>] [--host=<url>] [--ppv2en]",
Use: "lb IP [--select=<rr|hash|priority|persist>] [--tcp=<port>:<targetPort>] [--udp=<port>:<targetPort>] [--sctp=<port>:<targetPort>] [--icmp] [--mark=<val>] [--secips=<ip>,] [--sources=<ip>,] [--endpoints=<ip>:<weight>,] [--mode=<onearm|fullnat>] [--bgp] [--monitor] [--inatimeout=<to>] [--name=<service-name>] [--attachEP] [--detachEP] [--security=<https|e2ehttps|none>] [--host=<url>] [--ppv2en] [--egress]",
Short: "Create a LoadBalancer",
Long: `Create a LoadBalancer
Expand All @@ -158,9 +159,10 @@ func NewCreateLoadBalancerCmd(restOptions *api.RESTOptions) *cobra.Command {
hostonearm - LB operating in host one-arm
ex) loxicmd create lb 192.168.0.200 --tcp=80:32015 --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1
loxicmd create lb 192.168.0.200 --tcp=80:32015 --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1 --security=https
loxicmd create lb 192.168.0.200 --tcp=5000:5201-5300 --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1
loxicmd create lb 192.168.0.200 --tcp=80:32015 --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1 --security=https
loxicmd create lb 192.168.0.200 --tcp=80:32015 --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1 --host=loxilb.io
loxicmd create lb 192.168.0.200 --tcp=80:32015 --name="http-service" --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1
loxicmd create lb 192.168.0.200 --tcp=80:32015 --name="http-service" --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1
loxicmd create lb 192.168.0.200 --udp=80:32015 --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1 --mark=10
loxicmd create lb 192.168.0.200 --tcp=80:32015 --udp=80:32015 --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1
loxicmd create lb 192.168.0.200 --select=hash --tcp=80:32015 --endpoints=10.212.0.1:1,10.212.0.2:1,10.212.0.3:1
Expand Down Expand Up @@ -215,12 +217,17 @@ ex) loxicmd create lb 192.168.0.200 --tcp=80:32015 --endpoints=10.212.0.1:1,10.2
return
}
for proto, portPairList := range ProtoPortpair {
portPair, err := GetPortPairList(portPairList)
portTargetPorts, err := GetPortPairList(portPairList)
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
for port, targetPort := range portPair {
if len(portTargetPorts) <= 0 {
fmt.Printf("portPair: None specified\n")
return
}

for port := range portTargetPorts {
lbModel := api.LoadBalancerModel{}
oper := 0
if o.Attach {
Expand All @@ -243,21 +250,24 @@ ex) loxicmd create lb 192.168.0.200 --tcp=80:32015 --endpoints=10.212.0.1:1,10.2
Security: api.LbSec(SecStringToNum(o.Security)),
Host: o.Host,
PpV2: o.PPv2En,
}

if o.Mode == "dsr" && targetPort != port {
fmt.Printf("Error: No port-translation in dsr mode\n")
return
Egress: o.Egress,
}

lbModel.Service = lbService
for endpoint, weight := range endpointPair {
ep := api.LoadBalancerEndpoint{
EndpointIP: endpoint,
TargetPort: targetPort,
Weight: weight,
targetPorts := portTargetPorts[port]
for _, targetPort := range targetPorts {
if o.Mode == "dsr" && targetPort != port {
fmt.Printf("Error: No port-translation in dsr mode\n")
return
}
ep := api.LoadBalancerEndpoint{
EndpointIP: endpoint,
TargetPort: targetPort,
Weight: weight,
}
lbModel.Endpoints = append(lbModel.Endpoints, ep)
}
lbModel.Endpoints = append(lbModel.Endpoints, ep)
}

for _, sip := range o.SecIPs {
Expand Down Expand Up @@ -289,7 +299,6 @@ ex) loxicmd create lb 192.168.0.200 --tcp=80:32015 --endpoints=10.212.0.1:1,10.2
}
}
}

},
}

Expand All @@ -312,6 +321,7 @@ ex) loxicmd create lb 192.168.0.200 --tcp=80:32015 --endpoints=10.212.0.1:1,10.2
createLbCmd.Flags().StringVarP(&o.Host, "host", "", o.Host, "Ingress Host URL Path")
createLbCmd.Flags().StringSliceVar(&o.AllowedSources, "sources", o.AllowedSources, "Allowed sources for this rule as '<allowedSources>'")
createLbCmd.Flags().BoolVarP(&o.PPv2En, "ppv2en", "", false, "Enable proxy procotol v2")
createLbCmd.Flags().BoolVarP(&o.Egress, "egress", "", false, "Specify egress rule")

return createLbCmd
}
Expand Down Expand Up @@ -340,8 +350,8 @@ func PrintCreateResult(resp *http.Response, o api.RESTOptions) {
fmt.Printf("%s\n", result.Result)
}

func GetPortPairList(portPairStrList []string) (map[uint16]uint16, error) {
result := make(map[uint16]uint16)
func GetPortPairList(portPairStrList []string) (map[uint16][]uint16, error) {
result := make(map[uint16][]uint16)
for _, portPairStr := range portPairStrList {
portPair := strings.Split(portPairStr, ":")
if len(portPair) != 2 {
Expand All @@ -353,14 +363,38 @@ func GetPortPairList(portPairStrList []string) (map[uint16]uint16, error) {
return nil, fmt.Errorf("port '%s' is not integer", portPair[0])
}

targetPort, err := strconv.Atoi(portPair[1])
if err != nil {
return nil, fmt.Errorf("targetPort '%s' is not integer", portPair[1])
startTP := 0
endTP := 0

targetPortRange := strings.Split(portPair[1], "-")
if len(targetPortRange) > 2 {
continue
} else if len(targetPortRange) == 2 {
startTP, err = strconv.Atoi(targetPortRange[0])
if err != nil {
return nil, fmt.Errorf("targetPort0 '%s' is not integer", targetPortRange[0])
}
endTP, err = strconv.Atoi(targetPortRange[1])
if err != nil {
return nil, fmt.Errorf("targetPort1 '%s' is not integer", targetPortRange[1])
}
if endTP < startTP {
return nil, fmt.Errorf("targetPort2 '%s' < targetPort2 '%s'", targetPortRange[1], targetPortRange[0])
}
} else {
startTP, err = strconv.Atoi(targetPortRange[0])
if err != nil {
return nil, fmt.Errorf("targetPort0 '%s' is not integer", targetPortRange[0])
}
endTP = startTP
}

result[uint16(port)] = uint16(targetPort)
}
result[uint16(port)] = make([]uint16, 0)

for targetPort := startTP; targetPort <= endTP; targetPort++ {
result[uint16(port)] = append(result[uint16(port)], uint16(targetPort))
}
}
return result, nil
}

Expand Down
5 changes: 4 additions & 1 deletion cmd/get/get_firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,14 @@ func MakeFirewallOptionToString(t api.FwOptArg) (ret string) {
ret = fmt.Sprintf("Snat(%s:%d)", t.ToIP, t.ToPort)
}
if t.Record {
ret += fmt.Sprintf(",Record")
ret += ",Record"
}
if t.Mark != 0 {
ret += fmt.Sprintf(",FwMark(%v)", t.Mark)
}
if t.OnDefault {
ret += ",Egr"
}
return ret
}

Expand Down
11 changes: 7 additions & 4 deletions cmd/get/get_loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func NumToSecurty(sec int) string {
return ret
}

func NumToMode(mode int, ppv2 bool) string {
func NumToMode(mode int, ppv2 bool, egress bool) string {
var ret string
switch mode {
case 1:
Expand All @@ -120,6 +120,9 @@ func NumToMode(mode int, ppv2 bool) string {
if ppv2 {
ret += ":ppv2"
}
if egress {
ret += ":egress"
}
return ret
}

Expand Down Expand Up @@ -191,7 +194,7 @@ func PrintGetLbResult(resp *http.Response, o api.RESTOptions) {
for i, eps := range lbrule.Endpoints {
if i == 0 {

data = append(data, []string{lbrule.Service.ExternalIP, secIPs, sources, lbrule.Service.Host, fmt.Sprintf("%d", lbrule.Service.Port), protocolStr, lbrule.Service.Name, fmt.Sprintf("%d", lbrule.Service.Block), NumToSelect(int(lbrule.Service.Sel)), NumToMode(int(lbrule.Service.Mode), lbrule.Service.PpV2),
data = append(data, []string{lbrule.Service.ExternalIP, secIPs, sources, lbrule.Service.Host, fmt.Sprintf("%d", lbrule.Service.Port), protocolStr, lbrule.Service.Name, fmt.Sprintf("%d", lbrule.Service.Block), NumToSelect(int(lbrule.Service.Sel)), NumToMode(int(lbrule.Service.Mode), lbrule.Service.PpV2, lbrule.Service.Egress),
eps.EndpointIP, fmt.Sprintf("%d", eps.TargetPort), fmt.Sprintf("%d", eps.Weight), eps.State, eps.Counter})
} else {
data = append(data, []string{"", "", "", "", "", "", "", "", "", "", eps.EndpointIP, fmt.Sprintf("%d", eps.TargetPort), fmt.Sprintf("%d", eps.Weight), eps.State, eps.Counter})
Expand All @@ -200,7 +203,7 @@ func PrintGetLbResult(resp *http.Response, o api.RESTOptions) {
} else {
for i, eps := range lbrule.Endpoints {
if i == 0 {
data = append(data, []string{lbrule.Service.ExternalIP, secIPs, sources, lbrule.Service.Host, fmt.Sprintf("%d", lbrule.Service.Port), protocolStr, lbrule.Service.Name, fmt.Sprintf("%d", lbrule.Service.Block), NumToSelect(int(lbrule.Service.Sel)), NumToMode(int(lbrule.Service.Mode), lbrule.Service.PpV2),
data = append(data, []string{lbrule.Service.ExternalIP, secIPs, sources, lbrule.Service.Host, fmt.Sprintf("%d", lbrule.Service.Port), protocolStr, lbrule.Service.Name, fmt.Sprintf("%d", lbrule.Service.Block), NumToSelect(int(lbrule.Service.Sel)), NumToMode(int(lbrule.Service.Mode), lbrule.Service.PpV2, lbrule.Service.Egress),
eps.EndpointIP, fmt.Sprintf("%d", eps.TargetPort), fmt.Sprintf("%d", eps.Weight), "-", eps.Counter})
} else {
data = append(data, []string{"", "", "", "", "", "", "", "", "", "", eps.EndpointIP, fmt.Sprintf("%d", eps.TargetPort), fmt.Sprintf("%d", eps.Weight), "-", eps.Counter})
Expand All @@ -209,7 +212,7 @@ func PrintGetLbResult(resp *http.Response, o api.RESTOptions) {
}
} else {
table.SetHeader(LOADBALANCER_TITLE)
data = append(data, []string{lbrule.Service.ExternalIP, fmt.Sprintf("%d", lbrule.Service.Port), protocolStr, lbrule.Service.Name, fmt.Sprintf("%d", lbrule.Service.Block), NumToSelect(int(lbrule.Service.Sel)), NumToMode(int(lbrule.Service.Mode), lbrule.Service.PpV2), fmt.Sprintf("%d", len(lbrule.Endpoints)), BoolToMon(lbrule.Service.Monitor)})
data = append(data, []string{lbrule.Service.ExternalIP, fmt.Sprintf("%d", lbrule.Service.Port), protocolStr, lbrule.Service.Name, fmt.Sprintf("%d", lbrule.Service.Block), NumToSelect(int(lbrule.Service.Sel)), NumToMode(int(lbrule.Service.Mode), lbrule.Service.PpV2, lbrule.Service.Egress), fmt.Sprintf("%d", len(lbrule.Endpoints)), BoolToMon(lbrule.Service.Monitor)})
}
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/api/firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type FwOptArg struct {
DoSnat bool `json:"doSnat"`
ToIP string `json:"toIP"`
ToPort uint16 `json:"toPort"`
// OnDefault - Trigger only on default cases
OnDefault bool `json:"onDefault"`
// Counter - Traffic counter
Counter string `json:"counter"`
}
Expand Down
1 change: 1 addition & 0 deletions pkg/api/loadBalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type LoadBalancerService struct {
Security LbSec `json:"security,omitempty" yaml:"security"`
Host string `json:"host,omitempty" yaml:"path"`
PpV2 bool `json:"proxyprotocolv2" yaml:"proxyprotocolv2"`
Egress bool `json:"egress" yaml:"egress"`
}

type LoadBalancerEndpoint struct {
Expand Down

0 comments on commit 8a7ae83

Please sign in to comment.