@@ -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,7 +94,18 @@ 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 {
97+ nics , err := p .client .GetNICsForServer (ctx , projectID , providerSpec .Region , server .ID )
98+ if err != nil {
99+ klog .Errorf ("Failed to get NICs for server %q: %v" , req .Machine .Name , err )
100+ return nil , status .Error (codes .Unavailable , fmt .Sprintf ("failed to get NICs for server: %v" , err ))
101+ }
102+
103+ if len (nics ) == 0 {
104+ klog .Errorf ("No NICs found for server %q (ID: %s)" , req .Machine .Name , server .ID )
105+ return nil , status .Error (codes .Unavailable , fmt .Sprintf ("no NICs found for server %q" , server .ID ))
106+ }
107+
108+ if err := p .patchNetworkInterface (ctx , projectID , nics , providerSpec ); err != nil {
93109 klog .Errorf ("Failed to patch network interface for server %q: %v" , req .Machine .Name , err )
94110 return nil , status .Error (codes .Unavailable , fmt .Sprintf ("failed to patch network interface for server: %v" , err ))
95111 }
@@ -101,6 +117,7 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR
101117 return & driver.CreateMachineResponse {
102118 ProviderID : providerID ,
103119 NodeName : req .Machine .Name ,
120+ Addresses : nicAddresses (nics ),
104121 }, nil
105122}
106123
@@ -213,6 +230,19 @@ func (p *Provider) createServerRequest(req *driver.CreateMachineRequest, provide
213230 return createReq
214231}
215232
233+ func nicAddresses (nics []* client.NIC ) []corev1.NodeAddress {
234+ var addresses []corev1.NodeAddress
235+ for _ , nic := range nics {
236+ if nic .IPv4 != "" {
237+ addresses = append (addresses , corev1.NodeAddress {Type : corev1 .NodeInternalIP , Address : nic .IPv4 })
238+ }
239+ if nic .IPv6 != "" {
240+ addresses = append (addresses , corev1.NodeAddress {Type : corev1 .NodeInternalIP , Address : nic .IPv6 })
241+ }
242+ }
243+ return addresses
244+ }
245+
216246func (p * Provider ) getServerByName (ctx context.Context , projectID , region , serverName string ) (* client.Server , error ) {
217247 // Check if the server got already created
218248 labelSelector := map [string ]string {
@@ -235,20 +265,11 @@ func (p *Provider) getServerByName(ctx context.Context, projectID, region, serve
235265 return nil , nil
236266}
237267
238- func (p * Provider ) patchNetworkInterface (ctx context.Context , projectID , serverID string , providerSpec * api.ProviderSpec ) error {
268+ func (p * Provider ) patchNetworkInterface (ctx context.Context , projectID string , nics [] * client. NIC , providerSpec * api.ProviderSpec ) error {
239269 if len (providerSpec .AllowedAddresses ) == 0 {
240270 return nil
241271 }
242272
243- nics , err := p .client .GetNICsForServer (ctx , projectID , providerSpec .Region , serverID )
244- if err != nil {
245- return fmt .Errorf ("failed to get NICs for server %q: %w" , serverID , err )
246- }
247-
248- if len (nics ) == 0 {
249- return fmt .Errorf ("failed to find NIC for server %q" , serverID )
250- }
251-
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
0 commit comments