Skip to content

Commit 01eee75

Browse files
committed
feature: reserve n IPs on Networks
1 parent 137a743 commit 01eee75

File tree

9 files changed

+118
-72
lines changed

9 files changed

+118
-72
lines changed

apis/ipam/v1alpha1/network_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ type NetworkSpec struct {
4040
// CIDR is the desired CIDR for the remote cluster.
4141
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="CIDR field is immutable"
4242
CIDR networkingv1beta1.CIDR `json:"cidr"`
43+
// PreAllocated is the number of IPs to pre-allocate (reserve) in the CIDR, starting from the first IP.
44+
// +kubebuilder:validation:Optional
45+
// +kubebuilder:validation:Minimum=0
46+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Reserved field is immutable"
47+
PreAllocated uint `json:"preAllocated"`
4348
}
4449

4550
// NetworkStatus defines the observed state of Network.

deployments/liqo/charts/liqo-crds/crds/ipam.liqo.io_networks.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ spec:
6060
x-kubernetes-validations:
6161
- message: CIDR field is immutable
6262
rule: self == oldSelf
63+
preAllocated:
64+
description: PreAllocated is the number of IPs to pre-allocate (reserve)
65+
in the CIDR, starting from the first IP.
66+
minimum: 0
67+
type: integer
68+
x-kubernetes-validations:
69+
- message: Reserved field is immutable
70+
rule: self == oldSelf
6371
required:
6472
- cidr
6573
type: object

deployments/liqo/templates/liqo-ipam-networks.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ metadata:
3131
ipam.liqo.io/network-type: external-cidr
3232
spec:
3333
cidr: {{ .Values.ipam.externalCIDR }}
34+
preAllocated: 1 # the first IP of the external CIDR is reserved for the unknown source traffic
3435
---
3536
apiVersion: ipam.liqo.io/v1alpha1
3637
kind: Network

