@@ -11,6 +11,7 @@ import (
1111 "errors"
1212 "fmt"
1313 "slices"
14+ "strconv"
1415 "strings"
1516
1617 "github.com/gardener/machine-controller-manager/pkg/util/provider/driver"
@@ -28,6 +29,8 @@ const (
2829 StackitRoleLabel = "mcm.gardener.cloud/role"
2930)
3031
32+ const migratedMachineAnnotation = "stackit.cloud/migrated-machine"
33+
3134// CreateMachine handles a machine creation request by creating a STACKIT server
3235//
3336// This method creates a new server in STACKIT infrastructure based on the ProviderSpec
@@ -54,6 +57,10 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR
5457 return nil , status .Error (codes .InvalidArgument , err .Error ())
5558 }
5659
60+ if m , _ := strconv .ParseBool (req .Machine .Annotations [migratedMachineAnnotation ]); m {
61+ return nil , status .Error (codes .AlreadyExists , fmt .Errorf ("create for migrated machine %s will not work" , req .Machine .Name ).Error ())
62+ }
63+
5764 // Decode ProviderSpec from MachineClass
5865 providerSpec , err := decodeProviderSpec (req .MachineClass )
5966 if err != nil {
@@ -186,12 +193,25 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR
186193 }
187194
188195 // check if server already exists
189- server , err := p .getServerByName (ctx , projectID , providerSpec .Region , req .Machine .Name )
196+ servers , err := p .getServersByName (ctx , projectID , providerSpec .Region , map [string ]string {
197+ StackitMachineLabel : req .Machine .Name ,
198+ })
190199 if err != nil {
191200 klog .Errorf ("Failed to fetch server for machine %q: %v" , req .Machine .Name , err )
192201 return nil , status .Error (codes .Unavailable , fmt .Sprintf ("failed to fetch server: %v" , err ))
193202 }
194203
204+ if len (servers ) > 1 {
205+ klog .Errorf ("Multiple servers already exists for this machine %q: %v" , req .Machine .Name , err )
206+ return nil , status .Error (codes .AlreadyExists , fmt .Sprintf ("failed to fetch server: %v" , err ))
207+ }
208+
209+ var server * Server
210+
211+ if len (servers ) == 1 {
212+ server = servers [0 ]
213+ }
214+
195215 if server == nil {
196216 // Call STACKIT API to create server
197217 server , err = p .client .CreateServer (ctx , projectID , providerSpec .Region , createReq )
@@ -216,26 +236,18 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR
216236 }, nil
217237}
218238
219- func (p * Provider ) getServerByName (ctx context.Context , projectID , region , serverName string ) (* Server , error ) {
239+ func (p * Provider ) getServersByName (ctx context.Context , projectID , region string , selector map [ string ] string ) ([] * Server , error ) {
220240 // Check if the server got already created
221- labelSelector := map [string ]string {
222- StackitMachineLabel : serverName ,
223- }
224- servers , err := p .client .ListServers (ctx , projectID , region , labelSelector )
241+ servers , err := p .client .ListServers (ctx , projectID , region , selector )
225242 if err != nil {
226- return nil , fmt .Errorf ("SDK ListServers with labelSelector: %v failed: %w" , labelSelector , err )
243+ return nil , fmt .Errorf ("SDK ListServers with labelSelector: %v failed: %w" , selector , err )
227244 }
228245
229- if len (servers ) > 1 {
230- return nil , fmt . Errorf ( "%v servers found for server name %v" , len ( servers ), serverName )
246+ if len (servers ) == 0 {
247+ return nil , nil
231248 }
232249
233- if len (servers ) == 1 {
234- return servers [0 ], nil
235- }
236-
237- // no servers found len == 0
238- return nil , nil
250+ return servers , nil
239251}
240252
241253func (p * Provider ) patchNetworkInterface (ctx context.Context , projectID , serverID string , providerSpec * api.ProviderSpec ) error {
@@ -305,9 +317,11 @@ func (p *Provider) DeleteMachine(ctx context.Context, req *driver.DeleteMachineR
305317 return nil , status .Error (codes .Internal , fmt .Sprintf ("failed to initialize STACKIT client: %v" , err ))
306318 }
307319
308- var projectID , serverID string
320+ var projectID string
321+ var serverIDs []string
309322 var err error
310323 if req .Machine .Spec .ProviderID != "" {
324+ var serverID string
311325 if ! strings .HasPrefix (req .Machine .Spec .ProviderID , StackitProviderName ) {
312326 return nil , status .Error (codes .InvalidArgument , "providerID is not empty and does not start with stackit://" )
313327 }
@@ -317,6 +331,7 @@ func (p *Provider) DeleteMachine(ctx context.Context, req *driver.DeleteMachineR
317331 if err != nil {
318332 klog .V (2 ).Infof ("invalid ProviderID format: %v" , err )
319333 }
334+ serverIDs = append (serverIDs , serverID )
320335 }
321336
322337 if projectID == "" {
@@ -328,36 +343,67 @@ func (p *Provider) DeleteMachine(ctx context.Context, req *driver.DeleteMachineR
328343 return nil , status .Error (codes .Internal , err .Error ())
329344 }
330345
331- if serverID == "" {
332- server , err := p .getServerByName (ctx , projectID , providerSpec .Region , req .Machine .Name )
346+ if len (serverIDs ) == 0 {
347+ selector := map [string ]string {
348+ StackitMachineLabel : req .Machine .Name ,
349+ }
350+
351+ if m , _ := strconv .ParseBool (req .Machine .Annotations [migratedMachineAnnotation ]); m {
352+ selector = nil
353+ }
354+
355+ servers , err := p .getServersByName (ctx , projectID , providerSpec .Region , selector )
333356 if err != nil {
334357 return nil , status .Error (codes .Internal , fmt .Sprintf ("failed to find server by name: %v" , err ))
335358 }
336359
337- if server != nil {
338- serverID = server .ID
360+ for _ , server := range servers {
361+ if server .Name != req .Machine .Name {
362+ continue
363+ }
364+ serverIDs = append (serverIDs , server .ID )
339365 }
340366 }
341367
342- if serverID == "" {
343- klog .V (2 ).Infof ("Server is already deleted for machine %q" , req .Machine .Name )
344- return & driver.DeleteMachineResponse {}, nil
368+ for _ , id := range serverIDs {
369+ // Call STACKIT API to delete server
370+ err = p .client .DeleteServer (ctx , projectID , providerSpec .Region , id )
371+ if err != nil {
372+ // Check if server was not found (404) - this is OK for idempotency
373+ if errors .Is (err , ErrServerNotFound ) {
374+ klog .V (2 ).Infof ("Server %q already deleted for machine %q (idempotent)" , id , req .Machine .Name )
375+ return & driver.DeleteMachineResponse {}, nil
376+ }
377+ // All other errors are internal errors
378+ klog .Errorf ("Failed to delete server for machine %q: %v" , req .Machine .Name , err )
379+ return nil , status .Error (codes .Internal , fmt .Sprintf ("failed to delete server: %v" , err ))
380+ }
345381 }
346382
347- // Call STACKIT API to delete server
348- err = p .client .DeleteServer (ctx , projectID , providerSpec .Region , serverID )
349- if err != nil {
350- // Check if server was not found (404) - this is OK for idempotency
351- if errors .Is (err , ErrServerNotFound ) {
352- klog .V (2 ).Infof ("Server %q already deleted for machine %q (idempotent)" , serverID , req .Machine .Name )
353- return & driver.DeleteMachineResponse {}, nil
383+ if m , _ := strconv .ParseBool (req .Machine .Annotations [migratedMachineAnnotation ]); m {
384+ nics , err := p .client .ListNICs (ctx , projectID , providerSpec .Region , providerSpec .Networking .NetworkID )
385+ if err != nil {
386+ return nil , err
387+ }
388+ for _ , nic := range nics {
389+ if nic .Name != req .Machine .Name {
390+ continue
391+ }
392+ err = p .client .DeleteNIC (ctx , projectID , providerSpec .Region , nic .NetworkID , nic .ID )
393+ if err != nil {
394+ // Check if server was not found (404) - this is OK for idempotency
395+ if errors .Is (err , ErrNicNotFound ) {
396+ klog .V (2 ).Infof ("Nic %q already deleted for machine %q (idempotent)" , nic .ID , req .Machine .Name )
397+ return & driver.DeleteMachineResponse {}, nil
398+ }
399+ // All other errors are internal errors
400+ klog .Errorf ("Failed to delete nic for machine %q: %v" , req .Machine .Name , err )
401+ return nil , status .Error (codes .Internal , fmt .Sprintf ("failed to delete nic: %v" , err ))
402+ }
354403 }
355- // All other errors are internal errors
356- klog .Errorf ("Failed to delete server for machine %q: %v" , req .Machine .Name , err )
357- return nil , status .Error (codes .Internal , fmt .Sprintf ("failed to delete server: %v" , err ))
358- }
359404
360- klog .V (2 ).Infof ("Successfully deleted server %q for machine %q" , serverID , req .Machine .Name )
405+ }
406+ klog .V (2 ).Infof ("Successfully deleted server for machine %q" , req .Machine .Name )
361407
362408 return & driver.DeleteMachineResponse {}, nil
363409}
0 commit comments