Skip to content

Commit

Permalink
fixup! fixup! feat: ipam timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
cheina97 committed Dec 3, 2024
1 parent 75f31ad commit b3c8ee2
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 18 deletions.
34 changes: 32 additions & 2 deletions pkg/ipam/core/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ func (ipam *Ipam) ListIPs(prefix netip.Prefix) ([]netip.Addr, error) {
return nil, nil
}

// IsAllocatedIP checks if the IP address is allocated from the given prefix.
// IPIsAlocated checks if the IP address is allocated from the given prefix.
// It returns true if the IP address is allocated, false otherwise.
func (ipam *Ipam) IsAllocatedIP(prefix netip.Prefix, addr netip.Addr) (bool, error) {
func (ipam *Ipam) IPIsAlocated(prefix netip.Prefix, addr netip.Addr) (bool, error) {
node, err := ipam.search(prefix)
if err != nil {
return false, err
Expand Down Expand Up @@ -220,3 +220,33 @@ func checkRoots(roots []netip.Prefix) error {
}
return nil
}

// NetworkSetLastUpdateTimestamp sets the last update time of the network with the given prefix.
// This function is for testing purposes only.
func (ipam *Ipam) NetworkSetLastUpdateTimestamp(prefix netip.Prefix, lastUpdateTimestamp time.Time) error {
node, err := ipam.search(prefix)
if err != nil {
return err
}
if node == nil {
return fmt.Errorf("prefix %s not found", prefix)
}
node.lastUpdateTimestamp = lastUpdateTimestamp
return nil
}

// IPSetCreationTimestamp sets the creation timestamp of the IP address with the given address.
// This function is for testing purposes only.
func (ipam *Ipam) IPSetCreationTimestamp(addr netip.Addr, prefix netip.Prefix, creationTimestamp time.Time) error {
node, err := ipam.search(prefix)
if err != nil {
return err
}
for i := range node.ips {
if node.ips[i].addr.Compare(addr) == 0 {
node.ips[i].creationTimestamp = creationTimestamp
return nil
}
}
return nil
}
22 changes: 11 additions & 11 deletions pkg/ipam/core/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type nodeIP struct {

// node represents a node in the binary tree.
type node struct {
lastUpdate time.Time
lastUpdateTimestamp time.Time

prefix netip.Prefix
acquired bool
Expand All @@ -53,7 +53,7 @@ const (
)

func newNode(prefix netip.Prefix) node {
return node{prefix: prefix, lastUpdate: time.Now()}
return node{prefix: prefix, lastUpdateTimestamp: time.Now()}
}

func allocateNetwork(size int, node *node) *netip.Prefix {
Expand All @@ -63,7 +63,7 @@ func allocateNetwork(size int, node *node) *netip.Prefix {
if node.prefix.Bits() == size {
if !node.isSplitted() {
node.acquired = true
node.lastUpdate = time.Now()
node.lastUpdateTimestamp = time.Now()
return &node.prefix
}
return nil
Expand All @@ -88,7 +88,7 @@ func allocateNetworkWithPrefix(prefix netip.Prefix, node *node) *netip.Prefix {
if node.prefix.Addr().Compare(prefix.Addr()) == 0 && node.prefix.Bits() == prefix.Bits() {
if !node.acquired && node.left == nil && node.right == nil {
node.acquired = true
node.lastUpdate = time.Now()
node.lastUpdateTimestamp = time.Now()
return &node.prefix
}
return nil
Expand All @@ -115,10 +115,10 @@ func networkRelease(prefix netip.Prefix, node *node, gracePeriod time.Duration)
return nil
}

if node.prefix.Addr().Compare(prefix.Addr()) == 0 && node.prefix.Bits() == prefix.Bits() && node.lastUpdate.Add(gracePeriod).Before(time.Now()) {
if node.prefix.Addr().Compare(prefix.Addr()) == 0 && node.prefix.Bits() == prefix.Bits() && node.lastUpdateTimestamp.Add(gracePeriod).Before(time.Now()) {
if node.acquired {
node.acquired = false
node.lastUpdate = time.Now()
node.lastUpdateTimestamp = time.Now()
return &node.prefix
}
return nil
Expand Down Expand Up @@ -191,7 +191,7 @@ func (n *node) ipAcquire() *netip.Addr {
if !n.isAllocatedIP(addr) {
n.ips = append(n.ips, nodeIP{addr: addr, creationTimestamp: time.Now()})
n.lastip = addr
n.lastUpdate = time.Now()
n.lastUpdateTimestamp = time.Now()
return &addr
}
addr = addr.Next()
Expand All @@ -215,7 +215,7 @@ func (n *node) allocateIPWithAddr(addr netip.Addr) *netip.Addr {
}

n.ips = append(n.ips, nodeIP{addr: addr, creationTimestamp: time.Now()})
n.lastUpdate = time.Now()
n.lastUpdateTimestamp = time.Now()

return &n.ips[len(n.ips)-1].addr
}
Expand All @@ -231,7 +231,7 @@ func (n *node) ipRelease(ip netip.Addr, gracePeriod time.Duration) *netip.Addr {
}
if nodeIP.addr.Compare(ip) == 0 {
n.ips = append(n.ips[:i], n.ips[i+1:]...)
n.lastUpdate = time.Now()
n.lastUpdateTimestamp = time.Now()
return &nodeIP.addr
}
}
Expand Down Expand Up @@ -270,7 +270,7 @@ func (n *node) merge(gracePeriod time.Duration) {
if n.left == nil || n.right == nil {
return
}
if !n.left.lastUpdate.Add(gracePeriod).Before(time.Now()) || !n.right.lastUpdate.Add(gracePeriod).Before(time.Now()) {
if !n.left.lastUpdateTimestamp.Add(gracePeriod).Before(time.Now()) || !n.right.lastUpdateTimestamp.Add(gracePeriod).Before(time.Now()) {
return // grace period not expired
}
if !n.left.isLeaf() || !n.right.isLeaf() {
Expand All @@ -282,7 +282,7 @@ func (n *node) merge(gracePeriod time.Duration) {

n.left = nil
n.right = nil
n.lastUpdate = time.Now()
n.lastUpdateTimestamp = time.Now()
}

func (n *node) insert(nd nodeDirection, prefix netip.Prefix) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/ipam/ips.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (lipam *LiqoIPAM) ipRelease(addr netip.Addr, prefix netip.Prefix, gracePeri

// isIPAvailable checks if an IP is available.
func (lipam *LiqoIPAM) isIPAvailable(addr netip.Addr, prefix netip.Prefix) (bool, error) {
allocated, err := lipam.IpamCore.IsAllocatedIP(prefix, addr)
allocated, err := lipam.IpamCore.IPIsAlocated(prefix, addr)
return !allocated, err
}

Expand Down
25 changes: 21 additions & 4 deletions pkg/ipam/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (

var _ = Describe("Sync routine tests", func() {
const (
syncGracePeriod = time.Millisecond * 100
syncGracePeriod = time.Second * 5
testNamespace = "test"
)

Expand Down Expand Up @@ -109,8 +109,14 @@ var _ = Describe("Sync routine tests", func() {
Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.4.0.0/16"))).To(Equal(false))
Expect(fakeIpamServer.networkIsAvailable(netip.MustParsePrefix("10.5.0.0/16"))).To(Equal(false))

time.Sleep(syncGracePeriod)
// Run sync
newLastUpdate := time.Now().Add(-syncGracePeriod)
Expect(fakeIpamServer.IpamCore.NetworkSetLastUpdateTimestamp(netip.MustParsePrefix("10.0.0.0/16"), newLastUpdate)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.NetworkSetLastUpdateTimestamp(netip.MustParsePrefix("10.1.0.0/16"), newLastUpdate)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.NetworkSetLastUpdateTimestamp(netip.MustParsePrefix("10.2.0.0/16"), newLastUpdate)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.NetworkSetLastUpdateTimestamp(netip.MustParsePrefix("10.3.0.0/16"), newLastUpdate)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.NetworkSetLastUpdateTimestamp(netip.MustParsePrefix("10.4.0.0/16"), newLastUpdate)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.NetworkSetLastUpdateTimestamp(netip.MustParsePrefix("10.5.0.0/16"), newLastUpdate)).Should(Succeed())

Expect(fakeIpamServer.syncNetworks(ctx)).To(Succeed())

// Check the cache after grace period
Expand Down Expand Up @@ -170,7 +176,18 @@ var _ = Describe("Sync routine tests", func() {
Expect(fakeIpamServer.isIPAvailable(netip.MustParseAddr("10.0.0.3"), netip.MustParsePrefix("10.0.0.0/24"))).To(Equal(false))
Expect(fakeIpamServer.isIPAvailable(netip.MustParseAddr("10.0.0.4"), netip.MustParsePrefix("10.0.0.0/24"))).To(Equal(false))

time.Sleep(syncGracePeriod)
newCreationTimestamp := time.Now().Add(-syncGracePeriod)
Expect(fakeIpamServer.IpamCore.IPSetCreationTimestamp(
netip.MustParseAddr("10.0.0.0"), netip.MustParsePrefix("10.0.0.0/24"), newCreationTimestamp)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.IPSetCreationTimestamp(
netip.MustParseAddr("10.0.0.1"), netip.MustParsePrefix("10.0.0.0/24"), newCreationTimestamp)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.IPSetCreationTimestamp(
netip.MustParseAddr("10.0.0.2"), netip.MustParsePrefix("10.0.0.0/24"), newCreationTimestamp)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.IPSetCreationTimestamp(
netip.MustParseAddr("10.0.0.3"), netip.MustParsePrefix("10.0.0.0/24"), newCreationTimestamp)).Should(Succeed())
Expect(fakeIpamServer.IpamCore.IPSetCreationTimestamp(
netip.MustParseAddr("10.0.0.4"), netip.MustParsePrefix("10.0.0.0/24"), newCreationTimestamp)).Should(Succeed())

// Run sync
Expect(fakeIpamServer.syncIPs(ctx)).To(Succeed())

Expand Down

0 comments on commit b3c8ee2

Please sign in to comment.