@@ -11,6 +11,7 @@ import (
1111
1212 "github.com/IBM/vpc-go-sdk/vpcv1"
1313 "github.com/sirupsen/logrus"
14+ corev1 "k8s.io/api/core/v1"
1415 "k8s.io/apimachinery/pkg/util/sets"
1516 "k8s.io/apimachinery/pkg/util/wait"
1617 "k8s.io/utils/ptr"
@@ -280,10 +281,50 @@ func (p Provider) InfraReady(ctx context.Context, in clusterapi.InfraReadyInput)
280281 return nil
281282}
282283
284+ func findMachineAddress (ctx context.Context , in clusterapi.PostProvisionInput , key crclient.ObjectKey ) (string , error ) {
285+ powerVSMachine := & capibm.IBMPowerVSMachine {}
286+
287+ // Get the machine address
288+ // Unfortunately https://pkg.go.dev/k8s.io/apimachinery/pkg/util/wait#PollUntilContextCancel
289+ // can only return a bool. It would be nice if it could return a pointer.
290+ if err := wait .PollUntilContextCancel (ctx , time .Second * 10 ,
291+ false ,
292+ func (ctx context.Context ) (bool , error ) {
293+ if err := in .Client .Get (ctx , key , powerVSMachine ); err != nil {
294+ return false , fmt .Errorf ("failed to get PowerVS machine in PostProvision: %w" , err )
295+ }
296+
297+ for _ , address := range powerVSMachine .Status .Addresses {
298+ if address .Type == corev1 .NodeInternalIP {
299+ logrus .Debugf ("PostProvision: found %s address %s" , key .Name , address .Address )
300+ return true , nil
301+ }
302+ }
303+
304+ logrus .Debugf ("PostProvision: waiting for %s machine" , key .Name )
305+ return false , nil
306+ }); err != nil {
307+ return "" , err
308+ }
309+
310+ if err := in .Client .Get (ctx , key , powerVSMachine ); err != nil {
311+ return "" , fmt .Errorf ("failed to get PowerVS machine in PostProvision: %w" , err )
312+ }
313+
314+ for _ , address := range powerVSMachine .Status .Addresses {
315+ if address .Type == corev1 .NodeInternalIP {
316+ return address .Address , nil
317+ }
318+ }
319+
320+ return "" , fmt .Errorf ("failed to get machine %s IP address" , key .Name )
321+ }
322+
283323// PostProvision should be called to add or update PowerVS resources after provisioning has completed.
284324func (p Provider ) PostProvision (ctx context.Context , in clusterapi.PostProvisionInput ) error {
285325 var (
286326 client * powervsconfig.Client
327+ ipAddr string
287328 refServiceInstance * capibm.IBMPowerVSResourceReference
288329 sshKeyName string
289330 err error
@@ -300,22 +341,52 @@ func (p Provider) PostProvision(ctx context.Context, in clusterapi.PostProvision
300341 logrus .Debugf ("PostProvision: NewClient returns %+v" , client )
301342
302343 // Step 1.
303- // Create worker ssh key
344+ // Wait until bootstrap and master nodes have IP addresses. This will verify
345+ // that the Transit Gateway and DHCP server work correctly before continuing on.
346+
347+ // Get master IP addresses
348+ masterCount := int64 (1 )
349+ if reps := in .InstallConfig .Config .ControlPlane .Replicas ; reps != nil {
350+ masterCount = * reps
351+ }
352+ logrus .Debugf ("PostProvision: masterCount = %d" , masterCount )
353+ for i := int64 (0 ); i < masterCount ; i ++ {
354+ key := crclient.ObjectKey {
355+ Name : fmt .Sprintf ("%s-master-%d" , in .InfraID , i ),
356+ Namespace : capiutils .Namespace ,
357+ }
358+ if ipAddr , err = findMachineAddress (ctx , in , key ); err != nil {
359+ return err
360+ }
361+ logrus .Debugf ("PostProvision: %s ipAddr = %v" , key .Name , ipAddr )
362+ }
363+
304364 // Get the bootstrap machine from the provider
305365 key := crclient.ObjectKey {
306366 Name : fmt .Sprintf ("%s-bootstrap" , in .InfraID ),
307367 Namespace : capiutils .Namespace ,
308368 }
309369 logrus .Debugf ("PostProvision: machine key = %+v" , key )
310- powerVSMachine := & capibm.IBMPowerVSMachine {}
311370
312- if err = in .Client .Get (ctx , key , powerVSMachine ); err != nil {
313- return fmt .Errorf ("failed to get PowerVS machine in PostProvision: %w" , err )
371+ // Find its address
372+ if ipAddr , err = findMachineAddress (ctx , in , key ); err != nil {
373+ return err
374+ }
375+ logrus .Debugf ("PostProvision: ipAddr = %v" , ipAddr )
376+
377+ // Get information about it
378+ powerVSMachine := & capibm.IBMPowerVSMachine {}
379+ if err := in .Client .Get (ctx , key , powerVSMachine ); err != nil {
380+ return fmt .Errorf ("failed to get PowerVS bootstrap machine in PostProvision: %w" , err )
314381 }
315382 logrus .Debugf ("PostProvision: machine = %+v" , powerVSMachine )
383+
384+ // Specifically the Power Virtual Server (PVS)
316385 logrus .Debugf ("PostProvision: machine.Spec.ServiceInstance = %+v" , powerVSMachine .Spec .ServiceInstance )
317386 refServiceInstance = powerVSMachine .Spec .ServiceInstance
318387
388+ // Step 2.
389+ // Create worker ssh key in the PVS
319390 if in .InstallConfig .Config .SSHKey == "" {
320391 return fmt .Errorf ("install config's ssh key is empty?" )
321392 }
0 commit comments