@@ -32,6 +32,11 @@ type Executor struct {
3232 Config * api.MachineProviderConfig
3333}
3434
35+ type CreateMachineResult struct {
36+ ProviderID string
37+ InternalIPs []string
38+ }
39+
3540// NewExecutor returns a new instance of Executor.
3641func NewExecutor (factory * client.Factory , config * api.MachineProviderConfig ) (* Executor , error ) {
3742 computeClient , err := factory .Compute (client .WithRegion (config .Spec .Region ))
@@ -59,9 +64,41 @@ func NewExecutor(factory *client.Factory, config *api.MachineProviderConfig) (*E
5964 return ex , nil
6065}
6166
67+ // getServerIPs assumes the server has exactly one network interface
68+ // and extracts its internal IP addresses.
69+ func getServerIPs (server * servers.Server ) ([]string , error ) {
70+ ips := make ([]string , 0 )
71+
72+ if len (server .Addresses ) != 1 {
73+ return nil , fmt .Errorf ("expected 1 network, but found %d" , len (server .Addresses ))
74+ }
75+
76+ // Format of the addresses field: https://docs.openstack.org/api-ref/compute/#list-servers-detailed.
77+ for _ , networkAddresses := range server .Addresses {
78+ addrList , ok := networkAddresses .([]any )
79+ if ! ok {
80+ return nil , fmt .Errorf ("could not assert network addresses to slice" )
81+ }
82+
83+ // Iterate through the addresses (may be IPv4, IPv6).
84+ for _ , addrData := range addrList {
85+ addressMap , ok := addrData .(map [string ]any )
86+ if ! ok {
87+ continue
88+ }
89+
90+ if ipAddress , ok := addressMap ["addr" ].(string ); ok {
91+ ips = append (ips , ipAddress )
92+ }
93+ }
94+ }
95+
96+ return ips , nil
97+ }
98+
6299// CreateMachine creates a new OpenStack server instance and waits until it reports "ACTIVE".
63100// 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 ) {
101+ func (ex * Executor ) CreateMachine (ctx context.Context , machineName string , userData []byte ) (* CreateMachineResult , error ) {
65102 var (
66103 server * servers.Server
67104 err error
@@ -79,30 +116,44 @@ func (ex *Executor) CreateMachine(ctx context.Context, machineName string, userD
79116 if err == nil {
80117 klog .Infof ("found existing server [Name=%q, ID=%q]" , machineName , server .ID )
81118 } else if ! errors .Is (err , ErrNotFound ) {
82- return "" , err
119+ return nil , err
83120 } else {
84121 // clean-up function when creation fails in an intermediate step
85122 serverNetworks , err := ex .resolveServerNetworks (ctx , machineName )
86123 if err != nil {
87- return "" , deleteOnFail (fmt .Errorf ("failed to resolve server [Name=%q] networks: %w" , machineName , err ))
124+ return nil , deleteOnFail (fmt .Errorf ("failed to resolve server [Name=%q] networks: %w" , machineName , err ))
88125 }
89126
90127 server , err = ex .deployServer (ctx , machineName , userData , serverNetworks )
91128 if err != nil {
92- return "" , deleteOnFail (fmt .Errorf ("failed to deploy server [Name=%q]: %w" , machineName , err ))
129+ return nil , deleteOnFail (fmt .Errorf ("failed to deploy server [Name=%q]: %w" , machineName , err ))
93130 }
94131 }
95132
96- err = ex .waitForServerStatus (ctx , server .ID , []string {client .ServerStatusBuild }, []string {client .ServerStatusActive }, 1200 )
133+ // The server information when status is ACTIVE has addresses field populated
134+ var activeServer * servers.Server
135+ activeServer , err = ex .waitForServerStatus (ctx ,
136+ server .ID ,
137+ []string {client .ServerStatusBuild },
138+ []string {client .ServerStatusActive }, 1200 )
97139 if err != nil {
98- return "" , deleteOnFail (fmt .Errorf ("error waiting for server [ID=%q] to reach target status: %w" , server .ID , err ))
140+ return nil , deleteOnFail (fmt .Errorf ("error waiting for server [ID=%q] to reach target status: %w" , server .ID , err ))
99141 }
100142
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 ))
143+ if err := ex .patchServerPortsForPodNetwork (ctx , activeServer .ID ); err != nil {
144+ return nil , deleteOnFail (fmt .Errorf ("failed to patch server [ID=%q] ports: %s" , server .ID , err ))
103145 }
104146
105- return encodeProviderID (ex .Config .Spec .Region , server .ID ), nil
147+ var internalIPs []string
148+ internalIPs , err = getServerIPs (activeServer )
149+ if err != nil {
150+ klog .Infof ("failed to extract internal IPs [ID=%q] ports: %s" , activeServer .ID , err )
151+ }
152+
153+ return & CreateMachineResult {
154+ ProviderID : encodeProviderID (ex .Config .Spec .Region , activeServer .ID ),
155+ InternalIPs : internalIPs ,
156+ }, nil
106157}
107158
108159// resolveServerNetworks resolves the network configuration for the server.
@@ -156,10 +207,11 @@ func (ex *Executor) resolveServerNetworks(ctx context.Context, machineName strin
156207 return serverNetworks , nil
157208}
158209
159- // waitForServerStatus blocks until the server with the specified ID reaches one of the target status.
210+ // waitForServerStatus blocks until the server with the specified ID reaches one of the target status and returns the server after reaching this status .
160211// 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 (
212+ func (ex * Executor ) waitForServerStatus (ctx context.Context , serverID string , pending []string , target []string , secs int ) (* servers.Server , error ) {
213+ var server * servers.Server
214+ return server , wait .PollUntilContextTimeout (
163215 ctx ,
164216 10 * time .Second ,
165217 time .Duration (secs )* time .Second ,
@@ -175,6 +227,7 @@ func (ex *Executor) waitForServerStatus(ctx context.Context, serverID string, pe
175227
176228 klog .V (5 ).Infof ("waiting for server [ID=%q] and current status %v, to reach status %v." , serverID , current .Status , target )
177229 if strSliceContains (target , current .Status ) {
230+ server = current
178231 return true , nil
179232 }
180233
@@ -468,7 +521,7 @@ func (ex *Executor) DeleteMachine(ctx context.Context, machineName, providerID s
468521 return err
469522 }
470523
471- if err = ex .waitForServerStatus (ctx , server .ID , nil , []string {client .ServerStatusDeleted }, 1200 ); err != nil {
524+ if _ , err = ex .waitForServerStatus (ctx , server .ID , nil , []string {client .ServerStatusDeleted }, 1200 ); err != nil {
472525 return fmt .Errorf ("error while waiting for server [ID=%q] to be deleted: %v" , server .ID , err )
473526 }
474527 } else if ! errors .Is (err , ErrNotFound ) {
0 commit comments