@@ -328,9 +328,24 @@ func (r *OpenStackMachineReconciler) reconcileNormal(ctx context.Context, scope
328
328
return ctrl.Result {}, err
329
329
}
330
330
331
- instanceStatus , err := r .getOrCreate (scope .Logger (), cluster , openStackCluster , machine , openStackMachine , computeService , userData )
331
+ managedSecurityGroups := getManagedSecurityGroups (openStackCluster , machine , openStackMachine )
332
+ instanceTags := getInstanceTags (openStackMachine , openStackCluster )
333
+ portsStatus , err := r .getOrCreatePorts (scope .Logger (), clusterName , openStackCluster , openStackMachine .Spec .Ports , openStackMachine .Spec .Trunk , managedSecurityGroups , instanceTags , openStackMachine .Name , openStackMachine , networkingService )
332
334
if err != nil {
333
- // Conditions set in getOrCreate
335
+ // Conditions set in getOrCreatePorts
336
+ return ctrl.Result {}, err
337
+ }
338
+ // TODO(emilien) do we want to deal with Ports Status like we do for the nova instance? Might be expensive...
339
+ // In the meantime, we consider that ports are ready if they are created.
340
+ conditions .MarkTrue (openStackMachine , infrav1 .PortsReadyCondition )
341
+ portIDs := make ([]string , len (* portsStatus ))
342
+ for i , portStatus := range * portsStatus {
343
+ portIDs [i ] = portStatus .ID
344
+ }
345
+
346
+ instanceStatus , err := r .getOrCreateInstance (scope .Logger (), cluster , openStackCluster , machine , openStackMachine , computeService , userData , portIDs )
347
+ if err != nil {
348
+ // Conditions set in getOrCreateInstance
334
349
return ctrl.Result {}, err
335
350
}
336
351
@@ -430,7 +445,32 @@ func (r *OpenStackMachineReconciler) reconcileNormal(ctx context.Context, scope
430
445
return ctrl.Result {}, nil
431
446
}
432
447
433
- func (r * OpenStackMachineReconciler ) getOrCreate (logger logr.Logger , cluster * clusterv1.Cluster , openStackCluster * infrav1.OpenStackCluster , machine * clusterv1.Machine , openStackMachine * infrav1.OpenStackMachine , computeService * compute.Service , userData string ) (* compute.InstanceStatus , error ) {
448
+ func (r * OpenStackMachineReconciler ) getOrCreatePorts (logger logr.Logger , clusterName string , openStackCluster * infrav1.OpenStackCluster , machinePorts []infrav1.PortOpts , trunkEnabled bool , securityGroups []infrav1.SecurityGroupFilter , instanceTags []string , instanceName string , openStackMachine * infrav1.OpenStackMachine , networkingService * networking.Service ) (* []infrav1.PortStatus , error ) {
449
+ // TODO(emilien) implement portsStatus where we check if the machine has ports created and part of the OpenStackMachine.Status
450
+ // Check `GetInstanceStatusByName` as it's done for instances. For each port found in Status, we might want get the port name and verify there is no duplicate.
451
+ // If Status is empty, we create the ports and add them to the Status.
452
+ // If Status is not empty, we try to adopt the existing ports by checking if the ports are still there and if not, we create them and add them to the Status.
453
+
454
+ // For now, we create the ports.
455
+ var portsStatus * []infrav1.PortStatus
456
+ var err error
457
+
458
+ if openStackMachine .Status .PortsStatus == nil {
459
+ logger .Info ("Creating ports for OpenStackMachine" , "name" , openStackMachine .Name )
460
+ portsStatus , err = networkingService .CreatePorts (openStackMachine , clusterName , openStackCluster , machinePorts , trunkEnabled , securityGroups , instanceTags , instanceName )
461
+ if err != nil {
462
+ // Add Conditions
463
+ conditions .MarkFalse (openStackMachine , infrav1 .PortsReadyCondition , infrav1 .PortsCreateFailedReason , clusterv1 .ConditionSeverityError , err .Error ())
464
+ return nil , fmt .Errorf ("create ports: %w" , err )
465
+ }
466
+ }
467
+
468
+ openStackMachine .Status .PortsStatus = * portsStatus
469
+
470
+ return portsStatus , nil
471
+ }
472
+
473
+ func (r * OpenStackMachineReconciler ) getOrCreateInstance (logger logr.Logger , cluster * clusterv1.Cluster , openStackCluster * infrav1.OpenStackCluster , machine * clusterv1.Machine , openStackMachine * infrav1.OpenStackMachine , computeService * compute.Service , userData string , portIDs []string ) (* compute.InstanceStatus , error ) {
434
474
instanceStatus , err := computeService .GetInstanceStatusByName (openStackMachine , openStackMachine .Name )
435
475
if err != nil {
436
476
logger .Info ("Unable to get OpenStack instance" , "name" , openStackMachine .Name )
@@ -441,7 +481,7 @@ func (r *OpenStackMachineReconciler) getOrCreate(logger logr.Logger, cluster *cl
441
481
if instanceStatus == nil {
442
482
instanceSpec := machineToInstanceSpec (openStackCluster , machine , openStackMachine , userData )
443
483
logger .Info ("Machine does not exist, creating Machine" , "name" , openStackMachine .Name )
444
- instanceStatus , err = computeService .CreateInstance (openStackMachine , openStackCluster , instanceSpec , cluster .Name )
484
+ instanceStatus , err = computeService .CreateInstance (openStackMachine , openStackCluster , instanceSpec , cluster .Name , portIDs )
445
485
if err != nil {
446
486
conditions .MarkFalse (openStackMachine , infrav1 .InstanceReadyCondition , infrav1 .InstanceCreateFailedReason , clusterv1 .ConditionSeverityError , err .Error ())
447
487
return nil , fmt .Errorf ("create OpenStack instance: %w" , err )
@@ -472,6 +512,19 @@ func machineToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, machine *
472
512
instanceSpec .FailureDomain = * machine .Spec .FailureDomain
473
513
}
474
514
515
+ instanceSpec .Tags = getInstanceTags (openStackMachine , openStackCluster )
516
+
517
+ instanceSpec .SecurityGroups = getManagedSecurityGroups (openStackCluster , machine , openStackMachine )
518
+
519
+ instanceSpec .Ports = openStackMachine .Spec .Ports
520
+
521
+ return & instanceSpec
522
+ }
523
+
524
+ // getInstanceTags returns the tags that should be applied to the instance.
525
+ // The tags are a combination of the tags specified on the OpenStackMachine and
526
+ // the ones specified on the OpenStackCluster.
527
+ func getInstanceTags (openStackMachine * infrav1.OpenStackMachine , openStackCluster * infrav1.OpenStackCluster ) []string {
475
528
machineTags := []string {}
476
529
477
530
// Append machine specific tags
@@ -494,31 +547,31 @@ func machineToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, machine *
494
547
}
495
548
machineTags = deduplicate (machineTags )
496
549
497
- instanceSpec .Tags = machineTags
550
+ return machineTags
551
+ }
498
552
499
- instanceSpec .SecurityGroups = openStackMachine .Spec .SecurityGroups
500
- if openStackCluster .Spec .ManagedSecurityGroups {
501
- var managedSecurityGroup string
502
- if util .IsControlPlaneMachine (machine ) {
503
- if openStackCluster .Status .ControlPlaneSecurityGroup != nil {
504
- managedSecurityGroup = openStackCluster .Status .ControlPlaneSecurityGroup .ID
505
- }
506
- } else {
507
- if openStackCluster .Status .WorkerSecurityGroup != nil {
508
- managedSecurityGroup = openStackCluster .Status .WorkerSecurityGroup .ID
509
- }
553
+ // getManagedSecurityGroups returns a combination of OpenStackMachine.Spec.SecurityGroups
554
+ // and the security group managed by the OpenStackCluster whether it's a control plane or a worker machine.
555
+ func getManagedSecurityGroups (openStackCluster * infrav1.OpenStackCluster , machine * clusterv1.Machine , openStackMachine * infrav1.OpenStackMachine ) []infrav1.SecurityGroupFilter {
556
+ machineSpecSecurityGroups := openStackMachine .Spec .SecurityGroups
557
+ var managedSecurityGroup string
558
+ if util .IsControlPlaneMachine (machine ) {
559
+ if openStackCluster .Status .ControlPlaneSecurityGroup != nil {
560
+ managedSecurityGroup = openStackCluster .Status .ControlPlaneSecurityGroup .ID
510
561
}
511
-
512
- if managedSecurityGroup != "" {
513
- instanceSpec .SecurityGroups = append (instanceSpec .SecurityGroups , infrav1.SecurityGroupFilter {
514
- ID : managedSecurityGroup ,
515
- })
562
+ } else {
563
+ if openStackCluster .Status .WorkerSecurityGroup != nil {
564
+ managedSecurityGroup = openStackCluster .Status .WorkerSecurityGroup .ID
516
565
}
517
566
}
518
567
519
- instanceSpec .Ports = openStackMachine .Spec .Ports
568
+ if managedSecurityGroup != "" {
569
+ machineSpecSecurityGroups = append (machineSpecSecurityGroups , infrav1.SecurityGroupFilter {
570
+ ID : managedSecurityGroup ,
571
+ })
572
+ }
520
573
521
- return & instanceSpec
574
+ return machineSpecSecurityGroups
522
575
}
523
576
524
577
func (r * OpenStackMachineReconciler ) reconcileLoadBalancerMember (scope scope.Scope , openStackCluster * infrav1.OpenStackCluster , openStackMachine * infrav1.OpenStackMachine , instanceNS * compute.InstanceNetworkStatus , clusterName string ) error {
0 commit comments