@@ -16,19 +16,74 @@ package nodes
16
16
17
17
import (
18
18
"errors"
19
- "math"
20
19
"regexp"
20
+ "sort"
21
21
"strconv"
22
22
"strings"
23
23
24
24
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/lib"
25
-
25
+ "github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/objects"
26
26
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/pkg/utils"
27
27
28
28
"github.com/vmware/alb-sdk/go/models"
29
29
v1 "k8s.io/api/core/v1"
30
30
)
31
31
32
+ func GetStaticRoutesForOtherNodes (aviVrfNode * AviVrfNode , routeId string ) []* models.StaticRoute {
33
+ var staticRouteCopy []* models.StaticRoute
34
+ nodePrefix := lib .GetClusterName () + "-" + routeId
35
+ for i := 0 ; i < len (aviVrfNode .StaticRoutes ); i ++ {
36
+ if routeId == "" || ! strings .HasPrefix (* aviVrfNode .StaticRoutes [i ].RouteID , nodePrefix ) {
37
+ staticRouteCopy = append (staticRouteCopy , aviVrfNode .StaticRoutes [i ])
38
+ }
39
+ }
40
+ return staticRouteCopy
41
+ }
42
+
43
+ func (o * AviObjectGraph ) CheckAndDeduplicateRecords (key string ) {
44
+ aviVrfNodes := o .GetAviVRF ()
45
+ if len (aviVrfNodes ) == 0 {
46
+ return
47
+ }
48
+ // Each AKO should have single VRF node as it deals with single cluster only.
49
+ aviVrfNode := aviVrfNodes [0 ]
50
+
51
+ podCidrNextHopMap := make (map [string ]string )
52
+ hasDuplicateRecords := false
53
+ // Check if duplicate records for staticroutes exist
54
+ for i := 0 ; i < len (aviVrfNode .StaticRoutes ); i ++ {
55
+ _ , ok := podCidrNextHopMap [* aviVrfNode .StaticRoutes [i ].Prefix .IPAddr .Addr ]
56
+ if ok {
57
+ hasDuplicateRecords = true
58
+ break
59
+ } else {
60
+ podCidrNextHopMap [* aviVrfNode .StaticRoutes [i ].Prefix .IPAddr .Addr ] = * aviVrfNode .StaticRoutes [i ].NextHop .Addr
61
+ }
62
+ }
63
+ if ! hasDuplicateRecords {
64
+ return
65
+ }
66
+
67
+ o .Lock .Lock ()
68
+ // Clean VRFCache
69
+ aviVrfNode .Nodes = nil
70
+ aviVrfNode .StaticRoutes = nil
71
+ aviVrfNode .NodeStaticRoutes = nil
72
+
73
+ o .Lock .Unlock ()
74
+
75
+ // send sorted list of nodes from here.
76
+ allNodes := objects .SharedNodeLister ().CopyAllObjects ()
77
+ var nodeNames []string
78
+ for k := range allNodes {
79
+ nodeNames = append (nodeNames , k )
80
+ }
81
+ sort .Strings (nodeNames )
82
+ for _ , nodeKey := range nodeNames {
83
+ o .BuildVRFGraph (key , aviVrfNode .Name , nodeKey , false )
84
+ }
85
+ }
86
+
32
87
// BuildVRFGraph : build vrf graph from k8s nodes
33
88
func (o * AviObjectGraph ) BuildVRFGraph (key , vrfName , nodeName string , deleteFlag bool ) error {
34
89
o .Lock .Lock ()
@@ -45,10 +100,8 @@ func (o *AviObjectGraph) BuildVRFGraph(key, vrfName, nodeName string, deleteFlag
45
100
// Each AKO should have single VRF node as it deals with single cluster only.
46
101
aviVrfNode := aviVrfNodes [0 ]
47
102
48
- routeid := 1
49
103
if len (aviVrfNode .StaticRoutes ) == 0 {
50
104
aviVrfNode .NodeStaticRoutes = make (map [string ]StaticRouteDetails )
51
- aviVrfNode .NodeIds = make (map [int ]struct {})
52
105
}
53
106
var nodeRoutes []* models.StaticRoute
54
107
// For new node addition (coming from ingestion layer), nodes static routes will be attahced at the end
@@ -60,19 +113,22 @@ func (o *AviObjectGraph) BuildVRFGraph(key, vrfName, nodeName string, deleteFlag
60
113
node , err := utils .GetInformers ().NodeInformer .Lister ().Get (nodeName )
61
114
if err != nil {
62
115
utils .AviLog .Errorf ("key: %s, Error in fetching node details: %s: %v" , key , nodeName , err )
116
+ aviVrfNode .StaticRoutes = GetStaticRoutesForOtherNodes (aviVrfNode , nodeStaticRouteDetails .RouteIDPrefix )
117
+ processNodeStaticRouteAndNodeDeletion (nodeName , aviVrfNode )
63
118
return err
64
119
}
120
+ var routeIdPrefix string
65
121
if ok {
66
- routeid = nodeStaticRouteDetails .routeID
122
+ routeIdPrefix = nodeStaticRouteDetails .RouteIDPrefix
67
123
} else {
68
- //O(n) for each node. But it will re-use previous index. So used instead of always incrementing index.
69
- routeid = findFreeRouteId (aviVrfNode .NodeIds )
124
+ routeIdPrefix = lib .Uuid4 ()
70
125
}
71
- aviVrfNode . NodeIds [ routeid ] = struct {}{}
72
- nodeRoutes , err = o .addRouteForNode (node , vrfName , routeid , aviVrfNode . NodeIds )
126
+
127
+ nodeRoutes , err = o .addRouteForNode (node , vrfName , routeIdPrefix )
73
128
if err != nil {
74
129
utils .AviLog .Errorf ("key: %s, Error Adding vrf for node %s: %v" , key , nodeName , err )
75
- delete (aviVrfNode .NodeIds , routeid )
130
+ aviVrfNode .StaticRoutes = GetStaticRoutesForOtherNodes (aviVrfNode , routeIdPrefix )
131
+ processNodeStaticRouteAndNodeDeletion (nodeName , aviVrfNode )
76
132
return err
77
133
}
78
134
if ! ok {
@@ -81,62 +137,45 @@ func (o *AviObjectGraph) BuildVRFGraph(key, vrfName, nodeName string, deleteFlag
81
137
// node is not present and no overlapping of cidr, append at last
82
138
aviVrfNode .StaticRoutes = append (aviVrfNode .StaticRoutes , nodeRoutes ... )
83
139
nodeStaticRoute := StaticRouteDetails {}
84
- // start index shows at what index of StaticRoutes, nodes routes start (index based zero)
85
- nodeStaticRoute .StartIndex = routeid - 1
86
140
nodeStaticRoute .Count = len (nodeRoutes )
87
- nodeStaticRoute .routeID = routeid
141
+ nodeStaticRoute .RouteIDPrefix = routeIdPrefix
88
142
aviVrfNode .NodeStaticRoutes [nodeName ] = nodeStaticRoute
89
143
aviVrfNode .Nodes = append (aviVrfNode .Nodes , nodeName )
90
144
} else {
91
145
if len (nodeRoutes ) == 0 {
92
- delete (aviVrfNode .NodeIds , routeid )
146
+ //delete all the routes and details of this node
147
+ aviVrfNode .StaticRoutes = GetStaticRoutesForOtherNodes (aviVrfNode , routeIdPrefix )
148
+ processNodeStaticRouteAndNodeDeletion (nodeName , aviVrfNode )
93
149
}
94
150
}
95
151
} else {
96
152
// update case
97
- // Assumption: updated routes (values) for given node will not overlap with other nodes.
153
+ // Assumption: updated routes (values) for given node will not overlap with other nodes
98
154
// So only updating existing routes of that node.
99
155
utils .AviLog .Debugf ("key: %s, StaticRoutes before updation/deletion: [%v]" , key , utils .Stringify (aviVrfNode .StaticRoutes ))
100
- startIndex := nodeStaticRouteDetails .StartIndex
101
156
lenNewNodeRoutes := len (nodeRoutes )
102
157
diff := lenNewNodeRoutes - nodeStaticRouteDetails .Count
103
158
104
- var staticRouteCopy []* models.StaticRoute
105
- copyTill := int (math .Min (float64 (startIndex ), float64 (len (aviVrfNode .StaticRoutes ))))
106
- staticRouteCopy = append (staticRouteCopy , aviVrfNode .StaticRoutes [:copyTill ]... )
107
-
159
+ staticRouteCopy := GetStaticRoutesForOtherNodes (aviVrfNode , routeIdPrefix )
108
160
staticRouteCopy = append (staticRouteCopy , nodeRoutes ... )
109
-
110
- copyFrom := int (math .Min (float64 (startIndex + nodeStaticRouteDetails .Count ), float64 (len (aviVrfNode .StaticRoutes ))))
111
- staticRouteCopy = append (staticRouteCopy , aviVrfNode .StaticRoutes [copyFrom :]... )
112
-
113
161
aviVrfNode .StaticRoutes = staticRouteCopy
114
162
115
163
//if diff is 0, there is no change in number of routes previously exist and newly created.
116
164
if diff != 0 {
117
- updateNodeStaticRoutes (aviVrfNode , deleteFlag , nodeName , lenNewNodeRoutes , diff )
165
+ //update all the routes of this node
166
+ updateNodeStaticRoutes (aviVrfNode , deleteFlag , nodeName , lenNewNodeRoutes )
118
167
}
119
168
if lenNewNodeRoutes == 0 {
120
- processNodeStaticRouteAndNodeIdDeletion (nodeName , aviVrfNode )
169
+ //delete all the routes of this node
170
+ processNodeStaticRouteAndNodeDeletion (nodeName , aviVrfNode )
121
171
}
122
172
utils .AviLog .Debugf ("key: %s, StaticRoutes after updation/deletion: [%v]" , key , utils .Stringify (aviVrfNode .StaticRoutes ))
123
173
}
124
174
} else {
125
- //delete case
175
+ //delete flag is turned on and node is deleted
126
176
utils .AviLog .Debugf ("key: %s, StaticRoutes before deletion: [%v]" , key , utils .Stringify (aviVrfNode .StaticRoutes ))
127
- startIndex := nodeStaticRouteDetails .StartIndex
128
- count := nodeStaticRouteDetails .Count
129
- var staticRouteCopy []* models.StaticRoute
130
- updateNodeStaticRoutes (aviVrfNode , deleteFlag , nodeName , 0 , - count )
131
-
132
- copyTill := int (math .Min (float64 (startIndex ), float64 (len (aviVrfNode .StaticRoutes ))))
133
- staticRouteCopy = append (staticRouteCopy , aviVrfNode .StaticRoutes [:copyTill ]... )
134
-
135
- copyFrom := int (math .Min (float64 (startIndex + nodeStaticRouteDetails .Count ), float64 (len (aviVrfNode .StaticRoutes ))))
136
- staticRouteCopy = append (staticRouteCopy , aviVrfNode .StaticRoutes [copyFrom :]... )
137
-
138
- aviVrfNode .StaticRoutes = staticRouteCopy
139
- processNodeStaticRouteAndNodeIdDeletion (nodeName , aviVrfNode )
177
+ aviVrfNode .StaticRoutes = GetStaticRoutesForOtherNodes (aviVrfNode , nodeStaticRouteDetails .RouteIDPrefix )
178
+ processNodeStaticRouteAndNodeDeletion (nodeName , aviVrfNode )
140
179
utils .AviLog .Debugf ("key: %s, StaticRoutes after deletion: [%v]" , key , utils .Stringify (aviVrfNode .StaticRoutes ))
141
180
}
142
181
aviVrfNode .CalculateCheckSum ()
@@ -145,29 +184,25 @@ func (o *AviObjectGraph) BuildVRFGraph(key, vrfName, nodeName string, deleteFlag
145
184
utils .AviLog .Debugf ("key: %s, vrf node: [%v]" , key , utils .Stringify (aviVrfNode ))
146
185
return nil
147
186
}
148
- func processNodeStaticRouteAndNodeIdDeletion (nodeName string , aviVrfNode * AviVrfNode ) {
187
+ func processNodeStaticRouteAndNodeDeletion (nodeName string , aviVrfNode * AviVrfNode ) {
149
188
delete (aviVrfNode .NodeStaticRoutes , nodeName )
150
- for nodeId := len (aviVrfNode .NodeIds ); nodeId > len (aviVrfNode .StaticRoutes ); nodeId -- {
151
- delete (aviVrfNode .NodeIds , nodeId )
152
- }
153
- }
154
- func findFreeRouteId (routeIdList map [int ]struct {}) int {
155
- for i := 1 ; i < math .MaxInt32 ; i ++ {
156
- if _ , ok := routeIdList [i ]; ! ok {
157
- return i
189
+ nodesCopy := []string {}
190
+ for _ , node := range aviVrfNode .Nodes {
191
+ if node != nodeName {
192
+ nodesCopy = append (nodesCopy , node )
158
193
}
159
194
}
160
- return - 1
195
+ aviVrfNode . Nodes = nodesCopy
161
196
}
162
- func updateNodeStaticRoutes (aviVrfNode * AviVrfNode , isDelete bool , nodeName string , lenNewNodeRoutes , diff int ) {
197
+
198
+ func updateNodeStaticRoutes (aviVrfNode * AviVrfNode , isDelete bool , nodeNameToUpdate string , lenNewNodeRoutes int ) {
163
199
//get index of nodename in node array
164
200
indexOfNodeUnderUpdation := - 1
165
201
166
202
for i := 0 ; i < len (aviVrfNode .Nodes ); i ++ {
167
- if aviVrfNode .Nodes [i ] == nodeName {
203
+ if aviVrfNode .Nodes [i ] == nodeNameToUpdate {
168
204
indexOfNodeUnderUpdation = i
169
205
if ! isDelete {
170
- nodeNameToUpdate := aviVrfNode .Nodes [indexOfNodeUnderUpdation ]
171
206
nodeDetails := aviVrfNode .NodeStaticRoutes [nodeNameToUpdate ]
172
207
nodeDetails .Count = lenNewNodeRoutes
173
208
aviVrfNode .NodeStaticRoutes [nodeNameToUpdate ] = nodeDetails
@@ -176,32 +211,6 @@ func updateNodeStaticRoutes(aviVrfNode *AviVrfNode, isDelete bool, nodeName stri
176
211
}
177
212
}
178
213
if indexOfNodeUnderUpdation != - 1 {
179
- clusterName := lib .GetClusterName ()
180
- //Change nodemap entries till index
181
- for nodeIndex := len (aviVrfNode .Nodes ) - 1 ; nodeIndex > indexOfNodeUnderUpdation ; nodeIndex -- {
182
- nodeNameToUpdate := aviVrfNode .Nodes [nodeIndex ]
183
- nodeDetails := aviVrfNode .NodeStaticRoutes [nodeNameToUpdate ]
184
- oldStartIndex := nodeDetails .StartIndex
185
- nodeDetails .StartIndex = nodeDetails .StartIndex + diff
186
- nodeDetails .routeID = nodeDetails .StartIndex + 1
187
- aviVrfNode .NodeStaticRoutes [nodeNameToUpdate ] = nodeDetails
188
- newRouteId := nodeDetails .routeID
189
- var tempStartIndex int
190
- if isDelete {
191
- tempStartIndex = oldStartIndex
192
- } else {
193
- tempStartIndex = nodeDetails .StartIndex
194
- }
195
- for staticRouteIndex := tempStartIndex ; staticRouteIndex < nodeDetails .Count + tempStartIndex ; staticRouteIndex ++ {
196
- newRouteName := clusterName + "-" + strconv .Itoa (newRouteId )
197
- if staticRouteIndex > (len (aviVrfNode .StaticRoutes )- 1 ) || staticRouteIndex < 0 {
198
- utils .AviLog .Warnf ("Some StaticRoutes could not be updated." )
199
- continue
200
- }
201
- aviVrfNode .StaticRoutes [staticRouteIndex ].RouteID = & newRouteName
202
- newRouteId ++
203
- }
204
- }
205
214
// lenNewNodeRoutes will be zero if Node exists without any PodCidr/BloackAffinity attached to it.
206
215
if isDelete || lenNewNodeRoutes == 0 {
207
216
// now remove nodename from Nodes list
@@ -226,7 +235,7 @@ func findRoutePrefix(nodeRoutes, aviRoutes []*models.StaticRoute, key string) bo
226
235
return false
227
236
}
228
237
229
- func (o * AviObjectGraph ) addRouteForNode (node * v1.Node , vrfName string , routeid int , routeIdList map [ int ] struct {} ) ([]* models.StaticRoute , error ) {
238
+ func (o * AviObjectGraph ) addRouteForNode (node * v1.Node , vrfName string , routeIdPrefix string ) ([]* models.StaticRoute , error ) {
230
239
var nodeIP , nodeIP6 string
231
240
var nodeRoutes []* models.StaticRoute
232
241
@@ -243,7 +252,7 @@ func (o *AviObjectGraph) addRouteForNode(node *v1.Node, vrfName string, routeid
243
252
utils .AviLog .Errorf ("Error in fetching Pod CIDR for %v: %s" , node .ObjectMeta .Name , err .Error ())
244
253
return nil , errors .New ("podcidr not found" )
245
254
}
246
- for _ , podCIDR := range podCIDRs {
255
+ for index , podCIDR := range podCIDRs {
247
256
podCIDRAndMask := strings .Split (podCIDR , "/" )
248
257
if len (podCIDRAndMask ) != 2 {
249
258
utils .AviLog .Errorf ("Error in splitting Pod CIDR for %v" , node .ObjectMeta .Name )
@@ -273,7 +282,7 @@ func (o *AviObjectGraph) addRouteForNode(node *v1.Node, vrfName string, routeid
273
282
continue
274
283
}
275
284
mask32 := int32 (mask )
276
- routeIDString := clusterName + "-" + strconv .Itoa (routeid )
285
+ routeIDString := clusterName + "-" + routeIdPrefix + "-" + strconv .Itoa (index )
277
286
nodeRoute := models.StaticRoute {
278
287
RouteID : & routeIDString ,
279
288
Prefix : & models.IPAddrPrefix {
@@ -291,8 +300,6 @@ func (o *AviObjectGraph) addRouteForNode(node *v1.Node, vrfName string, routeid
291
300
}
292
301
293
302
nodeRoutes = append (nodeRoutes , & nodeRoute )
294
- routeIdList [routeid ] = struct {}{}
295
- routeid ++
296
303
}
297
304
return nodeRoutes , nil
298
305
}
0 commit comments