@@ -22,12 +22,14 @@ import (
22
22
"fmt"
23
23
24
24
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/external"
25
+ "golang.org/x/exp/slices"
25
26
corev1 "k8s.io/api/core/v1"
26
27
apierrors "k8s.io/apimachinery/pkg/api/errors"
27
28
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
29
"k8s.io/apimachinery/pkg/runtime"
29
30
"k8s.io/client-go/tools/record"
30
31
"k8s.io/utils/pointer"
32
+ "k8s.io/utils/set"
31
33
ipamv1 "sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1"
32
34
"sigs.k8s.io/cluster-api/util/patch"
33
35
ctrl "sigs.k8s.io/controller-runtime"
@@ -60,6 +62,7 @@ type OpenStackFloatingIPPoolReconciler struct {
60
62
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=openstackfloatingippools/status,verbs=get;update;patch
61
63
// +kubebuilder:rbac:groups=ipam.cluster.x-k8s.io,resources=ipaddressclaims;ipaddressclaims/status,verbs=get;list;watch;update;create;delete
62
64
// +kubebuilder:rbac:groups=ipam.cluster.x-k8s.io,resources=ipaddresses;ipaddresses/status,verbs=get;list;watch;create;update;delete
65
+
63
66
func (r * OpenStackFloatingIPPoolReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (_ ctrl.Result , reterr error ) {
64
67
log := ctrl .LoggerFrom (ctx )
65
68
pool := & infrav1.OpenStackFloatingIPPool {}
@@ -95,6 +98,9 @@ func (r *OpenStackFloatingIPPoolReconciler) Reconcile(ctx context.Context, req c
95
98
}
96
99
}()
97
100
101
+ set := set .New (pool .Spec .PreAllocatedFloatingIPs ... )
102
+ fmt .Println (set )
103
+
98
104
if err := r .reconcileFloatingIPNetwork (scope , pool ); err != nil {
99
105
return ctrl.Result {}, err
100
106
}
@@ -194,7 +200,7 @@ func (r *OpenStackFloatingIPPoolReconciler) reconcileDelete(ctx context.Context,
194
200
}
195
201
196
202
// Clean up ips created by the pool
197
- for _ , ip := range diff (pool .Status .IPs , pool .Spec .PreAllocatedFloatingIPs ) {
203
+ for _ , ip := range set . New (pool .Status .AllIPs ... ). Difference ( set . New ( pool .Spec .PreAllocatedFloatingIPs ... )). SortedList ( ) {
198
204
if err := networkingService .DeleteFloatingIP (pool , ip ); err != nil {
199
205
return fmt .Errorf ("delete floating IP: %w" , err )
200
206
}
@@ -207,49 +213,21 @@ func (r *OpenStackFloatingIPPoolReconciler) reconcileDelete(ctx context.Context,
207
213
return nil
208
214
}
209
215
210
- func union (a []string , b []string ) []string {
211
- m := make (map [string ]struct {})
212
- for _ , item := range a {
213
- m [item ] = struct {}{}
214
- }
215
- for _ , item := range b {
216
- m [item ] = struct {}{}
217
- }
218
- result := make ([]string , 0 , len (m ))
219
- for item := range m {
220
- result = append (result , item )
221
- }
222
- return result
223
- }
224
-
225
- func diff (a []string , b []string ) []string {
226
- m := make (map [string ]struct {})
227
- for _ , item := range a {
228
- m [item ] = struct {}{}
229
- }
230
- for _ , item := range b {
231
- delete (m , item )
232
- }
233
- result := make ([]string , 0 , len (m ))
234
- for item := range m {
235
- result = append (result , item )
236
- }
237
- return result
238
- }
239
-
240
216
func (r * OpenStackFloatingIPPoolReconciler ) setIPStatuses (ctx context.Context , pool * infrav1.OpenStackFloatingIPPool ) error {
241
217
ipAddresses := & ipamv1.IPAddressList {}
242
218
if err := r .Client .List (ctx , ipAddresses , client .InNamespace (pool .Namespace ), client.MatchingFields {infrav1 .OpenStackFloatingIPPoolNameIndex : pool .Name }); err != nil {
243
219
return err
244
220
}
245
- pool .Status .ClaimedIPs = []string {}
221
+ pool .Status .ClaimedIPs = make ( []string , 0 , len ( ipAddresses . Items ))
246
222
for _ , ip := range ipAddresses .Items {
247
223
pool .Status .ClaimedIPs = append (pool .Status .ClaimedIPs , ip .Spec .Address )
248
224
}
249
- pool .Status .IPs = append ([] string {}, pool .Spec .PreAllocatedFloatingIPs ... )
225
+ pool .Status .AllIPs = slices . Clone ( pool .Spec .PreAllocatedFloatingIPs )
250
226
251
- pool .Status .IPs = union (pool .Status .IPs , pool .Status .ClaimedIPs )
252
- pool .Status .AvailableIPs = diff (diff (pool .Status .IPs , pool .Status .ClaimedIPs ), pool .Status .FailedIPs )
227
+ pool .Status .AllIPs = set .New (pool .Status .AllIPs ... ).Union (set .New (pool .Status .ClaimedIPs ... )).SortedList ()
228
+ pool .Status .FailedIPs = set .New (pool .Status .FailedIPs ... ).Difference (set .New (pool .Status .AllIPs ... )).SortedList ()
229
+ unclaimedIps := set .New (pool .Status .AllIPs ... ).Difference (set .New (pool .Status .ClaimedIPs ... ))
230
+ pool .Status .AvailableIPs = unclaimedIps .Difference (set .New (pool .Status .FailedIPs ... )).SortedList ()
253
231
return nil
254
232
}
255
233
@@ -273,20 +251,14 @@ func (r *OpenStackFloatingIPPoolReconciler) getIP(scope scope.Scope, pool *infra
273
251
if err != nil {
274
252
return "" , fmt .Errorf ("get floating IP: %w" , err )
275
253
}
276
- // If the IP exist return it, else we continue and try to allocate it if we fail to allocate it we will mark it as failed
277
254
if fp != nil {
278
255
return fp .FloatingIP , nil
279
256
}
280
257
}
281
258
282
- // ip could be empty meaning we want to get a new one or the IP
283
- // if ip is not empty it got and ip from availableIPs that does not exist in openstack
284
- // we try to allocate it, if we fail we mark it as failed and skip it next time
285
- fp , err := networkingService .CreateFloatingIPForPool (pool , ip )
259
+ fp , err := networkingService .CreateFloatingIPForPool (pool , "" )
286
260
if err != nil {
287
- scope .Logger ().Error (err , "Failed to create floating IP" , "pool" , pool .Name , "ip" , ip )
288
- // If we tried to allocate a specific IP, we should mark it as failed so we don't try again
289
- // this should only happen if the pool thinks this IP is available and we do not have permission to allocate a specific IP
261
+ scope .Logger ().Error (err , "Failed to create floating IP" , "pool" , pool .Name )
290
262
if ip != "" {
291
263
pool .Status .FailedIPs = append (pool .Status .FailedIPs , ip )
292
264
}
@@ -295,7 +267,7 @@ func (r *OpenStackFloatingIPPoolReconciler) getIP(scope scope.Scope, pool *infra
295
267
296
268
ip = fp .FloatingIP
297
269
pool .Status .ClaimedIPs = append (pool .Status .ClaimedIPs , ip )
298
- pool .Status .IPs = append (pool .Status .IPs , ip )
270
+ pool .Status .AllIPs = append (pool .Status .AllIPs , ip )
299
271
return ip , nil
300
272
}
301
273
@@ -323,12 +295,11 @@ func (r *OpenStackFloatingIPPoolReconciler) reconcileFloatingIPNetwork(scope sco
323
295
return fmt .Errorf ("found multiple networks, expects filter to match one (result: %v)" , networkList )
324
296
}
325
297
326
- if pool .Status .FloatingIPNetwork == nil {
327
- pool .Status .FloatingIPNetwork = & infrav1.NetworkStatus {}
298
+ pool .Status .FloatingIPNetwork = & infrav1.NetworkStatus {
299
+ ID : networkList [0 ].ID ,
300
+ Name : networkList [0 ].Name ,
301
+ Tags : networkList [0 ].Tags ,
328
302
}
329
- pool .Status .FloatingIPNetwork .ID = networkList [0 ].ID
330
- pool .Status .FloatingIPNetwork .Name = networkList [0 ].Name
331
- pool .Status .FloatingIPNetwork .Tags = networkList [0 ].Tags
332
303
return nil
333
304
}
334
305
0 commit comments