@@ -25,7 +25,6 @@ import (
2525
2626 "github.com/IBM/vpc-go-sdk/vpcv1"
2727
28- corev1 "k8s.io/api/core/v1"
2928 apierrors "k8s.io/apimachinery/pkg/api/errors"
3029 "k8s.io/apimachinery/pkg/runtime"
3130 "k8s.io/client-go/tools/record"
@@ -35,11 +34,14 @@ import (
3534 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
3635
3736 capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
37+ capierrors "sigs.k8s.io/cluster-api/errors"
3838 "sigs.k8s.io/cluster-api/util"
39+ "sigs.k8s.io/cluster-api/util/conditions"
3940
4041 infrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
4142 "sigs.k8s.io/cluster-api-provider-ibmcloud/cloud/scope"
4243 "sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/endpoints"
44+ capibmrecord "sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/record"
4345)
4446
4547// IBMVPCMachineReconciler reconciles a IBMVPCMachine object.
@@ -139,7 +141,7 @@ func (r *IBMVPCMachineReconciler) SetupWithManager(mgr ctrl.Manager) error {
139141 Complete (r )
140142}
141143
142- func (r * IBMVPCMachineReconciler ) reconcileNormal (machineScope * scope.MachineScope ) (ctrl.Result , error ) {
144+ func (r * IBMVPCMachineReconciler ) reconcileNormal (machineScope * scope.MachineScope ) (ctrl.Result , error ) { //nolint:gocyclo
143145 if controllerutil .AddFinalizer (machineScope .IBMVPCMachine , infrav1beta2 .MachineFinalizer ) {
144146 return ctrl.Result {}, nil
145147 }
@@ -161,14 +163,79 @@ func (r *IBMVPCMachineReconciler) reconcileNormal(machineScope *scope.MachineSco
161163 return ctrl.Result {}, fmt .Errorf ("failed to reconcile VSI for IBMVPCMachine %s/%s: %w" , machineScope .IBMVPCMachine .Namespace , machineScope .IBMVPCMachine .Name , err )
162164 }
163165
166+ machineRunning := false
164167 if instance != nil {
165- machineScope .IBMVPCMachine .Status .InstanceID = * instance .ID
166- machineScope .IBMVPCMachine .Status .Addresses = []corev1.NodeAddress {
167- {
168- Type : corev1 .NodeInternalIP ,
169- Address : * instance .PrimaryNetworkInterface .PrimaryIP .Address ,
170- },
168+ // Attempt to tag the Instance.
169+ if err := machineScope .TagResource (machineScope .IBMVPCCluster .Name , * instance .CRN ); err != nil {
170+ return ctrl.Result {}, fmt .Errorf ("error failed to tag machine: %w" , err )
171171 }
172+
173+ // Set available status' for Machine.
174+ machineScope .SetInstanceID (* instance .ID )
175+ if err := machineScope .SetProviderID (instance .ID ); err != nil {
176+ return ctrl.Result {}, fmt .Errorf ("error failed to set machine provider id: %w" , err )
177+ }
178+ machineScope .SetAddresses (instance )
179+ machineScope .SetInstanceStatus (* instance .Status )
180+
181+ // Depending on the state of the Machine, update status, conditions, etc.
182+ switch machineScope .GetInstanceStatus () {
183+ case vpcv1 .InstanceStatusPendingConst :
184+ machineScope .SetNotReady ()
185+ conditions .MarkFalse (machineScope .IBMVPCMachine , infrav1beta2 .InstanceReadyCondition , infrav1beta2 .InstanceNotReadyReason , capiv1beta1 .ConditionSeverityWarning , "" )
186+ case vpcv1 .InstanceStatusStoppedConst :
187+ machineScope .SetNotReady ()
188+ conditions .MarkFalse (machineScope .IBMVPCMachine , infrav1beta2 .InstanceReadyCondition , infrav1beta2 .InstanceStoppedReason , capiv1beta1 .ConditionSeverityError , "" )
189+ case vpcv1 .InstanceStatusFailedConst :
190+ msg := ""
191+ healthReasonsLen := len (instance .HealthReasons )
192+ if healthReasonsLen > 0 {
193+ // Create a failure message using the last entry's Code and Message fields.
194+ // TODO(cjschaef): Consider adding the MoreInfo field as well, as it contains a link to IBM Cloud docs.
195+ msg = fmt .Sprintf ("%s: %s" , * instance .HealthReasons [healthReasonsLen - 1 ].Code , * instance .HealthReasons [healthReasonsLen - 1 ].Message )
196+ }
197+ machineScope .SetNotReady ()
198+ machineScope .SetFailureReason (capierrors .UpdateMachineError )
199+ machineScope .SetFailureMessage (msg )
200+ conditions .MarkFalse (machineScope .IBMVPCMachine , infrav1beta2 .InstanceReadyCondition , infrav1beta2 .InstanceErroredReason , capiv1beta1 .ConditionSeverityError , "%s" , msg )
201+ capibmrecord .Warnf (machineScope .IBMVPCMachine , "FailedBuildInstance" , "Failed to build the instance - %s" , msg )
202+ return ctrl.Result {}, nil
203+ case vpcv1 .InstanceStatusRunningConst :
204+ machineRunning = true
205+ default :
206+ machineScope .SetNotReady ()
207+ machineScope .V (3 ).Info ("unexpected vpc instance status" , "instanceStatus" , * instance .Status , "instanceID" , machineScope .GetInstanceID ())
208+ conditions .MarkUnknown (machineScope .IBMVPCMachine , infrav1beta2 .InstanceReadyCondition , "" , "" )
209+ }
210+ } else {
211+ machineScope .SetNotReady ()
212+ conditions .MarkUnknown (machineScope .IBMVPCMachine , infrav1beta2 .InstanceReadyCondition , infrav1beta2 .InstanceStateUnknownReason , "" )
213+ }
214+
215+ // Check if the Machine is running.
216+ if ! machineRunning {
217+ // Requeue after 1 minute if machine is not running.
218+ return ctrl.Result {RequeueAfter : 1 * time .Minute }, nil
219+ }
220+
221+ // Rely on defined VPC Load Balancer Pool Members first before falling back to hardcoded defaults.
222+ if len (machineScope .IBMVPCMachine .Spec .LoadBalancerPoolMembers ) > 0 {
223+ needsRequeue := false
224+ for _ , poolMember := range machineScope .IBMVPCMachine .Spec .LoadBalancerPoolMembers {
225+ requeue , err := machineScope .ReconcileVPCLoadBalancerPoolMember (poolMember )
226+ if err != nil {
227+ return ctrl.Result {}, fmt .Errorf ("error failed to reconcile machine's pool member: %w" , err )
228+ } else if requeue {
229+ needsRequeue = true
230+ }
231+ }
232+
233+ // If any VPC Load Balancer Pool Member needs reconciliation, requeue.
234+ if needsRequeue {
235+ return ctrl.Result {RequeueAfter : 1 * time .Minute }, nil
236+ }
237+ } else {
238+ // Otherwise, default to previous Load Balancer Pool Member configuration.
172239 _ , ok := machineScope .IBMVPCMachine .Labels [capiv1beta1 .MachineControlPlaneNameLabel ]
173240 if err = machineScope .SetProviderID (instance .ID ); err != nil {
174241 return ctrl.Result {}, fmt .Errorf ("failed to set provider id IBMVPCMachine %s/%s: %w" , machineScope .IBMVPCMachine .Namespace , machineScope .IBMVPCMachine .Name , err )
@@ -187,9 +254,11 @@ func (r *IBMVPCMachineReconciler) reconcileNormal(machineScope *scope.MachineSco
187254 return ctrl.Result {RequeueAfter : 1 * time .Minute }, nil
188255 }
189256 }
190- machineScope .IBMVPCMachine .Status .Ready = true
191257 }
192258
259+ // With a running machine and all Load Balancer Pool Members reconciled, mark machine as ready.
260+ machineScope .SetReady ()
261+ conditions .MarkTrue (machineScope .IBMVPCMachine , infrav1beta2 .InstanceReadyCondition )
193262 return ctrl.Result {}, nil
194263}
195264
0 commit comments