@@ -13,6 +13,7 @@ import (
1313 "github.com/stackitcloud/machine-controller-manager-provider-stackit/pkg/client"
1414 api "github.com/stackitcloud/machine-controller-manager-provider-stackit/pkg/provider/apis"
1515 "github.com/stackitcloud/machine-controller-manager-provider-stackit/pkg/provider/apis/validation"
16+ corev1 "k8s.io/api/core/v1"
1617 "k8s.io/apimachinery/pkg/util/wait"
1718 "k8s.io/klog/v2"
1819 "k8s.io/utils/ptr"
@@ -27,10 +28,14 @@ import (
2728// Returns:
2829// - ProviderID: Unique identifier in format "stackit://<projectId>/<serverId>"
2930// - NodeName: Name that the VM will register with in Kubernetes (matches Machine name)
31+ // - Addresses: Internal IP addresses of the server's NICs (NodeInternalIP)
3032//
31- // Error codes:
32- // - InvalidArgument: Invalid ProviderSpec or missing required fields
33- // - Internal: Failed to create server or communicate with STACKIT API
33+ // Error codes (see machine_error_codes.md for retry semantics):
34+ // - InvalidArgument (no retry): Invalid ProviderSpec fields or missing required values
35+ // - Internal (no retry): Malformed ProviderSpec JSON or failed to initialize STACKIT client
36+ // - Unavailable (retry): Transient API failure (create/get server, get NICs, patch NIC)
37+ // - ResourceExhausted (no retry): No capacity available (e.g. "no valid host was found")
38+ // - DeadlineExceeded (retry): Server did not reach ACTIVE state within the polling timeout
3439func (p * Provider ) CreateMachine (ctx context.Context , req * driver.CreateMachineRequest ) (* driver.CreateMachineResponse , error ) {
3540 // Log messages to track request
3641 klog .V (2 ).Infof ("Machine creation request has been received for %q" , req .Machine .Name )
@@ -89,9 +94,10 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR
8994 return nil , status .Error (codes .DeadlineExceeded , fmt .Sprintf ("failed waiting for server to be ACTIVE: %v" , err ))
9095 }
9196
92- if err := p .patchNetworkInterface (ctx , projectID , server .ID , providerSpec ); err != nil {
93- klog .Errorf ("Failed to patch network interface for server %q: %v" , req .Machine .Name , err )
94- return nil , status .Error (codes .Unavailable , fmt .Sprintf ("failed to patch network interface for server: %v" , err ))
97+ nics , err := p .patchNetworkInterfaces (ctx , projectID , server .ID , providerSpec )
98+ if err != nil {
99+ klog .Errorf ("Failed to patch NICs for server %q: %v" , req .Machine .Name , err )
100+ return nil , status .Error (codes .Unavailable , fmt .Sprintf ("failed to patch NICs for server: %v" , err ))
95101 }
96102
97103 // Generate ProviderID in format: stackit://<projectId>/<serverId>
@@ -101,6 +107,7 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR
101107 return & driver.CreateMachineResponse {
102108 ProviderID : providerID ,
103109 NodeName : req .Machine .Name ,
110+ Addresses : nicAddresses (nics ),
104111 }, nil
105112}
106113
@@ -213,6 +220,19 @@ func (p *Provider) createServerRequest(req *driver.CreateMachineRequest, provide
213220 return createReq
214221}
215222
223+ func nicAddresses (nics []* client.NIC ) []corev1.NodeAddress {
224+ var addresses []corev1.NodeAddress
225+ for _ , nic := range nics {
226+ if nic .IPv4 != "" {
227+ addresses = append (addresses , corev1.NodeAddress {Type : corev1 .NodeInternalIP , Address : nic .IPv4 })
228+ }
229+ if nic .IPv6 != "" {
230+ addresses = append (addresses , corev1.NodeAddress {Type : corev1 .NodeInternalIP , Address : nic .IPv6 })
231+ }
232+ }
233+ return addresses
234+ }
235+
216236func (p * Provider ) getServerByName (ctx context.Context , projectID , region , serverName string ) (* client.Server , error ) {
217237 // Check if the server got already created
218238 labelSelector := map [string ]string {
@@ -235,26 +255,28 @@ func (p *Provider) getServerByName(ctx context.Context, projectID, region, serve
235255 return nil , nil
236256}
237257
238- func (p * Provider ) patchNetworkInterface (ctx context.Context , projectID , serverID string , providerSpec * api.ProviderSpec ) error {
239- if len (providerSpec .AllowedAddresses ) == 0 {
240- return nil
241- }
242-
258+ func (p * Provider ) patchNetworkInterfaces (ctx context.Context , projectID , serverID string , providerSpec * api.ProviderSpec ) ([]* client.NIC , error ) {
243259 nics , err := p .client .GetNICsForServer (ctx , projectID , providerSpec .Region , serverID )
244260 if err != nil {
245- return fmt .Errorf ("failed to get NICs for server %q: %w" , serverID , err )
261+ return nil , fmt .Errorf ("failed to get NICs for server %q: %w" , serverID , err )
246262 }
247263
248264 if len (nics ) == 0 {
249- return fmt .Errorf ("failed to find NIC for server %q" , serverID )
265+ return nil , fmt .Errorf ("no NICs found for server %q" , serverID )
250266 }
251267
268+ if len (providerSpec .AllowedAddresses ) == 0 {
269+ return nics , nil
270+ }
271+
272+ result := make ([]* client.NIC , 0 , len (nics ))
252273 for _ , nic := range nics {
253274 // if networking is not set, server is inside the default network
254275 // just patch the interface since the server should only have one
255276 if providerSpec .Networking != nil {
256277 // only process interfaces that are either in the configured network (NetworkID) or are defined in NICIDs
257278 if providerSpec .Networking .NetworkID != nic .NetworkID && ! slices .Contains (providerSpec .Networking .NICIDs , nic .ID ) {
279+ result = append (result , nic )
258280 continue
259281 }
260282 }
@@ -269,17 +291,20 @@ func (p *Provider) patchNetworkInterface(ctx context.Context, projectID, serverI
269291 }
270292
271293 if ! updateNic {
294+ result = append (result , nic )
272295 continue
273296 }
274297
275- if _ , err := p .client .UpdateNIC (ctx , projectID , providerSpec .Region , nic .NetworkID , nic .ID , nic .AllowedAddresses ); err != nil {
276- return fmt .Errorf ("failed to update allowed addresses for NIC %s: %w" , nic .ID , err )
298+ updatedNic , err := p .client .UpdateNIC (ctx , projectID , providerSpec .Region , nic .NetworkID , nic .ID , nic .AllowedAddresses )
299+ if err != nil {
300+ return nil , fmt .Errorf ("failed to update allowed addresses for NIC %s: %w" , nic .ID , err )
277301 }
278302
279303 klog .V (2 ).Infof ("Updated allowed addresses for NIC %s to %v" , nic .ID , nic .AllowedAddresses )
304+ result = append (result , updatedNic )
280305 }
281306
282- return nil
307+ return result , nil
283308}
284309
285310func (p * Provider ) WaitUntilServerRunning (ctx context.Context , projectID , region , serverID string ) error {
0 commit comments