@@ -276,179 +276,242 @@ func (d *Driver) PreCreateCheck() error {
276
276
277
277
// Create actually creates the hetzner-cloud server; see [drivers.Driver.Create]
278
278
func (d * Driver ) Create () error {
279
- if d .originalKey != "" {
280
- log .Debugf ("Copying SSH key..." )
281
- if err := d .copySSHKeyPair (d .originalKey ); err != nil {
282
- return errors .Wrap (err , "could not copy ssh key pair" )
283
- }
284
- } else {
285
- log .Debugf ("Generating SSH key..." )
286
- if err := mcnssh .GenerateSSHKey (d .GetSSHKeyPath ()); err != nil {
287
- return errors .Wrap (err , "could not generate ssh key" )
288
- }
279
+ err := d .prepareLocalKey ()
280
+ if err != nil {
281
+ return err
289
282
}
290
283
291
284
defer d .destroyDanglingKeys ()
292
- if d .KeyID == 0 {
293
- log .Infof ("Creating SSH key..." )
285
+ err = d .createRemoteKeys ()
286
+ if err != nil {
287
+ return err
288
+ }
294
289
295
- buf , err := ioutil .ReadFile (d .GetSSHKeyPath () + ".pub" )
296
- if err != nil {
297
- return errors .Wrap (err , "could not read ssh public key" )
298
- }
290
+ log .Infof ("Creating Hetzner server..." )
299
291
300
- key , err := d .getRemoteKeyWithSameFingerprint (buf )
301
- if err != nil {
302
- return errors .Wrap (err , "error retrieving potentially existing key" )
303
- }
304
- if key == nil {
305
- log .Infof ("SSH key not found in Hetzner. Uploading..." )
292
+ srvopts , err := d .makeCreateServerOptions ()
293
+ if err != nil {
294
+ return err
295
+ }
306
296
307
- key , err = d .makeKey (d .GetMachineName (), string (buf ))
297
+ srv , _ , err := d .getClient ().Server .Create (context .Background (), * srvopts )
298
+ if err != nil {
299
+ return errors .Wrap (err , "could not create server" )
300
+ }
301
+
302
+ log .Infof (" -> Creating server %s[%d] in %s[%d]" , srv .Server .Name , srv .Server .ID , srv .Action .Command , srv .Action .ID )
303
+ if err = d .waitForAction (srv .Action ); err != nil {
304
+ return errors .Wrap (err , "could not wait for action" )
305
+ }
306
+
307
+ d .ServerID = srv .Server .ID
308
+ log .Infof (" -> Server %s[%d]: Waiting to come up..." , srv .Server .Name , srv .Server .ID )
309
+
310
+ err = d .waitForRunningServer ()
311
+ if err != nil {
312
+ return err
313
+ }
314
+
315
+ err = d .configureNetworkAccess (srv )
316
+ if err != nil {
317
+ return err
318
+ }
319
+
320
+ log .Infof (" -> Server %s[%d] ready. Ip %s" , srv .Server .Name , srv .Server .ID , d .IPAddress )
321
+ // Successful creation, so no keys dangle anymore
322
+ d .danglingKeys = nil
323
+
324
+ return nil
325
+ }
326
+
327
+ func (d * Driver ) configureNetworkAccess (srv hcloud.ServerCreateResult ) error {
328
+ if d .UsePrivateNetwork {
329
+ for {
330
+ // we need to wait until network is attached
331
+ log .Infof ("Wait until private network attached ..." )
332
+ server , _ , err := d .getClient ().Server .GetByID (context .Background (), srv .Server .ID )
308
333
if err != nil {
309
- return err
334
+ return errors . Wrapf ( err , "could not get newly created server [%d]" , srv . Server . ID )
310
335
}
311
- } else {
312
- d .IsExistingKey = true
313
- log .Debugf ("SSH key found in Hetzner. ID: %d" , key .ID )
336
+ if server .PrivateNet != nil {
337
+ d .IPAddress = server .PrivateNet [0 ].IP .String ()
338
+ break
339
+ }
340
+ time .Sleep (1 * time .Second )
314
341
}
315
-
316
- d .KeyID = key .ID
342
+ } else {
343
+ log .Infof ("Using public network ..." )
344
+ d .IPAddress = srv .Server .PublicNet .IPv4 .IP .String ()
317
345
}
318
- for i , pubkey := range d .additionalKeys {
319
- key , err := d .getRemoteKeyWithSameFingerprint ([]byte (pubkey ))
346
+ return nil
347
+ }
348
+
349
+ func (d * Driver ) waitForRunningServer () error {
350
+ for {
351
+ srvstate , err := d .GetState ()
320
352
if err != nil {
321
- return errors .Wrapf (err , "error checking for existing key for %v" , pubkey )
353
+ return errors .Wrap (err , "could not get state" )
322
354
}
323
- if key == nil {
324
- log .Infof ("Creating new key for %v..." , pubkey )
325
- key , err = d .makeKey (fmt .Sprintf ("%v-additional-%d" , d .GetMachineName (), i ), pubkey )
326
-
327
- if err != nil {
328
- return errors .Wrapf (err , "error creating new key for %v" , pubkey )
329
- }
330
355
331
- log .Infof (" -> Created %v" , key .ID )
332
- d .AdditionalKeyIDs = append (d .AdditionalKeyIDs , key .ID )
333
- } else {
334
- log .Infof ("Using existing key (%v) %v" , key .ID , key .Name )
356
+ if srvstate == state .Running {
357
+ break
335
358
}
336
359
337
- d . cachedAdditionalKeys = append ( d . cachedAdditionalKeys , key )
360
+ time . Sleep ( 1 * time . Second )
338
361
}
362
+ return nil
363
+ }
339
364
340
- log .Infof ("Creating Hetzner server..." )
341
-
365
+ func (d * Driver ) makeCreateServerOptions () (* hcloud.ServerCreateOpts , error ) {
342
366
srvopts := hcloud.ServerCreateOpts {
343
367
Name : d .GetMachineName (),
344
368
UserData : d .userData ,
345
369
Labels : d .serverLabels ,
346
370
}
347
371
372
+ networks , err := d .createNetworks ()
373
+ if err != nil {
374
+ return nil , err
375
+ }
376
+ srvopts .Networks = networks
377
+
378
+ firewalls , err := d .createFirewalls ()
379
+ if err != nil {
380
+ return nil , err
381
+ }
382
+ srvopts .Firewalls = firewalls
383
+
384
+ volumes , err := d .createVolumes ()
385
+ if err != nil {
386
+ return nil , err
387
+ }
388
+ srvopts .Volumes = volumes
389
+
390
+ if srvopts .Location , err = d .getLocation (); err != nil {
391
+ return nil , errors .Wrap (err , "could not get location" )
392
+ }
393
+ if srvopts .ServerType , err = d .getType (); err != nil {
394
+ return nil , errors .Wrap (err , "could not get type" )
395
+ }
396
+ if srvopts .Image , err = d .getImage (); err != nil {
397
+ return nil , errors .Wrap (err , "could not get image" )
398
+ }
399
+ key , err := d .getKey ()
400
+ if err != nil {
401
+ return nil , errors .Wrap (err , "could not get ssh key" )
402
+ }
403
+ srvopts .SSHKeys = append (d .cachedAdditionalKeys , key )
404
+ return & srvopts , nil
405
+ }
406
+
407
+ func (d * Driver ) createNetworks () ([]* hcloud.Network , error ) {
348
408
networks := []* hcloud.Network {}
349
409
for _ , networkIDorName := range d .networks {
350
410
network , _ , err := d .getClient ().Network .Get (context .Background (), networkIDorName )
351
411
if err != nil {
352
- return errors .Wrap (err , "could not get network by ID or name" )
412
+ return nil , errors .Wrap (err , "could not get network by ID or name" )
353
413
}
354
414
if network == nil {
355
- return errors .Errorf ("network '%s' not found" , networkIDorName )
415
+ return nil , errors .Errorf ("network '%s' not found" , networkIDorName )
356
416
}
357
417
networks = append (networks , network )
358
418
}
359
- srvopts .Networks = networks
419
+ return networks , nil
420
+ }
360
421
422
+ func (d * Driver ) createFirewalls () ([]* hcloud.ServerCreateFirewall , error ) {
361
423
firewalls := []* hcloud.ServerCreateFirewall {}
362
424
for _ , firewallIDorName := range d .firewalls {
363
425
firewall , _ , err := d .getClient ().Firewall .Get (context .Background (), firewallIDorName )
364
426
if err != nil {
365
- return errors .Wrap (err , "could not get firewall by ID or name" )
427
+ return nil , errors .Wrap (err , "could not get firewall by ID or name" )
366
428
}
367
429
if firewall == nil {
368
- return errors .Errorf ("firewall '%s' not found" , firewallIDorName )
430
+ return nil , errors .Errorf ("firewall '%s' not found" , firewallIDorName )
369
431
}
370
432
firewalls = append (firewalls , & hcloud.ServerCreateFirewall {Firewall : * firewall })
371
433
}
372
- srvopts .Firewalls = firewalls
434
+ return firewalls , nil
435
+ }
373
436
437
+ func (d * Driver ) createVolumes () ([]* hcloud.Volume , error ) {
374
438
volumes := []* hcloud.Volume {}
375
439
for _ , volumeIDorName := range d .volumes {
376
440
volume , _ , err := d .getClient ().Volume .Get (context .Background (), volumeIDorName )
377
441
if err != nil {
378
- return errors .Wrap (err , "could not get volume by ID or name" )
442
+ return nil , errors .Wrap (err , "could not get volume by ID or name" )
379
443
}
380
444
if volume == nil {
381
- return errors .Errorf ("volume '%s' not found" , volumeIDorName )
445
+ return nil , errors .Errorf ("volume '%s' not found" , volumeIDorName )
382
446
}
383
447
volumes = append (volumes , volume )
384
448
}
385
- srvopts .Volumes = volumes
386
-
387
- var err error
388
- if srvopts .Location , err = d .getLocation (); err != nil {
389
- return errors .Wrap (err , "could not get location" )
390
- }
391
- if srvopts .ServerType , err = d .getType (); err != nil {
392
- return errors .Wrap (err , "could not get type" )
393
- }
394
- if srvopts .Image , err = d .getImage (); err != nil {
395
- return errors .Wrap (err , "could not get image" )
396
- }
397
- key , err := d .getKey ()
398
- if err != nil {
399
- return errors .Wrap (err , "could not get ssh key" )
400
- }
401
- srvopts .SSHKeys = append (d .cachedAdditionalKeys , key )
402
-
403
- srv , _ , err := d .getClient ().Server .Create (context .Background (), srvopts )
404
- if err != nil {
405
- return errors .Wrap (err , "could not create server" )
406
- }
449
+ return volumes , nil
450
+ }
407
451
408
- log .Infof (" -> Creating server %s[%d] in %s[%d]" , srv .Server .Name , srv .Server .ID , srv .Action .Command , srv .Action .ID )
409
- if err = d .waitForAction (srv .Action ); err != nil {
410
- return errors .Wrap (err , "could not wait for action" )
411
- }
452
+ func (d * Driver ) createRemoteKeys () error {
453
+ if d .KeyID == 0 {
454
+ log .Infof ("Creating SSH key..." )
412
455
413
- d .ServerID = srv .Server .ID
414
- log .Infof (" -> Server %s[%d]: Waiting to come up..." , srv .Server .Name , srv .Server .ID )
456
+ buf , err := ioutil .ReadFile (d .GetSSHKeyPath () + ".pub" )
457
+ if err != nil {
458
+ return errors .Wrap (err , "could not read ssh public key" )
459
+ }
415
460
416
- for {
417
- srvstate , err := d .GetState ()
461
+ key , err := d .getRemoteKeyWithSameFingerprint (buf )
418
462
if err != nil {
419
- return errors .Wrap (err , "could not get state " )
463
+ return errors .Wrap (err , "error retrieving potentially existing key " )
420
464
}
465
+ if key == nil {
466
+ log .Infof ("SSH key not found in Hetzner. Uploading..." )
421
467
422
- if srvstate == state .Running {
423
- break
468
+ key , err = d .makeKey (d .GetMachineName (), string (buf ))
469
+ if err != nil {
470
+ return err
471
+ }
472
+ } else {
473
+ d .IsExistingKey = true
474
+ log .Debugf ("SSH key found in Hetzner. ID: %d" , key .ID )
424
475
}
425
476
426
- time . Sleep ( 1 * time . Second )
477
+ d . KeyID = key . ID
427
478
}
479
+ for i , pubkey := range d .additionalKeys {
480
+ key , err := d .getRemoteKeyWithSameFingerprint ([]byte (pubkey ))
481
+ if err != nil {
482
+ return errors .Wrapf (err , "error checking for existing key for %v" , pubkey )
483
+ }
484
+ if key == nil {
485
+ log .Infof ("Creating new key for %v..." , pubkey )
486
+ key , err = d .makeKey (fmt .Sprintf ("%v-additional-%d" , d .GetMachineName (), i ), pubkey )
428
487
429
- if d .UsePrivateNetwork {
430
- for {
431
- // we need to wait until network is attached
432
- log .Infof ("Wait until private network attached ..." )
433
- server , _ , err := d .getClient ().Server .GetByID (context .Background (), srv .Server .ID )
434
488
if err != nil {
435
- return errors .Wrapf (err , "could not get newly created server [%d]" , srv .Server .ID )
436
- }
437
- if server .PrivateNet != nil {
438
- d .IPAddress = server .PrivateNet [0 ].IP .String ()
439
- break
489
+ return errors .Wrapf (err , "error creating new key for %v" , pubkey )
440
490
}
441
- time .Sleep (1 * time .Second )
491
+
492
+ log .Infof (" -> Created %v" , key .ID )
493
+ d .AdditionalKeyIDs = append (d .AdditionalKeyIDs , key .ID )
494
+ } else {
495
+ log .Infof ("Using existing key (%v) %v" , key .ID , key .Name )
442
496
}
443
- } else {
444
- log .Infof ("Using public network ..." )
445
- d .IPAddress = srv .Server .PublicNet .IPv4 .IP .String ()
446
- }
447
497
448
- log .Infof (" -> Server %s[%d] ready. Ip %s" , srv .Server .Name , srv .Server .ID , d .IPAddress )
449
- // Successful creation, so no keys dangle anymore
450
- d .danglingKeys = nil
498
+ d .cachedAdditionalKeys = append (d .cachedAdditionalKeys , key )
499
+ }
500
+ return nil
501
+ }
451
502
503
+ func (d * Driver ) prepareLocalKey () error {
504
+ if d .originalKey != "" {
505
+ log .Debugf ("Copying SSH key..." )
506
+ if err := d .copySSHKeyPair (d .originalKey ); err != nil {
507
+ return errors .Wrap (err , "could not copy ssh key pair" )
508
+ }
509
+ } else {
510
+ log .Debugf ("Generating SSH key..." )
511
+ if err := mcnssh .GenerateSSHKey (d .GetSSHKeyPath ()); err != nil {
512
+ return errors .Wrap (err , "could not generate ssh key" )
513
+ }
514
+ }
452
515
return nil
453
516
}
454
517
@@ -737,19 +800,19 @@ func (d *Driver) getKey() (*hcloud.SSHKey, error) {
737
800
return stype , nil
738
801
}
739
802
740
- func (d * Driver ) getRemoteKeyWithSameFingerprint (pubkey_byte []byte ) (* hcloud.SSHKey , error ) {
741
- pubkey , _ , _ , _ , err := ssh .ParseAuthorizedKey (pubkey_byte )
803
+ func (d * Driver ) getRemoteKeyWithSameFingerprint (publicKeyBytes []byte ) (* hcloud.SSHKey , error ) {
804
+ publicKey , _ , _ , _ , err := ssh .ParseAuthorizedKey (publicKeyBytes )
742
805
if err != nil {
743
806
return nil , errors .Wrap (err , "could not parse ssh public key" )
744
807
}
745
808
746
- fp := ssh .FingerprintLegacyMD5 (pubkey )
809
+ fp := ssh .FingerprintLegacyMD5 (publicKey )
747
810
748
- remotekey , _ , err := d .getClient ().SSHKey .GetByFingerprint (context .Background (), fp )
811
+ remoteKey , _ , err := d .getClient ().SSHKey .GetByFingerprint (context .Background (), fp )
749
812
if err != nil {
750
- return remotekey , errors .Wrap (err , "could not get sshkey by fingerprint" )
813
+ return remoteKey , errors .Wrap (err , "could not get sshkey by fingerprint" )
751
814
}
752
- return remotekey , nil
815
+ return remoteKey , nil
753
816
}
754
817
755
818
func (d * Driver ) getServerHandle () (* hcloud.Server , error ) {
0 commit comments