pkg/ipam/ipam.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (lipam *LiqoIPAM) IPRelease(_ context.Context, req *IPReleaseRequest) (*IPR
9090

9191
// NetworkAcquire acquires a network. If it is already reserved, it allocates and reserves a new free one with the same prefix length.
9292
func (lipam *LiqoIPAM) NetworkAcquire(_ context.Context, req *NetworkAcquireRequest) (*NetworkAcquireResponse, error) {
93-
remappedCidr, err := lipam.acquireNetwork(req.GetCidr(), req.GetImmutable())
93+
remappedCidr, err := lipam.acquireNetwork(req.GetCidr(), uint(req.GetPreAllocated()), req.GetImmutable())
9494
if err != nil {
9595
return &NetworkAcquireResponse{}, err
9696
}
@@ -100,14 +100,14 @@ func (lipam *LiqoIPAM) NetworkAcquire(_ context.Context, req *NetworkAcquireRequ
100100

101101
// NetworkRelease releases a network.
102102
func (lipam *LiqoIPAM) NetworkRelease(_ context.Context, req *NetworkReleaseRequest) (*NetworkReleaseResponse, error) {
103-
lipam.freeNetwork(req.GetCidr())
103+
lipam.freeNetwork(network{cidr: req.GetCidr()})
104104

105105
return &NetworkReleaseResponse{}, nil
106106
}
107107

108108
// NetworkIsAvailable checks if a network is available.
109109
func (lipam *LiqoIPAM) NetworkIsAvailable(_ context.Context, req *NetworkAvailableRequest) (*NetworkAvailableResponse, error) {
110-
available := lipam.isNetworkAvailable(req.GetCidr())
110+
available := lipam.isNetworkAvailable(network{cidr: req.GetCidr()})
111111

112112
return &NetworkAvailableResponse{Available: available}, nil
113113
}

pkg/ipam/ipam.pb.go

Lines changed: 57 additions & 47 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/ipam/ipam.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ message IPReleaseResponse {
3434
message NetworkAcquireRequest {
3535
string cidr = 1;
3636
bool immutable = 2; // If true, the network cannot be remapped. It will be allocated if available, or an error will be returned.
37+
uint32 preAllocated = 3; // The number of IPs to pre-allocate (reserve) in the CIDR, starting from the first IP of the CIDR.
3738
}
3839

3940
message NetworkAcquireResponse {

pkg/ipam/networks.go

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,39 @@ import (
2525
)
2626

2727
type networkInfo struct {
28-
cidr string
28+
network
2929
creationTimestamp time.Time
3030
}
3131

32+
type network struct {
33+
cidr string
34+
preAllocated uint
35+
}
36+
37+
func (n network) String() string {
38+
return n.cidr
39+
}
40+
3241
// reserveNetwork reserves a network, saving it in the cache.
33-
func (lipam *LiqoIPAM) reserveNetwork(cidr string) error {
42+
func (lipam *LiqoIPAM) reserveNetwork(nw network) error {
3443
lipam.mutex.Lock()
3544
defer lipam.mutex.Unlock()
3645

46+
// TODO: implement real network reserve logic
3747
if lipam.cacheNetworks == nil {
3848
lipam.cacheNetworks = make(map[string]networkInfo)
3949
}
40-
lipam.cacheNetworks[cidr] = networkInfo{
41-
cidr: cidr,
50+
lipam.cacheNetworks[nw.String()] = networkInfo{
51+
network: nw,
4252
creationTimestamp: time.Now(),
4353
}
4454

45-
klog.Infof("Reserved network %q", cidr)
55+
klog.Infof("Reserved network %q", nw)
4656
return nil
4757
}
4858

4959
// acquireNetwork acquires a network, eventually remapped if conflicts are found.
50-
func (lipam *LiqoIPAM) acquireNetwork(cidr string, immutable bool) (string, error) {
60+
func (lipam *LiqoIPAM) acquireNetwork(cidr string, preAllocated uint, immutable bool) (string, error) {
5161
lipam.mutex.Lock()
5262
defer lipam.mutex.Unlock()
5363

@@ -56,39 +66,45 @@ func (lipam *LiqoIPAM) acquireNetwork(cidr string, immutable bool) (string, erro
5666
if lipam.cacheNetworks == nil {
5767
lipam.cacheNetworks = make(map[string]networkInfo)
5868
}
59-
lipam.cacheNetworks[cidr] = networkInfo{
60-
cidr: cidr,
69+
nw := network{
70+
cidr: cidr,
71+
preAllocated: preAllocated,
72+
}
73+
lipam.cacheNetworks[nw.String()] = networkInfo{
74+
network: nw,
6175
creationTimestamp: time.Now(),
6276
}
6377

64-
klog.Infof("Acquired network %q", cidr)
65-
return cidr, nil
78+
klog.Infof("Acquired network %q", nw)
79+
return nw.cidr, nil
6680
}
6781

6882
// freeNetwork frees a network, removing it from the cache.
69-
func (lipam *LiqoIPAM) freeNetwork(cidr string) {
83+
func (lipam *LiqoIPAM) freeNetwork(nw network) {
7084
lipam.mutex.Lock()
7185
defer lipam.mutex.Unlock()
7286

73-
delete(lipam.cacheNetworks, cidr)
74-
klog.Infof("Freed network %q", cidr)
87+
// TODO: implement real network free logic
88+
delete(lipam.cacheNetworks, nw.String())
89+
klog.Infof("Freed network %q", nw.cidr)
7590
}
7691

7792
// isNetworkAvailable checks if a network is available.
78-
func (lipam *LiqoIPAM) isNetworkAvailable(cidr string) bool {
93+
func (lipam *LiqoIPAM) isNetworkAvailable(nw network) bool {
7994
lipam.mutex.Lock()
8095
defer lipam.mutex.Unlock()
8196

97+
// TODO: implement real network availability check logic
8298
if lipam.cacheNetworks == nil {
8399
return true
84100
}
85-
_, ok := lipam.cacheNetworks[cidr]
101+
_, ok := lipam.cacheNetworks[nw.String()]
86102

87103
return ok
88104
}
89105

90-
func listNetworksOnCluster(ctx context.Context, cl client.Client) ([]string, error) {
91-
var nets []string
106+
func listNetworksOnCluster(ctx context.Context, cl client.Client) ([]network, error) {
107+
var nets []network
92108
var networks ipamv1alpha1.NetworkList
93109
if err := cl.List(ctx, &networks); err != nil {
94110
return nil, err
@@ -103,7 +119,10 @@ func listNetworksOnCluster(ctx context.Context, cl client.Client) ([]string, err
103119
continue
104120
}
105121

106-
nets = append(nets, cidr)
122+
nets = append(nets, network{
123+
cidr: cidr,
124+
preAllocated: net.Spec.PreAllocated,
125+
})
107126
}
108127

109128
return nets, nil

pkg/ipam/sync.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,18 @@ func (lipam *LiqoIPAM) syncNetworks(ctx context.Context, expiredThreshold time.T
6565

6666
// Add networks that are present in the cluster but not in the cache.
6767
for _, net := range clusterNetworks {
68-
if _, inCache := lipam.cacheNetworks[net]; !inCache {
68+
if _, inCache := lipam.cacheNetworks[net.String()]; !inCache {
6969
if err := lipam.reserveNetwork(net); err != nil {
7070
return err
7171
}
7272
}
73-
setClusterNetworks[net] = struct{}{} // add network to the set
73+
setClusterNetworks[net.String()] = struct{}{} // add network to the set
7474
}
7575

7676
// Remove networks that are present in the cache but not in the cluster, and were added before the threshold.
7777
for key := range lipam.cacheNetworks {
7878
if _, inCluster := setClusterNetworks[key]; !inCluster && lipam.cacheNetworks[key].creationTimestamp.Before(expiredThreshold) {
79-
lipam.freeNetwork(lipam.cacheNetworks[key].cidr)
79+
lipam.freeNetwork(lipam.cacheNetworks[key].network)
8080
}
8181
}
8282

pkg/ipam/sync_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ var _ = Describe("Sync routine tests", func() {
4545

4646
addNetowrkToCache = func(ipamServer *LiqoIPAM, cidr string, creationTimestamp time.Time) {
4747
ipamServer.cacheNetworks[cidr] = networkInfo{
48-
cidr: cidr,
48+
network: network{
49+
cidr: cidr,
50+
},
4951
creationTimestamp: creationTimestamp,
5052
}
5153
}

0 commit comments

Comments
 (0)