Cleanup of ipvs utils

pull/6/head
Rohit Ramkumar 2018-02-06 08:26:17 -08:00
parent ffda1e2200
commit daae0e6cec
2 changed files with 103 additions and 103 deletions

View File

@ -25,83 +25,86 @@ import (
"strings" "strings"
"syscall" "syscall"
"github.com/docker/libnetwork/ipvs" libipvs "github.com/docker/libnetwork/ipvs"
"github.com/golang/glog" "github.com/golang/glog"
utilexec "k8s.io/utils/exec" utilexec "k8s.io/utils/exec"
) )
// runner implements Interface. // runner implements ipvs.Interface.
type runner struct { type runner struct {
exec utilexec.Interface exec utilexec.Interface
ipvsHandle *ipvs.Handle ipvsHandle *libipvs.Handle
} }
// Protocol is the IPVS service protocol type
type Protocol uint16
// New returns a new Interface which will call ipvs APIs. // New returns a new Interface which will call ipvs APIs.
func New(exec utilexec.Interface) Interface { func New(exec utilexec.Interface) Interface {
ihandle, err := ipvs.New("") handle, err := libipvs.New("")
if err != nil { if err != nil {
glog.Errorf("IPVS interface can't be initialized, error: %v", err) glog.Errorf("IPVS interface can't be initialized, error: %v", err)
return nil return nil
} }
return &runner{ return &runner{
exec: exec, exec: exec,
ipvsHandle: ihandle, ipvsHandle: handle,
} }
} }
// AddVirtualServer is part of Interface. // AddVirtualServer is part of ipvs.Interface.
func (runner *runner) AddVirtualServer(vs *VirtualServer) error { func (runner *runner) AddVirtualServer(vs *VirtualServer) error {
eSvc, err := toBackendService(vs) svc, err := toIPVSService(vs)
if err != nil { if err != nil {
return err return err
} }
return runner.ipvsHandle.NewService(eSvc) return runner.ipvsHandle.NewService(svc)
} }
// UpdateVirtualServer is part of Interface. // UpdateVirtualServer is part of ipvs.Interface.
func (runner *runner) UpdateVirtualServer(vs *VirtualServer) error { func (runner *runner) UpdateVirtualServer(vs *VirtualServer) error {
bSvc, err := toBackendService(vs) svc, err := toIPVSService(vs)
if err != nil { if err != nil {
return err return err
} }
return runner.ipvsHandle.UpdateService(bSvc) return runner.ipvsHandle.UpdateService(svc)
} }
// DeleteVirtualServer is part of Interface. // DeleteVirtualServer is part of ipvs.Interface.
func (runner *runner) DeleteVirtualServer(vs *VirtualServer) error { func (runner *runner) DeleteVirtualServer(vs *VirtualServer) error {
bSvc, err := toBackendService(vs) svc, err := toIPVSService(vs)
if err != nil { if err != nil {
return err return err
} }
return runner.ipvsHandle.DelService(bSvc) return runner.ipvsHandle.DelService(svc)
} }
// GetVirtualServer is part of Interface. // GetVirtualServer is part of ipvs.Interface.
func (runner *runner) GetVirtualServer(vs *VirtualServer) (*VirtualServer, error) { func (runner *runner) GetVirtualServer(vs *VirtualServer) (*VirtualServer, error) {
bSvc, err := toBackendService(vs) svc, err := toIPVSService(vs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ipvsService, err := runner.ipvsHandle.GetService(bSvc) ipvsSvc, err := runner.ipvsHandle.GetService(svc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
virtualServer, err := toVirtualServer(ipvsService) vServ, err := toVirtualServer(ipvsSvc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return virtualServer, nil return vServ, nil
} }
// GetVirtualServers is part of Interface. // GetVirtualServers is part of ipvs.Interface.
func (runner *runner) GetVirtualServers() ([]*VirtualServer, error) { func (runner *runner) GetVirtualServers() ([]*VirtualServer, error) {
ipvsServices, err := runner.ipvsHandle.GetServices() ipvsSvcs, err := runner.ipvsHandle.GetServices()
if err != nil { if err != nil {
return nil, err return nil, err
} }
vss := make([]*VirtualServer, 0) vss := make([]*VirtualServer, 0)
for _, ipvsService := range ipvsServices { for _, ipvsSvc := range ipvsSvcs {
vs, err := toVirtualServer(ipvsService) vs, err := toVirtualServer(ipvsSvc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -110,61 +113,61 @@ func (runner *runner) GetVirtualServers() ([]*VirtualServer, error) {
return vss, nil return vss, nil
} }
// Flush is part of Interface. Currently we delete IPVS services one by one // Flush is part of ipvs.Interface. Currently we delete IPVS services one by one
func (runner *runner) Flush() error { func (runner *runner) Flush() error {
return runner.ipvsHandle.Flush() return runner.ipvsHandle.Flush()
} }
// AddRealServer is part of Interface. // AddRealServer is part of ipvs.Interface.
func (runner *runner) AddRealServer(vs *VirtualServer, rs *RealServer) error { func (runner *runner) AddRealServer(vs *VirtualServer, rs *RealServer) error {
bSvc, err := toBackendService(vs) svc, err := toIPVSService(vs)
if err != nil { if err != nil {
return err return err
} }
bDst, err := toBackendDestination(rs) dst, err := toIPVSDestination(rs)
if err != nil { if err != nil {
return err return err
} }
return runner.ipvsHandle.NewDestination(bSvc, bDst) return runner.ipvsHandle.NewDestination(svc, dst)
} }
// DeleteRealServer is part of Interface. // DeleteRealServer is part of ipvs.Interface.
func (runner *runner) DeleteRealServer(vs *VirtualServer, rs *RealServer) error { func (runner *runner) DeleteRealServer(vs *VirtualServer, rs *RealServer) error {
bSvc, err := toBackendService(vs) svc, err := toIPVSService(vs)
if err != nil { if err != nil {
return err return err
} }
bDst, err := toBackendDestination(rs) dst, err := toIPVSDestination(rs)
if err != nil { if err != nil {
return err return err
} }
return runner.ipvsHandle.DelDestination(bSvc, bDst) return runner.ipvsHandle.DelDestination(svc, dst)
} }
// GetRealServers is part of Interface. // GetRealServers is part of ipvs.Interface.
func (runner *runner) GetRealServers(vs *VirtualServer) ([]*RealServer, error) { func (runner *runner) GetRealServers(vs *VirtualServer) ([]*RealServer, error) {
bSvc, err := toBackendService(vs) svc, err := toIPVSService(vs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
bDestinations, err := runner.ipvsHandle.GetDestinations(bSvc) dsts, err := runner.ipvsHandle.GetDestinations(svc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
realServers := make([]*RealServer, 0) rss := make([]*RealServer, 0)
for _, dest := range bDestinations { for _, dst := range dsts {
dst, err := toRealServer(dest) dst, err := toRealServer(dst)
// TODO: aggregate errors? // TODO: aggregate errors?
if err != nil { if err != nil {
return nil, err return nil, err
} }
realServers = append(realServers, dst) rss = append(rss, dst)
} }
return realServers, nil return rss, nil
} }
// toVirtualServer converts an IPVS service representation to the equivalent virtual server structure. // toVirtualServer converts an IPVS Service to the equivalent VirtualServer structure.
func toVirtualServer(svc *ipvs.Service) (*VirtualServer, error) { func toVirtualServer(svc *libipvs.Service) (*VirtualServer, error) {
if svc == nil { if svc == nil {
return nil, errors.New("ipvs svc should not be empty") return nil, errors.New("ipvs svc should not be empty")
} }
@ -172,7 +175,7 @@ func toVirtualServer(svc *ipvs.Service) (*VirtualServer, error) {
Address: svc.Address, Address: svc.Address,
Port: svc.Port, Port: svc.Port,
Scheduler: svc.SchedName, Scheduler: svc.SchedName,
Protocol: protocolNumbeToString(ProtoType(svc.Protocol)), Protocol: protocolToString(Protocol(svc.Protocol)),
Timeout: svc.Timeout, Timeout: svc.Timeout,
} }
@ -194,8 +197,8 @@ func toVirtualServer(svc *ipvs.Service) (*VirtualServer, error) {
return vs, nil return vs, nil
} }
// toRealServer converts an IPVS destination representation to the equivalent real server structure. // toRealServer converts an IPVS Destination to the equivalent RealServer structure.
func toRealServer(dst *ipvs.Destination) (*RealServer, error) { func toRealServer(dst *libipvs.Destination) (*RealServer, error) {
if dst == nil { if dst == nil {
return nil, errors.New("ipvs destination should not be empty") return nil, errors.New("ipvs destination should not be empty")
} }
@ -206,14 +209,14 @@ func toRealServer(dst *ipvs.Destination) (*RealServer, error) {
}, nil }, nil
} }
// toBackendService converts an IPVS real server representation to the equivalent "backend" service structure. // toIPVSService converts a VirtualServer to the equivalent IPVS Service structure.
func toBackendService(vs *VirtualServer) (*ipvs.Service, error) { func toIPVSService(vs *VirtualServer) (*libipvs.Service, error) {
if vs == nil { if vs == nil {
return nil, errors.New("virtual server should not be empty") return nil, errors.New("virtual server should not be empty")
} }
bakSvc := &ipvs.Service{ ipvsSvc := &libipvs.Service{
Address: vs.Address, Address: vs.Address,
Protocol: stringToProtocolNumber(vs.Protocol), Protocol: stringToProtocol(vs.Protocol),
Port: vs.Port, Port: vs.Port,
SchedName: vs.Scheduler, SchedName: vs.Scheduler,
Flags: uint32(vs.Flags), Flags: uint32(vs.Flags),
@ -221,29 +224,29 @@ func toBackendService(vs *VirtualServer) (*ipvs.Service, error) {
} }
if ip4 := vs.Address.To4(); ip4 != nil { if ip4 := vs.Address.To4(); ip4 != nil {
bakSvc.AddressFamily = syscall.AF_INET ipvsSvc.AddressFamily = syscall.AF_INET
bakSvc.Netmask = 0xffffffff ipvsSvc.Netmask = 0xffffffff
} else { } else {
bakSvc.AddressFamily = syscall.AF_INET6 ipvsSvc.AddressFamily = syscall.AF_INET6
bakSvc.Netmask = 128 ipvsSvc.Netmask = 128
} }
return bakSvc, nil return ipvsSvc, nil
} }
// toBackendDestination converts an IPVS real server representation to the equivalent "backend" destination structure. // toIPVSDestination converts a RealServer to the equivalent IPVS Destination structure.
func toBackendDestination(rs *RealServer) (*ipvs.Destination, error) { func toIPVSDestination(rs *RealServer) (*libipvs.Destination, error) {
if rs == nil { if rs == nil {
return nil, errors.New("real server should not be empty") return nil, errors.New("real server should not be empty")
} }
return &ipvs.Destination{ return &libipvs.Destination{
Address: rs.Address, Address: rs.Address,
Port: rs.Port, Port: rs.Port,
Weight: rs.Weight, Weight: rs.Weight,
}, nil }, nil
} }
// stringToProtocolNumber returns the protocol value for the given name // stringToProtocolType returns the protocol type for the given name
func stringToProtocolNumber(protocol string) uint16 { func stringToProtocol(protocol string) uint16 {
switch strings.ToLower(protocol) { switch strings.ToLower(protocol) {
case "tcp": case "tcp":
return uint16(syscall.IPPROTO_TCP) return uint16(syscall.IPPROTO_TCP)
@ -253,8 +256,8 @@ func stringToProtocolNumber(protocol string) uint16 {
return uint16(0) return uint16(0)
} }
// protocolNumbeToString returns the name for the given protocol value. // protocolTypeToString returns the name for the given protocol.
func protocolNumbeToString(proto ProtoType) string { func protocolToString(proto Protocol) string {
switch proto { switch proto {
case syscall.IPPROTO_TCP: case syscall.IPPROTO_TCP:
return "TCP" return "TCP"
@ -263,6 +266,3 @@ func protocolNumbeToString(proto ProtoType) string {
} }
return "" return ""
} }
// ProtoType is IPVS service protocol type
type ProtoType uint16

View File

@ -25,18 +25,18 @@ import (
"syscall" "syscall"
"testing" "testing"
"github.com/docker/libnetwork/ipvs" libipvs "github.com/docker/libnetwork/ipvs"
) )
func Test_toVirtualServer(t *testing.T) { func Test_toVirtualServer(t *testing.T) {
Tests := []struct { Tests := []struct {
ipvsService ipvs.Service ipvsService libipvs.Service
virtualServer VirtualServer virtualServer VirtualServer
expectError bool expectError bool
reason string reason string
}{ }{
{ {
ipvs.Service{ libipvs.Service{
Flags: 0x0, Flags: 0x0,
}, },
VirtualServer{}, VirtualServer{},
@ -44,7 +44,7 @@ func Test_toVirtualServer(t *testing.T) {
fmt.Sprintf("IPVS Service Flags should be >= %d, got 0x0", FlagHashed), fmt.Sprintf("IPVS Service Flags should be >= %d, got 0x0", FlagHashed),
}, },
{ {
ipvs.Service{ libipvs.Service{
Flags: 0x1, Flags: 0x1,
}, },
VirtualServer{}, VirtualServer{},
@ -52,7 +52,7 @@ func Test_toVirtualServer(t *testing.T) {
fmt.Sprintf("IPVS Service Flags should be >= %d, got 0x1", FlagHashed), fmt.Sprintf("IPVS Service Flags should be >= %d, got 0x1", FlagHashed),
}, },
{ {
ipvs.Service{ libipvs.Service{
Protocol: syscall.IPPROTO_TCP, Protocol: syscall.IPPROTO_TCP,
Port: 80, Port: 80,
FWMark: 0, FWMark: 0,
@ -76,7 +76,7 @@ func Test_toVirtualServer(t *testing.T) {
"", "",
}, },
{ {
ipvs.Service{ libipvs.Service{
Protocol: syscall.IPPROTO_UDP, Protocol: syscall.IPPROTO_UDP,
Port: 33434, Port: 33434,
FWMark: 0, FWMark: 0,
@ -100,7 +100,7 @@ func Test_toVirtualServer(t *testing.T) {
"", "",
}, },
{ {
ipvs.Service{ libipvs.Service{
Protocol: 0, Protocol: 0,
Port: 0, Port: 0,
FWMark: 0, FWMark: 0,
@ -124,7 +124,7 @@ func Test_toVirtualServer(t *testing.T) {
"", "",
}, },
{ {
ipvs.Service{ libipvs.Service{
Protocol: 0, Protocol: 0,
Port: 0, Port: 0,
FWMark: 0, FWMark: 0,
@ -165,13 +165,13 @@ func Test_toVirtualServer(t *testing.T) {
} }
} }
func Test_toBackendService(t *testing.T) { func Test_toIPVSService(t *testing.T) {
Tests := []struct { Tests := []struct {
ipvsService ipvs.Service ipvsService libipvs.Service
virtualServer VirtualServer virtualServer VirtualServer
}{ }{
{ {
ipvs.Service{ libipvs.Service{
Protocol: syscall.IPPROTO_TCP, Protocol: syscall.IPPROTO_TCP,
Port: 80, Port: 80,
FWMark: 0, FWMark: 0,
@ -193,7 +193,7 @@ func Test_toBackendService(t *testing.T) {
}, },
}, },
{ {
ipvs.Service{ libipvs.Service{
Protocol: syscall.IPPROTO_UDP, Protocol: syscall.IPPROTO_UDP,
Port: 33434, Port: 33434,
FWMark: 0, FWMark: 0,
@ -215,7 +215,7 @@ func Test_toBackendService(t *testing.T) {
}, },
}, },
{ {
ipvs.Service{ libipvs.Service{
Protocol: 0, Protocol: 0,
Port: 0, Port: 0,
FWMark: 0, FWMark: 0,
@ -237,7 +237,7 @@ func Test_toBackendService(t *testing.T) {
}, },
}, },
{ {
ipvs.Service{ libipvs.Service{
Protocol: 0, Protocol: 0,
Port: 0, Port: 0,
FWMark: 0, FWMark: 0,
@ -261,7 +261,7 @@ func Test_toBackendService(t *testing.T) {
} }
for i := range Tests { for i := range Tests {
got, err := toBackendService(&Tests[i].virtualServer) got, err := toIPVSService(&Tests[i].virtualServer)
if err != nil { if err != nil {
t.Errorf("case: %d, unexpected error: %v", i, err) t.Errorf("case: %d, unexpected error: %v", i, err)
} }
@ -271,13 +271,13 @@ func Test_toBackendService(t *testing.T) {
} }
} }
func Test_toFrontendDestination(t *testing.T) { func Test_toRealServer(t *testing.T) {
Tests := []struct { Tests := []struct {
ipvsDestination ipvs.Destination ipvsDestination libipvs.Destination
realServer RealServer realServer RealServer
}{ }{
{ {
ipvs.Destination{ libipvs.Destination{
Port: 54321, Port: 54321,
ConnectionFlags: 0, ConnectionFlags: 0,
Weight: 1, Weight: 1,
@ -290,7 +290,7 @@ func Test_toFrontendDestination(t *testing.T) {
}, },
}, },
{ {
ipvs.Destination{ libipvs.Destination{
Port: 53, Port: 53,
ConnectionFlags: 0, ConnectionFlags: 0,
Weight: 1, Weight: 1,
@ -314,10 +314,10 @@ func Test_toFrontendDestination(t *testing.T) {
} }
} }
func Test_toBackendDestination(t *testing.T) { func Test_toIPVSDestination(t *testing.T) {
Tests := []struct { Tests := []struct {
realServer RealServer realServer RealServer
ipvsDestination ipvs.Destination ipvsDestination libipvs.Destination
}{ }{
{ {
RealServer{ RealServer{
@ -325,7 +325,7 @@ func Test_toBackendDestination(t *testing.T) {
Port: 54321, Port: 54321,
Weight: 1, Weight: 1,
}, },
ipvs.Destination{ libipvs.Destination{
Port: 54321, Port: 54321,
ConnectionFlags: 0, ConnectionFlags: 0,
Weight: 1, Weight: 1,
@ -338,7 +338,7 @@ func Test_toBackendDestination(t *testing.T) {
Port: 53, Port: 53,
Weight: 1, Weight: 1,
}, },
ipvs.Destination{ libipvs.Destination{
Port: 53, Port: 53,
ConnectionFlags: 0, ConnectionFlags: 0,
Weight: 1, Weight: 1,
@ -347,44 +347,44 @@ func Test_toBackendDestination(t *testing.T) {
}, },
} }
for i := range Tests { for i := range Tests {
got, err := toBackendDestination(&Tests[i].realServer) got, err := toIPVSDestination(&Tests[i].realServer)
if err != nil { if err != nil {
t.Errorf("case %d unexpected error: %d", i, err) t.Errorf("case %d unexpected error: %d", i, err)
} }
if !reflect.DeepEqual(*got, Tests[i].ipvsDestination) { if !reflect.DeepEqual(*got, Tests[i].ipvsDestination) {
t.Errorf("case %d Failed to translate Destination - got %#v, want %#v", i, *got, Tests[i].ipvsDestination) t.Errorf("case %d failed to translate Destination - got %#v, want %#v", i, *got, Tests[i].ipvsDestination)
} }
} }
} }
func Test_stringToProtocolNumber(t *testing.T) { func Test_stringToProtocol(t *testing.T) {
tests := []string{ tests := []string{
"TCP", "UDP", "ICMP", "TCP", "UDP", "ICMP",
} }
expecteds := []uint16{ expected := []uint16{
uint16(syscall.IPPROTO_TCP), uint16(syscall.IPPROTO_UDP), uint16(0), uint16(syscall.IPPROTO_TCP), uint16(syscall.IPPROTO_UDP), uint16(0),
} }
for i := range tests { for i := range tests {
got := stringToProtocolNumber(tests[i]) got := stringToProtocol(tests[i])
if got != expecteds[i] { if got != expected[i] {
t.Errorf("stringToProtocolNumber() failed - got %#v, want %#v", t.Errorf("stringToProtocol() failed - got %#v, want %#v",
got, expecteds[i]) got, expected[i])
} }
} }
} }
func Test_protocolNumberToString(t *testing.T) { func Test_protocolToString(t *testing.T) {
tests := []ProtoType{ tests := []Protocol{
syscall.IPPROTO_TCP, syscall.IPPROTO_UDP, ProtoType(0), syscall.IPPROTO_TCP, syscall.IPPROTO_UDP, Protocol(0),
} }
expecteds := []string{ expected := []string{
"TCP", "UDP", "", "TCP", "UDP", "",
} }
for i := range tests { for i := range tests {
got := protocolNumbeToString(tests[i]) got := protocolToString(tests[i])
if got != expecteds[i] { if got != expected[i] {
t.Errorf("protocolNumbeToString() failed - got %#v, want %#v", t.Errorf("protocolToString() failed - got %#v, want %#v",
got, expecteds[i]) got, expected[i])
} }
} }
} }