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

add unittest for IPAM #2977

Merged
merged 3 commits into from
Jun 25, 2023
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
9 changes: 0 additions & 9 deletions charts/templates/kube-ovn-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1781,9 +1781,6 @@ spec:
- name: Subnet
type: string
jsonPath: .spec.subnet
- name: Protocol
type: string
jsonPath: .spec.protocol
- name: IPs
type: string
jsonPath: .spec.ips
Expand Down Expand Up @@ -1816,12 +1813,6 @@ spec:
x-kubernetes-list-type: set
items:
type: string
protocol:
type: string
enum:
- IPv4
- IPv6
- Dual
ips:
type: array
minItems: 1
Expand Down
9 changes: 0 additions & 9 deletions dist/images/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2319,9 +2319,6 @@ spec:
- name: Subnet
type: string
jsonPath: .spec.subnet
- name: Protocol
type: string
jsonPath: .spec.protocol
- name: IPs
type: string
jsonPath: .spec.ips
Expand Down Expand Up @@ -2354,12 +2351,6 @@ spec:
x-kubernetes-list-type: set
items:
type: string
protocol:
type: string
enum:
- IPv4
- IPv6
- Dual
ips:
type: array
minItems: 1
Expand Down
18 changes: 9 additions & 9 deletions pkg/apis/kubeovn/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/kubeovn/kube-ovn/pkg/internal"
"github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb"
)

