@@ -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 }
@@ -98,10 +114,25 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR
98114 providerID := fmt .Sprintf ("%s://%s/%s" , StackitProviderName , projectID , server .ID )
99115 klog .V (2 ).Infof ("Successfully created server %q with ID %q for machine %q" , server .Name , server .ID , req .Machine .Name )
100116
101- return & driver.CreateMachineResponse {
117+ response := & driver.CreateMachineResponse {
102118 ProviderID : providerID ,
103119 NodeName : req .Machine .Name ,
104- }, nil
120+ }
121+
122+ var addresses []corev1.NodeAddress
123+ for _ , nic := range nics {
124+ if nic .IPv4 != "" {
125+ addresses = append (addresses , corev1.NodeAddress {Type : corev1 .NodeInternalIP , Address : nic .IPv4 })
126+ }
127+ if nic .IPv6 != "" {
128+ addresses = append (addresses , corev1.NodeAddress {Type : corev1 .NodeInternalIP , Address : nic .IPv6 })
129+ }
130+ }
131+ if len (addresses ) > 0 {
132+ response .Addresses = addresses
133+ }
134+
135+ return response , nil
105136}
106137
107138// nolint: gocyclo // this function is already pretty simple
@@ -235,20 +266,11 @@ func (p *Provider) getServerByName(ctx context.Context, projectID, region, serve
235266 return nil , nil
236267}
237268
238- func (p * Provider ) patchNetworkInterface (ctx context.Context , projectID , serverID string , providerSpec * api.ProviderSpec ) error {
269+ func (p * Provider ) patchNetworkInterface (ctx context.Context , projectID string , nics [] * client. NIC , providerSpec * api.ProviderSpec ) error {
239270 if len (providerSpec .AllowedAddresses ) == 0 {
240271 return nil
241272 }
242273
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-
252274 for _ , nic := range nics {
253275 // if networking is not set, server is inside the default network
254276 // just patch the interface since the server should only have one
0 commit comments