@@ -226,39 +226,7 @@ func (driver *Driver) deployServer() (*compute.Server, error) {
226
226
log .Debugf ("Server '%s' ('%s') has been successfully deployed..." , driver .ServerID , server .Name )
227
227
228
228
driver .PrivateIPAddress = * server .Network .PrimaryAdapter .PrivateIPv4Address
229
-
230
- log .Debugf ("Creating NAT rule for server '%s' ('%s')..." , driver .MachineName , driver .PrivateIPAddress )
231
-
232
- natRule , err := driver .getExistingNATRuleByInternalIP (driver .PrivateIPAddress )
233
- if natRule == nil {
234
- err = driver .ensurePublicIPAvailable ()
235
- if err != nil {
236
- return nil , err
237
- }
238
-
239
- natRuleID , err := client .AddNATRule (driver .NetworkDomainID , driver .PrivateIPAddress , nil )
240
- if err != nil {
241
- return nil , err
242
- }
243
- natRule , err = client .GetNATRule (natRuleID )
244
- if err != nil {
245
- return nil , err
246
- }
247
- if natRule == nil {
248
- return nil , fmt .Errorf ("Failed to retrieve newly-created NAT rule '%s' for server '%s'" , natRuleID , driver .MachineName )
249
- }
250
- } else {
251
- log .Debugf ("NAT rule already exists (Id = '%s')." , natRule .ID )
252
- }
253
-
254
- driver .IPAddress = natRule .ExternalIPAddress
255
-
256
- log .Debugf ("Created NAT rule '%s' for server '%s' (Ext:'%s' -> Int:'%s')." ,
257
- driver .NATRuleID ,
258
- driver .MachineName ,
259
- driver .IPAddress ,
260
- driver .PrivateIPAddress ,
261
- )
229
+ driver .IPAddress = driver .PrivateIPAddress // NAT rule not created yet.
262
230
263
231
return server , nil
264
232
}
@@ -297,39 +265,111 @@ func (driver *Driver) buildDeploymentConfiguration() (deploymentConfiguration co
297
265
return
298
266
}
299
267
300
- // Ensure that at least one public IP address is available in the target network domain.
301
- func (driver * Driver ) ensurePublicIPAvailable () error {
302
- if driver .NetworkDomainID == "" {
303
- return errors .New ("Network domain has not been resolved." )
268
+ // Has a NAT rule been created for the server?
269
+ func (driver * Driver ) isNATRuleCreated () bool {
270
+ return driver .NATRuleID != ""
271
+ }
272
+
273
+ // Create a NAT rule to expose the server.
274
+ func (driver * Driver ) createNATRuleForServer () error {
275
+ if ! driver .isServerCreated () {
276
+ return errors .New ("Server has not been created" )
304
277
}
305
278
306
- log .Debugf ("Verifying that network domain '%s' has a public IP available for server '%s'..." , driver .NetworkDomainName , driver .MachineName )
279
+ if driver .isNATRuleCreated () {
280
+ return fmt .Errorf ("NAT rule '%s' has already been created for server '%s'" , driver .NATRuleID , driver .MachineName )
281
+ }
282
+
283
+ log .Debugf ("Creating NAT rule for server '%s' ('%s')..." , driver .MachineName , driver .PrivateIPAddress )
284
+
285
+ natRule , err := driver .getExistingNATRuleByInternalIP (driver .PrivateIPAddress )
286
+ if natRule == nil {
287
+ err = driver .ensurePublicIPAvailable ()
288
+ if err != nil {
289
+ return err
290
+ }
291
+
292
+ client , err := driver .getCloudControlClient ()
293
+ if err != nil {
294
+ return err
295
+ }
296
+
297
+ driver .NATRuleID , err = client .AddNATRule (driver .NetworkDomainID , driver .PrivateIPAddress , nil )
298
+ if err != nil {
299
+ return err
300
+ }
301
+ natRule , err = client .GetNATRule (driver .NATRuleID )
302
+ if err != nil {
303
+ return err
304
+ }
305
+ if natRule == nil {
306
+ return fmt .Errorf ("Failed to retrieve newly-created NAT rule '%s' for server '%s'" , driver .NATRuleID , driver .MachineName )
307
+ }
308
+
309
+ log .Debugf ("Created NAT rule '%s' for server '%s'" , driver .NATRuleID )
310
+ } else {
311
+ driver .NATRuleID = natRule .ID
312
+
313
+ log .Debugf ("NAT rule already exists (Id = '%s')." , driver .NATRuleID )
314
+ }
315
+
316
+ driver .IPAddress = natRule .ExternalIPAddress
317
+
318
+ log .Debugf ("Created NAT rule '%s' for server '%s' (Ext:'%s' -> Int:'%s')." ,
319
+ driver .NATRuleID ,
320
+ driver .MachineName ,
321
+ driver .IPAddress ,
322
+ driver .PrivateIPAddress ,
323
+ )
324
+
325
+ return nil
326
+ }
327
+
328
+ // Delete the the server's NAT rule (if any).
329
+ func (driver * Driver ) deleteNATRuleForServer () error {
330
+ if ! driver .isServerCreated () {
331
+ return errors .New ("Server has not been created" )
332
+ }
333
+
334
+ if ! driver .isNATRuleCreated () {
335
+ log .Debugf ("Not deleting NAT rule for server '%s' (no NAT rule was created for it)." )
336
+
337
+ return nil
338
+ }
339
+
340
+ log .Debugf ("Deleting NAT rule '%s' for server '%s' (Ext:'%s' -> Int:'%s')..." , driver .NATRuleID , driver .MachineName , driver .IPAddress , driver .PrivateIPAddress )
307
341
308
342
client , err := driver .getCloudControlClient ()
309
343
if err != nil {
310
344
return err
311
345
}
312
346
313
- availableIPs , err := client .GetAvailablePublicIPAddresses (driver .NetworkDomainID )
347
+ natRule , err := client .GetNATRule (driver .NATRuleID )
314
348
if err != nil {
315
349
return err
316
350
}
351
+ if natRule == nil {
352
+ log .Debugf ("NAT rule '%s' not found; will treat it as already deleted." )
317
353
318
- if len (availableIPs ) == 0 {
319
- log .Debugf ("There are no available public IPs in network domain '%s'; a new block of public IPs will be allocated." , driver .NetworkDomainID )
354
+ driver .NATRuleID = ""
320
355
321
- blockID , err := client .AddPublicIPBlock (driver .NetworkDomainID )
322
- if err != nil {
323
- return err
324
- }
356
+ return nil
357
+ }
325
358
326
- log .Debugf ("Allocated new public IP block '%s'." , blockID )
359
+ err = client .DeleteNATRule (driver .NATRuleID )
360
+ if err != nil {
361
+ return err
327
362
}
328
363
364
+ log .Debugf ("Deleted NAT rule '%s'." , driver .NATRuleID )
365
+
366
+ driver .NATRuleID = ""
367
+ driver .IPAddress = driver .PrivateIPAddress
368
+
329
369
return nil
330
370
}
331
371
332
- // Find the existing NAT rule (if any) for the specified internal IPv4 address.
372
+ // Find the existing NAT rule (if any) that forwards IPv4 traffic to specified internal address.
333
373
func (driver * Driver ) getExistingNATRuleByInternalIP (internalIPAddress string ) (* compute.NATRule , error ) {
334
374
if driver .NetworkDomainID == "" {
335
375
return nil , errors .New ("Network domain has not been resolved." )
@@ -362,3 +402,40 @@ func (driver *Driver) getExistingNATRuleByInternalIP(internalIPAddress string) (
362
402
363
403
return nil , nil
364
404
}
405
+
406
+ // Ensure that at least one public IP address is available in the target network domain.
407
+ func (driver * Driver ) ensurePublicIPAvailable () error {
408
+ if driver .NetworkDomainID == "" {
409
+ return errors .New ("Network domain has not been resolved." )
410
+ }
411
+
412
+ log .Debugf ("Verifying that network domain '%s' has a public IP available for server '%s'..." , driver .NetworkDomainName , driver .MachineName )
413
+
414
+ client , err := driver .getCloudControlClient ()
415
+ if err != nil {
416
+ return err
417
+ }
418
+
419
+ availableIPs , err := client .GetAvailablePublicIPAddresses (driver .NetworkDomainID )
420
+ if err != nil {
421
+ return err
422
+ }
423
+
424
+ if len (availableIPs ) == 0 {
425
+ log .Debugf ("There are no available public IPs in network domain '%s'; a new block of public IPs will be allocated." , driver .NetworkDomainID )
426
+
427
+ blockID , err := client .AddPublicIPBlock (driver .NetworkDomainID )
428
+ if err != nil {
429
+ return err
430
+ }
431
+
432
+ log .Debugf ("Allocated new public IP block '%s'." , blockID )
433
+ }
434
+
435
+ return nil
436
+ }
437
+
438
+ // Has a firewall rule been created to allow inbound SSH for the server?
439
+ func (driver * Driver ) isSSHFirewallRuleCreated () bool {
440
+ return driver .SSHFirewallRuleID != ""
441
+ }
0 commit comments