Skip to content

Commit

Permalink
feat: update normal sync pool service in vip loadbalancer
Browse files Browse the repository at this point in the history
Signed-off-by: wangxye <[email protected]>
  • Loading branch information
wangxye committed Aug 7, 2024
1 parent e0cca83 commit 1465fa1
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"fmt"
"net"
"strings"

"k8s.io/apimachinery/pkg/util/sets"
)

const (
Expand All @@ -33,10 +35,11 @@ type IPVRID struct {
}

type IPManager struct {
// ipPools indicates if ip is assign
ipPools map[string]int
IPRanges sets.Set[string]
// ipPools indicates if ip is assigned
IPPools map[string]int
// ipVRIDs indicates which IPs are assigned to vrid
ipVRIDs map[int][]string
IPVRIDs map[int][]string
}

func NewIPVRID(ips []string, vrid int) IPVRID {
Expand All @@ -46,15 +49,15 @@ func NewIPVRID(ips []string, vrid int) IPVRID {
}
}

func NewIPManager(ipRanges string) (*IPManager, error) {
manager := &IPManager{
ipPools: map[string]int{},
ipVRIDs: make(map[int][]string),
func NewIPManager(ipr []string) (*IPManager, error) {
if len(ipr) == 0 {
return nil, errors.New("ip ranges is empty")

Check warning on line 54 in pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go#L54

Added line #L54 was not covered by tests
}

iprs := ParseIP(ipRanges)
for _, ipr := range iprs {
manager.ipPools[ipr] = VRIDEVICTED
manager := &IPManager{
IPRanges: sets.New(ipr...),
IPPools: make(map[string]int),
IPVRIDs: make(map[int][]string),
}

return manager, nil
Expand Down Expand Up @@ -98,14 +101,14 @@ func incrementIP(ip net.IP) net.IP {
return ip
}

// Get return a IPVRID with a available IP and VRID combination
// Get return a IPVRID with an available IP and VRID combination
func (m *IPManager) Get() (IPVRID, error) {
for vrid := 0; vrid < VRIDMAXVALUE; vrid++ {
if ips, ok := m.ipVRIDs[vrid]; !ok || len(ips) == 0 {
for ip, used := range m.ipPools {
if used == VRIDEVICTED {
m.ipPools[ip] = vrid
m.ipVRIDs[vrid] = []string{ip}
if ips, ok := m.IPVRIDs[vrid]; !ok || len(ips) == 0 {
for ip, _ := range m.IPRanges {
if _, ok := m.IPPools[ip]; !ok || m.IPPools[ip] == VRIDEVICTED {
m.IPPools[ip] = vrid
m.IPVRIDs[vrid] = []string{ip}
return IPVRID{IPs: []string{ip}, VRID: vrid}, nil
}
}
Expand All @@ -119,72 +122,73 @@ func (m *IPManager) Get() (IPVRID, error) {
func (m *IPManager) Assign(ips []string) (IPVRID, error) {
var noConflictIPs []string
for _, ip := range ips {
// if conflict, just use no conflict
if m.ipPools[ip] != VRIDEVICTED {
// if conflicted, just use no conflict
if _, ok := m.IPPools[ip]; ok {
continue

Check warning on line 127 in pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go#L127

Added line #L127 was not covered by tests
}
noConflictIPs = append(noConflictIPs, ip)
}

// if no avalible ip, get a new ipvrid
// if no available ip, get a new ipvrid
if len(noConflictIPs) == 0 {
return m.Get()
}
var vrid int
for ; vrid < VRIDMAXVALUE; vrid++ {
if _, ok := m.ipVRIDs[vrid]; !ok {
m.ipVRIDs[vrid] = append(m.ipVRIDs[vrid], noConflictIPs...)
if _, ok := m.IPVRIDs[vrid]; ok {
continue

Check warning on line 139 in pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go#L139

Added line #L139 was not covered by tests
}

for _, ip := range noConflictIPs {
m.ipPools[ip] = vrid
}
break
m.IPVRIDs[vrid] = append(m.IPVRIDs[vrid], noConflictIPs...)
for _, ip := range noConflictIPs {
m.IPPools[ip] = vrid
}
break
}

// Get fully vrid-ips pair
return IPVRID{VRID: vrid, IPs: m.ipVRIDs[vrid]}, nil
return IPVRID{VRID: vrid, IPs: m.IPVRIDs[vrid]}, nil
}

// Release release ips from vrid, if vrid is not assigned, return error
// Release ips from vrid, if vrid is not assigned, return error
func (m *IPManager) Release(ipVRID IPVRID) error {
if err := m.IsValid(ipVRID); err != nil {
return err

Check warning on line 156 in pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go#L156

Added line #L156 was not covered by tests
}

if _, ok := m.ipVRIDs[ipVRID.VRID]; !ok {
if _, ok := m.IPVRIDs[ipVRID.VRID]; !ok {
return fmt.Errorf("VRID %d does not assign ips", ipVRID.VRID)

Check warning on line 160 in pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go#L160

Added line #L160 was not covered by tests
}
remain := make([]string, len(m.ipVRIDs[ipVRID.VRID])-len(ipVRID.IPs))
remain := make([]string, len(m.IPVRIDs[ipVRID.VRID])-len(ipVRID.IPs))

for _, ip := range m.ipVRIDs[ipVRID.VRID] {
for _, ip := range m.IPVRIDs[ipVRID.VRID] {
if m.isIPPresent(ip, ipVRID.IPs) {
continue
}

remain = append(remain, ip)
}

if len(remain) == len(m.ipVRIDs[ipVRID.VRID]) {
if len(remain) == len(m.IPVRIDs[ipVRID.VRID]) {
return fmt.Errorf("IP %v is not assigned", ipVRID.IPs)
}

for _, ip := range remain {
m.ipPools[ip] = VRIDEVICTED
m.IPPools[ip] = VRIDEVICTED

Check warning on line 177 in pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go

View check run for this annotation

Codecov / codecov/patch

pkg/yurtmanager/controller/loadbalancerset/viploadbalancer/ip_utils.go#L177

Added line #L177 was not covered by tests
}

return nil
}

// check if ip and vrid is valid in this ip-pools, if not return error
// IsValid check if ip and vrid is valid in this ip-pools, if not return error
func (m *IPManager) IsValid(ipvrid IPVRID) error {
if len(ipvrid.IPs) == 0 {
return fmt.Errorf("IPs is empty")
}

for _, ip := range ipvrid.IPs {
if _, ok := m.ipPools[ip]; !ok {
return fmt.Errorf("IP: %s is not found in IP-Pools", ip)
if !m.IPRanges.Has(ip) {
return fmt.Errorf("IP: %s is not found in IP-Ranges", ip)
}
}

Expand All @@ -203,15 +207,15 @@ func (m *IPManager) Sync(ipVRIDs []IPVRID) error {
ips := ipVRID.IPs
vrid := ipVRID.VRID

app, del := m.findDiffIPs(ips, m.ipVRIDs[vrid])
app, del := m.findDiffIPs(ips, m.IPVRIDs[vrid])

for _, ip := range del {
m.ipPools[ip] = VRIDEVICTED
m.IPPools[ip] = VRIDEVICTED
}

m.ipVRIDs[vrid] = ips
m.IPVRIDs[vrid] = ips
for _, ip := range app {
m.ipPools[ip] = vrid
m.IPPools[ip] = vrid
}

}
Expand All @@ -222,13 +226,13 @@ func (m *IPManager) Sync(ipVRIDs []IPVRID) error {
// findDiffIPs find the difference between des and cur, return the difference between des and cur
func (m *IPManager) findDiffIPs(des, cur []string) (app, del []string) {
for _, dip := range des {
if exsit := m.isIPPresent(dip, cur); !exsit {
if exist := m.isIPPresent(dip, cur); !exist {
app = append(app, dip)
}
}

for _, cip := range cur {
if exsit := m.isIPPresent(cip, des); !exsit {
if exist := m.isIPPresent(cip, des); !exist {
del = append(del, cip)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import (
vip "github.com/openyurtio/openyurt/pkg/yurtmanager/controller/loadbalancerset/viploadbalancer"
)

func TestIPMAnager(t *testing.T) {
func TestIPManager(t *testing.T) {
ipRanges := "192.168.0.1-192.168.1.5, 10.0.0.1-10.0.0.3"
manager, err := vip.NewIPManager(ipRanges)
manager, err := vip.NewIPManager(vip.ParseIP(ipRanges))
if err != nil {
t.Fatalf("Failed to create IPManager: %v", err)
}
Expand Down Expand Up @@ -54,7 +54,8 @@ func TestIPMAnager(t *testing.T) {

t.Run("get ip when none are available", func(t *testing.T) {
// Test getting IPVRID when none are available
m, err := vip.NewIPManager("192.168.0.1")
ipr := "192.168.0.1"
m, err := vip.NewIPManager(vip.ParseIP(ipr))
if err != nil {
t.Errorf("Failed to create IPManager: %v", err)
}
Expand Down Expand Up @@ -88,21 +89,7 @@ func TestIPMAnager(t *testing.T) {
}
})

t.Run("sync ip with repeat", func(t *testing.T) {
// Test syncing IPVRIDs
ipVRIDs := []vip.IPVRID{
{IPs: []string{"192.168.0.1"}, VRID: 0},
{IPs: []string{"192.168.0.2"}, VRID: 1},
{IPs: []string{"10.0.0.1"}, VRID: 0},
{IPs: []string{"10.0.0.2"}, VRID: 1},
}
err = manager.Sync(ipVRIDs)
if err != nil {
t.Errorf("Failed to sync IPVRIDs: %v", err)
}
})

t.Run("sync ip", func(t *testing.T) {
t.Run("sync ip with repeat vrid", func(t *testing.T) {
// Test syncing IPVRIDs
ipVRIDs := []vip.IPVRID{
{IPs: []string{"192.168.0.1"}, VRID: 0},
Expand Down
Loading

0 comments on commit 1465fa1

Please sign in to comment.