@@ -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,33 @@ 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
+ // TODO(emilien) maybe we want to set PortsStatus in OpenStackMachineStatus here instead of in port.go?
469
+ // Major difference of doing it in port.go is that we can add ports one by one into the status instead of all at once in the controller.
470
+
471
+ return portsStatus , nil
472
+ }
473
+
474
+ 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
475
instanceStatus , err := computeService .GetInstanceStatusByName (openStackMachine , openStackMachine .Name )
435
476
if err != nil {
436
477
logger .Info ("Unable to get OpenStack instance" , "name" , openStackMachine .Name )
@@ -441,7 +482,7 @@ func (r *OpenStackMachineReconciler) getOrCreate(logger logr.Logger, cluster *cl
441
482
if instanceStatus == nil {
442
483
instanceSpec := machineToInstanceSpec (openStackCluster , machine , openStackMachine , userData )
443
484
logger .Info ("Machine does not exist, creating Machine" , "name" , openStackMachine .Name )
444
- instanceStatus , err = computeService .CreateInstance (openStackMachine , openStackCluster , instanceSpec , cluster .Name )
485
+ instanceStatus , err = computeService .CreateInstance (openStackMachine , openStackCluster , instanceSpec , cluster .Name , portIDs )
445
486
if err != nil {
446
487
conditions .MarkFalse (openStackMachine , infrav1 .InstanceReadyCondition , infrav1 .InstanceCreateFailedReason , clusterv1 .ConditionSeverityError , err .Error ())
447
488
return nil , fmt .Errorf ("create OpenStack instance: %w" , err )
@@ -472,6 +513,19 @@ func machineToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, machine *
472
513
instanceSpec .FailureDomain = * machine .Spec .FailureDomain
473
514
}
474
515
516
+ instanceSpec .Tags = getInstanceTags (openStackMachine , openStackCluster )
517
+
518
+ instanceSpec .SecurityGroups = getManagedSecurityGroups (openStackCluster , machine , openStackMachine )
519
+
520
+ instanceSpec .Ports = openStackMachine .Spec .Ports
521
+
522
+ return & instanceSpec
523
+ }
524
+
525
+ // getInstanceTags returns the tags that should be applied to the instance.
526
+ // The tags are a combination of the tags specified on the OpenStackMachine and
527
+ // the ones specified on the OpenStackCluster.
528
+ func getInstanceTags (openStackMachine * infrav1.OpenStackMachine , openStackCluster * infrav1.OpenStackCluster ) []string {
475
529
machineTags := []string {}
476
530
477
531
// Append machine specific tags
@@ -494,31 +548,31 @@ func machineToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, machine *
494
548
}
495
549
machineTags = deduplicate (machineTags )
496
550
497
- instanceSpec .Tags = machineTags
551
+ return machineTags
552
+ }
498
553
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
- }
554
+ // getManagedSecurityGroups returns a combination of OpenStackMachine.Spec.SecurityGroups
555
+ // and the security group managed by the OpenStackCluster whether it's a control plane or a worker machine.
556
+ func getManagedSecurityGroups (openStackCluster * infrav1.OpenStackCluster , machine * clusterv1.Machine , openStackMachine * infrav1.OpenStackMachine ) []infrav1.SecurityGroupFilter {
557
+ machineSpecSecurityGroups := openStackMachine .Spec .SecurityGroups
558
+ var managedSecurityGroup string
559
+ if util .IsControlPlaneMachine (machine ) {
560
+ if openStackCluster .Status .ControlPlaneSecurityGroup != nil {
561
+ managedSecurityGroup = openStackCluster .Status .ControlPlaneSecurityGroup .ID
510
562
}
511
-
512
- if managedSecurityGroup != "" {
513
- instanceSpec .SecurityGroups = append (instanceSpec .SecurityGroups , infrav1.SecurityGroupFilter {
514
- ID : managedSecurityGroup ,
515
- })
563
+ } else {
564
+ if openStackCluster .Status .WorkerSecurityGroup != nil {
565
+ managedSecurityGroup = openStackCluster .Status .WorkerSecurityGroup .ID
516
566
}
517
567
}
518
568
519
- instanceSpec .Ports = openStackMachine .Spec .Ports
569
+ if managedSecurityGroup != "" {
570
+ machineSpecSecurityGroups = append (machineSpecSecurityGroups , infrav1.SecurityGroupFilter {
571
+ ID : managedSecurityGroup ,
572
+ })
573
+ }
520
574
521
- return & instanceSpec
575
+ return machineSpecSecurityGroups
522
576
}
523
577
524
578
func (r * OpenStackMachineReconciler ) reconcileLoadBalancerMember (scope scope.Scope , openStackCluster * infrav1.OpenStackCluster , openStackMachine * infrav1.OpenStackMachine , instanceNS * compute.InstanceNetworkStatus , clusterName string ) error {
0 commit comments