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

PR - loxilb-io/loxilb#877 support for egress config #34

Merged
merged 1 commit into from
Dec 22, 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
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