@@ -32,6 +32,13 @@ type Executor struct {
3232 Config * api.MachineProviderConfig
3333}
3434
35+ // CreateMachineResult return a slice of internal IPs under which the machine
36+ // with the given ID is reachable.
37+ type CreateMachineResult struct {
38+ ProviderID string
39+ InternalIPs []string
40+ }
41+
3542// NewExecutor returns a new instance of Executor.
3643func NewExecutor (factory * client.Factory , config * api.MachineProviderConfig ) (* Executor , error ) {
3744 computeClient , err := factory .Compute (client .WithRegion (config .Spec .Region ))
@@ -59,9 +66,41 @@ func NewExecutor(factory *client.Factory, config *api.MachineProviderConfig) (*E
5966 return ex , nil
6067}
6168
69+ // getServerIPs assumes the server has exactly one network interface
70+ // and extracts its internal IP addresses.
71+ func getServerIPs (server * servers.Server ) ([]string , error ) {
72+ ips := make ([]string , 0 )
73+
74+ if len (server .Addresses ) != 1 {
75+ return nil , fmt .Errorf ("expected 1 network, but found %d" , len (server .Addresses ))
76+ }
77+
78+ // Format of the addresses field: https://docs.openstack.org/api-ref/compute/#list-servers-detailed.
79+ for _ , networkAddresses := range server .Addresses {
80+ addrList , ok := networkAddresses .([]any )
81+ if ! ok {
82+ return nil , fmt .Errorf ("could not assert network addresses to slice" )
83+ }
84+
85+ // Iterate through the addresses (may be IPv4, IPv6).
86+ for _ , addrData := range addrList {
87+ addressMap , ok := addrData .(map [string ]any )
88+ if ! ok {
89+ continue
90+ }
91+
92+ if ipAddress , ok := addressMap ["addr" ].(string ); ok {
93+ ips = append (ips , ipAddress )
94+ }
95+ }
96+ }
97+
98+ return ips , nil
99+ }
100+
62101// CreateMachine creates a new OpenStack server instance and waits until it reports "ACTIVE".
63102// If there is an error during the build process, or if the building phase timeouts, it will delete any artifacts created.
64- func (ex * Executor ) CreateMachine (ctx context.Context , machineName string , userData []byte ) (string , error ) {
103+ func (ex * Executor ) CreateMachine (ctx context.Context , machineName string , userData []byte ) (* CreateMachineResult , error ) {
65104 var (
66105 server * servers.Server
67106 err error
@@ -79,30 +118,44 @@ func (ex *Executor) CreateMachine(ctx context.Context, machineName string, userD
79118 if err == nil {
80119 klog .Infof ("found existing server [Name=%q, ID=%q]" , machineName , server .ID )
81120 } else if ! errors .Is (err , ErrNotFound ) {
82- return "" , err
121+ return nil , err
83122 } else {
84123 // clean-up function when creation fails in an intermediate step
85124 serverNetworks , err := ex .resolveServerNetworks (ctx , machineName )
86125 if err != nil {
87- return "" , deleteOnFail (fmt .Errorf ("failed to resolve server [Name=%q] networks: %w" , machineName , err ))
126+ return nil , deleteOnFail (fmt .Errorf ("failed to resolve server [Name=%q] networks: %w" , machineName , err ))
88127 }
89128
90129 server , err = ex .deployServer (ctx , machineName , userData , serverNetworks )
91130 if err != nil {
92- return "" , deleteOnFail (fmt .Errorf ("failed to deploy server [Name=%q]: %w" , machineName , err ))
131+ return nil , deleteOnFail (fmt .Errorf ("failed to deploy server [Name=%q]: %w" , machineName , err ))
93132 }
94133 }
95134
96- err = ex .waitForServerStatus (ctx , server .ID , []string {client .ServerStatusBuild }, []string {client .ServerStatusActive }, 1200 )
135+ // The server information when status is ACTIVE has addresses field populated
136+ var activeServer * servers.Server
137+ activeServer , err = ex .waitForServerStatus (ctx ,
138+ server .ID ,
139+ []string {client .ServerStatusBuild },
140+ []string {client .ServerStatusActive }, 1200 )
97141 if err != nil {
98- return "" , deleteOnFail (fmt .Errorf ("error waiting for server [ID=%q] to reach target status: %w" , server .ID , err ))
142+ return nil , deleteOnFail (fmt .Errorf ("error waiting for server [ID=%q] to reach target status: %w" , server .ID , err ))
99143 }
100144
101- if err := ex .patchServerPortsForPodNetwork (ctx , server .ID ); err != nil {
102- return "" , deleteOnFail (fmt .Errorf ("failed to patch server [ID=%q] ports: %s" , server .ID , err ))
145+ if err := ex .patchServerPortsForPodNetwork (ctx , activeServer .ID ); err != nil {
146+ return nil , deleteOnFail (fmt .Errorf ("failed to patch server [ID=%q] ports: %s" , server .ID , err ))
103147 }
104148
105- return encodeProviderID (ex .Config .Spec .Region , server .ID ), nil
149+ var internalIPs []string
150+ internalIPs , err = getServerIPs (activeServer )
151+ if err != nil {
152+ klog .Infof ("failed to extract internal IPs [ID=%q] ports: %s" , activeServer .ID , err )
153+ }
154+
155+ return & CreateMachineResult {
156+ ProviderID : encodeProviderID (ex .Config .Spec .Region , activeServer .ID ),
157+ InternalIPs : internalIPs ,
158+ }, nil
106159}
107160
108161// resolveServerNetworks resolves the network configuration for the server.
@@ -156,10 +209,11 @@ func (ex *Executor) resolveServerNetworks(ctx context.Context, machineName strin
156209 return serverNetworks , nil
157210}
158211
159- // waitForServerStatus blocks until the server with the specified ID reaches one of the target status.
212+ // waitForServerStatus blocks until the server with the specified ID reaches one of the target status and returns the server after reaching this status .
160213// waitForServerStatus will fail if an error occurs, the operation it timeouts after the specified time, or the server status is not in the pending list.
161- func (ex * Executor ) waitForServerStatus (ctx context.Context , serverID string , pending []string , target []string , secs int ) error {
162- return wait .PollUntilContextTimeout (
214+ func (ex * Executor ) waitForServerStatus (ctx context.Context , serverID string , pending []string , target []string , secs int ) (* servers.Server , error ) {
215+ var server * servers.Server
216+ return server , wait .PollUntilContextTimeout (
163217 ctx ,
164218 10 * time .Second ,
165219 time .Duration (secs )* time .Second ,
@@ -175,6 +229,7 @@ func (ex *Executor) waitForServerStatus(ctx context.Context, serverID string, pe
175229
176230 klog .V (5 ).Infof ("waiting for server [ID=%q] and current status %v, to reach status %v." , serverID , current .Status , target )
177231 if strSliceContains (target , current .Status ) {
232+ server = current
178233 return true , nil
179234 }
180235
@@ -468,7 +523,7 @@ func (ex *Executor) DeleteMachine(ctx context.Context, machineName, providerID s
468523 return err
469524 }
470525
471- if err = ex .waitForServerStatus (ctx , server .ID , nil , []string {client .ServerStatusDeleted }, 1200 ); err != nil {
526+ if _ , err = ex .waitForServerStatus (ctx , server .ID , nil , []string {client .ServerStatusDeleted }, 1200 ); err != nil {
472527 return fmt .Errorf ("error while waiting for server [ID=%q] to be deleted: %v" , server .ID , err )
473528 }
474529 } else if ! errors .Is (err , ErrNotFound ) {
0 commit comments