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