Expand Down Expand Up @@ -265,7 +266,6 @@ type IPPool struct {

type IPPoolSpec struct {
Subnet string `json:"subnet,omitempty"`
Protocol string `json:"protocol,omitempty"`
Namespaces []string `json:"namespaces,omitempty"`
IPs []string `json:"ips,omitempty"`
}
Expand All @@ -275,14 +275,14 @@ type IPPoolSpec struct {
type IPPoolCondition Condition

type IPPoolStatus struct {
V4AvailableIPs float64 `json:"v4AvailableIPs"`
V4AvailableIPRange string `json:"v4AvailableIPRange"`
V4UsingIPs float64 `json:"v4UsingIPs"`
V4UsingIPRange string `json:"v4UsingIPRange"`
V6AvailableIPs float64 `json:"v6AvailableIPs"`
V6AvailableIPRange string `json:"v6AvailableIPRange"`
V6UsingIPs float64 `json:"v6UsingIPs"`
V6UsingIPRange string `json:"v6UsingIPRange"`
V4AvailableIPs internal.BigInt `json:"v4AvailableIPs"`
V4AvailableIPRange string `json:"v4AvailableIPRange"`
V4UsingIPs internal.BigInt `json:"v4UsingIPs"`
V4UsingIPRange string `json:"v4UsingIPRange"`
V6AvailableIPs internal.BigInt `json:"v6AvailableIPs"`
V6AvailableIPRange string `json:"v6AvailableIPRange"`
V6UsingIPs internal.BigInt `json:"v6UsingIPs"`
V6UsingIPRange string `json:"v6UsingIPRange"`

// Conditions represents the latest state of the object
// +optional
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/kubeovn/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions pkg/controller/ippool.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ func (c *Controller) enqueueUpdateIPPool(old, new interface{}) {
}

if !reflect.DeepEqual(oldIPPool.Spec.Namespaces, newIPPool.Spec.Namespaces) ||
!reflect.DeepEqual(oldIPPool.Spec.IPs, newIPPool.Spec.IPs) ||
oldIPPool.Spec.Protocol != newIPPool.Spec.Protocol {
!reflect.DeepEqual(oldIPPool.Spec.IPs, newIPPool.Spec.IPs) {
klog.V(3).Infof("enqueue update ippool %s", key)
c.addOrUpdateIPPoolQueue.Add(key)
}
Expand Down
47 changes: 47 additions & 0 deletions pkg/internal/big_int.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package internal

import (
"fmt"
"math/big"
)

type BigInt struct {
big.Int
}

func (b BigInt) DeepCopyInto(n *BigInt) {
n.Int.FillBytes(b.Int.Bytes())
}

func (b BigInt) Equal(n BigInt) bool {
return b.Cmp(n) == 0
}

func (b BigInt) Cmp(n BigInt) int {
return b.Int.Cmp(&n.Int)
}

func (b BigInt) Add(n BigInt) BigInt {
return BigInt{*big.NewInt(0).Add(&b.Int, &n.Int)}
}

func (b BigInt) Sub(n BigInt) BigInt {
return BigInt{*big.NewInt(0).Sub(&b.Int, &n.Int)}
}

func (b BigInt) MarshalJSON() ([]byte, error) {
return []byte(b.String()), nil
}

func (b *BigInt) UnmarshalJSON(p []byte) error {
if string(p) == "null" {
return nil
}
var z big.Int
_, ok := z.SetString(string(p), 10)
if !ok {
return fmt.Errorf("invalid big integer: %q", p)
}
b.Int = z
return nil
}
26 changes: 22 additions & 4 deletions pkg/ipam/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"math/big"
"net"
"strings"
)

type IP net.IP
Expand All @@ -14,9 +15,10 @@ func NewIP(s string) (IP, error) {
return nil, fmt.Errorf("invalid IP address %q", s)
}

if ip4 := ip.To4(); ip4 != nil {
ip = ip4
if !strings.ContainsRune(s, ':') {
ip = ip.To4()
}

return IP(ip), nil
}

Expand All @@ -41,11 +43,27 @@ func (a IP) GreaterThan(b IP) bool {
}

func (a IP) Add(n int64) IP {
return IP(big.NewInt(0).Add(big.NewInt(0).SetBytes([]byte(a)), big.NewInt(n)).Bytes())
buff := big.NewInt(0).Add(big.NewInt(0).SetBytes([]byte(a)), big.NewInt(n)).Bytes()
if len(buff) < len(a) {
tmp := make([]byte, len(a))
copy(tmp[len(tmp)-len(buff):], buff)
buff = tmp
} else if len(buff) > len(a) {
buff = buff[len(buff)-len(a):]
}
return IP(buff)
}

func (a IP) Sub(n int64) IP {
return IP(big.NewInt(0).Sub(big.NewInt(0).SetBytes([]byte(a)), big.NewInt(n)).Bytes())
buff := big.NewInt(0).Sub(big.NewInt(0).SetBytes([]byte(a)), big.NewInt(n)).Bytes()
if len(buff) < len(a) {
tmp := make([]byte, len(a))
copy(tmp[len(tmp)-len(buff):], buff)
buff = tmp
} else if len(buff) > len(a) {
buff = buff[len(buff)-len(a):]
}
return IP(buff)
}

func (a IP) String() string {
Expand Down
8 changes: 4 additions & 4 deletions pkg/ipam/ip_range.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package ipam
import (
"fmt"
"math/big"
"strconv"

"github.com/kubeovn/kube-ovn/pkg/internal"
)

// IPRange represents an IP range of [start, end]
Expand Down Expand Up @@ -35,10 +36,9 @@ func (r *IPRange) SetEnd(ip IP) {
r.end = ip
}

func (r *IPRange) Count() float64 {
func (r *IPRange) Count() internal.BigInt {
n := big.NewInt(0).Sub(big.NewInt(0).SetBytes([]byte(r.end)), big.NewInt(0).SetBytes([]byte(r.start)))
count, _ := strconv.ParseFloat(n.Add(n, big.NewInt(1)).String(), 64)
return count
return internal.BigInt{Int: *n.Add(n, big.NewInt(1))}
}

func (r *IPRange) Contains(ip IP) bool {
Expand Down
81 changes: 31 additions & 50 deletions pkg/ipam/ip_range_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,49 @@ import (
"fmt"
"sort"
"strings"

"github.com/kubeovn/kube-ovn/pkg/internal"
)

type IPRangeList struct {
ranges []*IPRange
}

func NewIPRangeList() *IPRangeList {
func NewEmptyIPRangeList() *IPRangeList {
return &IPRangeList{}
}

func NewIPRangeList(ips ...IP) (*IPRangeList, error) {
if len(ips)%2 != 0 {
return nil, fmt.Errorf("length of ips must be an even number, but current is %d", len(ips))
}

ret := &IPRangeList{make([]*IPRange, len(ips)/2)}
for i := 0; i < len(ips)/2; i++ {
ret.ranges[i] = NewIPRange(ips[i*2], ips[i*2+1])
}
return ret, nil
}

func NewIPRangeListFrom(x ...string) (*IPRangeList, error) {
ret := &IPRangeList{make([]*IPRange, 0, len(x))}
ret := &IPRangeList{}
for _, s := range x {
ips := strings.Split(s, "..")
start, err := NewIP(ips[0])
if err != nil {
return nil, err
}
var r *IPRange
if len(ips) == 1 {
ip, err := NewIP(ips[0])
if err != nil {
return nil, err
}
ret.Add(ip)
r = NewIPRange(start, start)
} else {
start, err := NewIP(ips[0])
if err != nil {
return nil, err
}
end, err := NewIP(ips[1])
if err != nil {
return nil, err
}
if end.LessThan(start) {
return nil, fmt.Errorf("invalid IP range %s: end %s must NOT be less than start %s", s, ips[1], ips[0])
}

n1, found1 := ret.Find(start)
n2, found2 := ret.Find(end)
if found1 {
if found2 {
if n1 != n2 {
ret.ranges[n1].SetEnd(ret.ranges[n2].End())
ret.ranges = append(ret.ranges[:n1+1], ret.ranges[n2+1:]...)
}
} else {
ret.ranges[n1].SetEnd(end)
ret.ranges = append(ret.ranges[:n1+1], ret.ranges[n2:]...)
}
} else {
if found2 {
ret.ranges[n2].SetStart(start)
ret.ranges = append(ret.ranges[:n1], ret.ranges[n2:]...)
} else {
if n1 == n2 {
tmp := make([]*IPRange, ret.Len()+1)
copy(tmp, ret.ranges[:n1])
tmp[n1] = NewIPRange(start, end)
copy(tmp[n1+1:], ret.ranges[n1:])
ret.ranges = tmp
} else {
ret.ranges[n1] = NewIPRange(start, end)
ret.ranges = append(ret.ranges[:n1+1], ret.ranges[n2+1:]...)
}
}
}
r = NewIPRange(start, end)
}
ret = ret.Merge(&IPRangeList{[]*IPRange{r}})
}
return ret, nil
}
Expand All @@ -81,12 +61,12 @@ func (r *IPRangeList) Len() int {
return len(r.ranges)
}

func (r *IPRangeList) Count() float64 {
var sum float64
func (r *IPRangeList) Count() internal.BigInt {
var count internal.BigInt
for _, v := range r.ranges {
sum += v.Count()
count = count.Add(v.Count())
}
return sum
return count
}

func (r *IPRangeList) At(i int) *IPRange {
Expand Down Expand Up @@ -171,7 +151,7 @@ func (r *IPRangeList) Allocate(skipped []IP) IP {
return ret
}

tmp := NewIPRangeList()
tmp := NewEmptyIPRangeList()
for _, ip := range skipped {
tmp.Add(ip)
}
Expand Down Expand Up @@ -203,7 +183,7 @@ func (r *IPRangeList) Equal(x *IPRangeList) bool {
// Separate returns a new list which contains items which are in `r` but not in `x`
func (r *IPRangeList) Separate(x *IPRangeList) *IPRangeList {
if r.Len() == 0 {
return NewIPRangeList()
return NewEmptyIPRangeList()
}
if x.Len() == 0 {
return r.Clone()
Expand Down Expand Up @@ -269,6 +249,7 @@ func (r *IPRangeList) Merge(x *IPRangeList) *IPRangeList {
if ret.ranges[i].End().Add(1).Equal(ret.ranges[i+1].Start()) {
ret.ranges[i].end = ret.ranges[i+1].end
ret.ranges = append(ret.ranges[:i+1], ret.ranges[i+2:]...)
i--
}
}

Expand Down
Loading