cloud-mu 3.1.3 → 3.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +10 -2
  3. data/bin/mu-adopt +5 -1
  4. data/bin/mu-load-config.rb +2 -3
  5. data/bin/mu-run-tests +112 -27
  6. data/cloud-mu.gemspec +20 -20
  7. data/cookbooks/mu-tools/libraries/helper.rb +2 -1
  8. data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
  9. data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
  10. data/cookbooks/mu-tools/resources/disk.rb +1 -1
  11. data/extras/image-generators/Google/centos6.yaml +1 -0
  12. data/extras/image-generators/Google/centos7.yaml +1 -1
  13. data/modules/mommacat.ru +5 -15
  14. data/modules/mu.rb +10 -14
  15. data/modules/mu/adoption.rb +20 -14
  16. data/modules/mu/cleanup.rb +13 -9
  17. data/modules/mu/cloud.rb +26 -26
  18. data/modules/mu/clouds/aws.rb +100 -59
  19. data/modules/mu/clouds/aws/alarm.rb +4 -2
  20. data/modules/mu/clouds/aws/bucket.rb +25 -21
  21. data/modules/mu/clouds/aws/cache_cluster.rb +25 -23
  22. data/modules/mu/clouds/aws/collection.rb +21 -20
  23. data/modules/mu/clouds/aws/container_cluster.rb +47 -26
  24. data/modules/mu/clouds/aws/database.rb +57 -68
  25. data/modules/mu/clouds/aws/dnszone.rb +14 -14
  26. data/modules/mu/clouds/aws/endpoint.rb +20 -16
  27. data/modules/mu/clouds/aws/firewall_rule.rb +19 -16
  28. data/modules/mu/clouds/aws/folder.rb +7 -7
  29. data/modules/mu/clouds/aws/function.rb +15 -12
  30. data/modules/mu/clouds/aws/group.rb +14 -10
  31. data/modules/mu/clouds/aws/habitat.rb +16 -13
  32. data/modules/mu/clouds/aws/loadbalancer.rb +16 -15
  33. data/modules/mu/clouds/aws/log.rb +13 -10
  34. data/modules/mu/clouds/aws/msg_queue.rb +15 -8
  35. data/modules/mu/clouds/aws/nosqldb.rb +18 -11
  36. data/modules/mu/clouds/aws/notifier.rb +11 -6
  37. data/modules/mu/clouds/aws/role.rb +87 -70
  38. data/modules/mu/clouds/aws/search_domain.rb +30 -19
  39. data/modules/mu/clouds/aws/server.rb +102 -72
  40. data/modules/mu/clouds/aws/server_pool.rb +47 -28
  41. data/modules/mu/clouds/aws/storage_pool.rb +5 -6
  42. data/modules/mu/clouds/aws/user.rb +13 -10
  43. data/modules/mu/clouds/aws/vpc.rb +135 -121
  44. data/modules/mu/clouds/azure.rb +16 -9
  45. data/modules/mu/clouds/azure/container_cluster.rb +2 -3
  46. data/modules/mu/clouds/azure/firewall_rule.rb +10 -10
  47. data/modules/mu/clouds/azure/habitat.rb +8 -6
  48. data/modules/mu/clouds/azure/loadbalancer.rb +5 -5
  49. data/modules/mu/clouds/azure/role.rb +8 -10
  50. data/modules/mu/clouds/azure/server.rb +65 -25
  51. data/modules/mu/clouds/azure/user.rb +5 -7
  52. data/modules/mu/clouds/azure/vpc.rb +12 -15
  53. data/modules/mu/clouds/cloudformation.rb +8 -7
  54. data/modules/mu/clouds/cloudformation/vpc.rb +2 -4
  55. data/modules/mu/clouds/google.rb +39 -24
  56. data/modules/mu/clouds/google/bucket.rb +9 -11
  57. data/modules/mu/clouds/google/container_cluster.rb +27 -42
  58. data/modules/mu/clouds/google/database.rb +6 -9
  59. data/modules/mu/clouds/google/firewall_rule.rb +11 -10
  60. data/modules/mu/clouds/google/folder.rb +16 -9
  61. data/modules/mu/clouds/google/function.rb +127 -161
  62. data/modules/mu/clouds/google/group.rb +21 -18
  63. data/modules/mu/clouds/google/habitat.rb +18 -15
  64. data/modules/mu/clouds/google/loadbalancer.rb +14 -16
  65. data/modules/mu/clouds/google/role.rb +48 -31
  66. data/modules/mu/clouds/google/server.rb +105 -105
  67. data/modules/mu/clouds/google/server_pool.rb +12 -31
  68. data/modules/mu/clouds/google/user.rb +67 -13
  69. data/modules/mu/clouds/google/vpc.rb +58 -65
  70. data/modules/mu/config.rb +89 -1738
  71. data/modules/mu/config/bucket.rb +3 -3
  72. data/modules/mu/config/collection.rb +3 -3
  73. data/modules/mu/config/container_cluster.rb +2 -2
  74. data/modules/mu/config/dnszone.rb +5 -5
  75. data/modules/mu/config/doc_helpers.rb +517 -0
  76. data/modules/mu/config/endpoint.rb +3 -3
  77. data/modules/mu/config/firewall_rule.rb +118 -3
  78. data/modules/mu/config/folder.rb +3 -3
  79. data/modules/mu/config/function.rb +2 -2
  80. data/modules/mu/config/group.rb +3 -3
  81. data/modules/mu/config/habitat.rb +3 -3
  82. data/modules/mu/config/loadbalancer.rb +3 -3
  83. data/modules/mu/config/log.rb +3 -3
  84. data/modules/mu/config/msg_queue.rb +3 -3
  85. data/modules/mu/config/nosqldb.rb +3 -3
  86. data/modules/mu/config/notifier.rb +2 -2
  87. data/modules/mu/config/ref.rb +333 -0
  88. data/modules/mu/config/role.rb +3 -3
  89. data/modules/mu/config/schema_helpers.rb +508 -0
  90. data/modules/mu/config/search_domain.rb +3 -3
  91. data/modules/mu/config/server.rb +86 -58
  92. data/modules/mu/config/server_pool.rb +2 -2
  93. data/modules/mu/config/tail.rb +189 -0
  94. data/modules/mu/config/user.rb +3 -3
  95. data/modules/mu/config/vpc.rb +44 -4
  96. data/modules/mu/defaults/Google.yaml +2 -2
  97. data/modules/mu/deploy.rb +13 -10
  98. data/modules/mu/groomer.rb +1 -1
  99. data/modules/mu/groomers/ansible.rb +69 -24
  100. data/modules/mu/groomers/chef.rb +52 -44
  101. data/modules/mu/logger.rb +17 -14
  102. data/modules/mu/master.rb +317 -2
  103. data/modules/mu/master/chef.rb +3 -4
  104. data/modules/mu/master/ldap.rb +3 -3
  105. data/modules/mu/master/ssl.rb +12 -2
  106. data/modules/mu/mommacat.rb +85 -1766
  107. data/modules/mu/mommacat/daemon.rb +394 -0
  108. data/modules/mu/mommacat/naming.rb +366 -0
  109. data/modules/mu/mommacat/storage.rb +689 -0
  110. data/modules/tests/bucket.yml +4 -0
  111. data/modules/tests/{win2k12.yaml → needwork/win2k12.yaml} +0 -0
  112. data/modules/tests/regrooms/aws-iam.yaml +201 -0
  113. data/modules/tests/regrooms/bucket.yml +19 -0
  114. metadata +112 -102
@@ -113,7 +113,7 @@ module MU
113
113
  }
114
114
  rescue MU::Groomer::RunError => e
115
115
  MU.log "Proceeding after failed initial Groomer run, but #{member.instance_id} may not behave as expected!", MU::WARN, details: e.inspect
116
- rescue Exception => e
116
+ rescue StandardError => e
117
117
  if !member.nil? and !done
118
118
  MU.log "Aborted before I could finish setting up #{@config['name']}, cleaning it up. Stack trace will print once cleanup is complete.", MU::WARN if !@deploy.nocleanup
119
119
  MU::MommaCat.unlockAll
@@ -293,7 +293,7 @@ module MU
293
293
  MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_or_update_tags(tag_conf)
294
294
  current.instances.each { |instance|
295
295
  tag_conf[:tags].each { |t|
296
- MU::MommaCat.createTag(instance.instance_id, t[:key], t[:value], region: @config['region'], credentials: @config['credentials'])
296
+ MU::Cloud::AWS.createTag(instance.instance_id, t[:key], t[:value], region: @config['region'], credentials: @config['credentials'])
297
297
  }
298
298
  }
299
299
  end
@@ -305,13 +305,11 @@ module MU
305
305
  asg_options[:min_size] = @config["min_size"]
306
306
  asg_options[:max_size] = @config["max_size"]
307
307
  asg_options[:new_instances_protected_from_scale_in] = (@config['scale_in_protection'] == "all")
308
- tg_arns = []
309
308
  if asg_options[:target_group_arns]
310
309
  MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).attach_load_balancer_target_groups(
311
310
  auto_scaling_group_name: @mu_name,
312
311
  target_group_arns: asg_options[:target_group_arns]
313
312
  )
314
- tg_arns = asg_options[:target_group_arns].dup
315
313
  asg_options.delete(:target_group_arns)
316
314
  end
317
315
 
@@ -365,7 +363,6 @@ module MU
365
363
  policy_params[:target_tracking_configuration].delete(:preferred_target_group)
366
364
  if policy_params[:target_tracking_configuration][:predefined_metric_specification] and
367
365
  policy_params[:target_tracking_configuration][:predefined_metric_specification][:predefined_metric_type] == "ALBRequestCountPerTarget"
368
- lb_path = nil
369
366
  lb = @deploy.deployment["loadbalancers"].values.first
370
367
  if @deploy.deployment["loadbalancers"].size > 1
371
368
  MU.log "Multiple load balancers attached to Autoscale group #{@mu_name}, guessing wildly which one to use for TargetTrackingScaling policy", MU::WARN
@@ -415,7 +412,7 @@ module MU
415
412
  }
416
413
  if !policy_already_correct
417
414
  MU.log "Putting scaling policy #{policy_name} for #{@mu_name}", MU::NOTICE, details: policy_params
418
- resp = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).put_scaling_policy(policy_params)
415
+ MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).put_scaling_policy(policy_params)
419
416
  end
420
417
 
421
418
  }
@@ -423,12 +420,15 @@ module MU
423
420
 
424
421
  end
425
422
 
423
+ @cloud_desc_cache = nil
426
424
  # Retrieve the AWS descriptor for this Autoscale group
427
425
  # @return [OpenStruct]
428
- def cloud_desc
429
- MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_auto_scaling_groups(
426
+ def cloud_desc(use_cache: true)
427
+ return @cloud_desc_cache if @cloud_desc_cache and use_cache
428
+ @cloud_desc_cache = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).describe_auto_scaling_groups(
430
429
  auto_scaling_group_names: [@mu_name]
431
430
  ).auto_scaling_groups.first
431
+ @cloud_desc_cache
432
432
  end
433
433
 
434
434
  # Canonical Amazon Resource Number for this resource
@@ -486,7 +486,7 @@ module MU
486
486
  # Reverse-map our cloud description into a runnable config hash.
487
487
  # We assume that any values we have in +@config+ are placeholders, and
488
488
  # calculate our own accordingly based on what's live in the cloud.
489
- def toKitten(rootparent: nil, billing: nil, habitats: nil)
489
+ def toKitten(**_args)
490
490
  bok = {
491
491
  "cloud" => "AWS",
492
492
  "credentials" => @config['credentials'],
@@ -504,7 +504,7 @@ module MU
504
504
  bok['tags'] ||= []
505
505
  bok['tags'] << { "key" => tag.key, "value" => tag.value }
506
506
  }
507
- realname = MU::Adoption.tagsToName(bok['tags'])
507
+ realname = MU::Adoption.tagsToName(bok['tags'], basename: @cloud_id)
508
508
  if realname
509
509
  bok['name'] = realname
510
510
  bok['name'].gsub!(/[^a-zA-Z0-9_\-]/, "_")
@@ -512,25 +512,45 @@ module MU
512
512
  end
513
513
  bok['name'] ||= @cloud_id
514
514
 
515
- # if cloud_desc.vpc_id
516
- # bok['vpc'] = MU::Config::Ref.get(
517
- # id: cloud_desc.vpc_id,
518
- # cloud: "AWS",
519
- # credentials: @credentials,
520
- # type: "vpcs",
521
- # )
522
- # end
515
+ bok['min_size'] = cloud_desc.min_size
516
+ bok['max_size'] = cloud_desc.max_size
523
517
 
524
- MU.log @cloud_id, MU::NOTICE, details: cloud_desc
518
+ if cloud_desc.launch_configuration_name
519
+ launch = MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @credentials).describe_launch_configurations(
520
+ launch_configuration_names: [cloud_desc.launch_configuration_name]
521
+ ).launch_configurations.first
522
+ bok['basis'] = {
523
+ "launch_config" => {
524
+ "image_id" => launch.image_id,
525
+ "name" => bok['name'],
526
+ "size" => launch.instance_type
527
+ }
528
+ }
529
+ end
530
+
531
+ if cloud_desc.vpc_zone_identifier and
532
+ !cloud_desc.vpc_zone_identifier.empty?
533
+ nets = cloud_desc.vpc_zone_identifier.split(/,/)
534
+ resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @credentials).describe_subnets(subnet_ids: nets).subnets.first
535
+ bok['vpc'] = MU::Config::Ref.get(
536
+ id: resp.vpc_id,
537
+ cloud: "AWS",
538
+ credentials: @credentials,
539
+ type: "vpcs",
540
+ subnets: nets.map { |s| { "subnet_id" => s } }
541
+ )
542
+ end
543
+
544
+ # MU.log @cloud_id, MU::NOTICE, details: cloud_desc
525
545
 
526
546
  bok
527
547
  end
528
548
 
529
549
 
530
550
  # Cloud-specific configuration properties.
531
- # @param config [MU::Config]: The calling MU::Config object
551
+ # @param _config [MU::Config]: The calling MU::Config object
532
552
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
533
- def self.schema(config)
553
+ def self.schema(_config)
534
554
  toplevel_required = []
535
555
 
536
556
  term_policies = MU::Cloud::AWS.credConfig ? MU::Cloud::AWS.autoscale.describe_termination_policy_types.termination_policy_types : ["AllocationStrategy", "ClosestToNextInstanceHour", "Default", "NewestInstance", "OldestInstance", "OldestLaunchConfiguration", "OldestLaunchTemplate"]
@@ -846,7 +866,7 @@ module MU
846
866
  next if !s[time]
847
867
  begin
848
868
  Time.parse(s[time])
849
- rescue Exception => e
869
+ rescue StandardError => e
850
870
  MU.log "Failed to parse #{time} '#{s[time]}' in scheduled action for AutoScale group #{pool['name']}: #{e.message}", MU::ERR
851
871
  ok = false
852
872
  end
@@ -1054,6 +1074,8 @@ module MU
1054
1074
  # @param region [String]: The cloud provider region
1055
1075
  # @return [void]
1056
1076
  def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
1077
+ MU.log "AWS::ServerPool.cleanup: need to support flags['known']", MU::DEBUG, details: flags
1078
+
1057
1079
  filters = [{name: "key", values: ["MU-ID"]}]
1058
1080
  if !ignoremaster
1059
1081
  filters << {name: "key", values: ["MU-MASTER-IP"]}
@@ -1134,7 +1156,6 @@ module MU
1134
1156
  instance_secret = Password.random(50)
1135
1157
  @deploy.saveNodeSecret("default", instance_secret, "instance_secret")
1136
1158
 
1137
- nodes_name = @deploy.getResourceName(@config['basis']["launch_config"]["name"])
1138
1159
  if !@config['basis']['launch_config']["server"].nil?
1139
1160
  #XXX this isn't how we find these; use findStray or something
1140
1161
  if @deploy.deployment["images"].nil? or @deploy.deployment["images"][@config['basis']['launch_config']["server"]].nil?
@@ -1205,7 +1226,7 @@ module MU
1205
1226
  vol.delete("encrypted")
1206
1227
  end
1207
1228
  end
1208
- mapping, cfm_mapping = MU::Cloud::AWS::Server.convertBlockDeviceMapping(vol)
1229
+ mapping, _cfm_mapping = MU::Cloud::AWS::Server.convertBlockDeviceMapping(vol)
1209
1230
  storage << mapping
1210
1231
  }
1211
1232
  end
@@ -1322,7 +1343,7 @@ module MU
1322
1343
  MU::Cloud::AWS.autoscale(region: @config['region'], credentials: @config['credentials']).create_launch_configuration(launch_options)
1323
1344
  rescue Aws::AutoScaling::Errors::ValidationError => e
1324
1345
  if lc_attempts > 3
1325
- MU.log "Got error while creating #{@mu_name} Launch Config#{@config['credentials'] ? " with credentials #{@config['credentials']}" : ""}: #{e.message}, retrying in 10s", MU::WARN, details: launch_options.reject { |k,v | k == :user_data }
1346
+ MU.log "Got error while creating #{@mu_name} Launch Config#{@config['credentials'] ? " with credentials #{@config['credentials']}" : ""}: #{e.message}, retrying in 10s", MU::WARN, details: launch_options.reject { |k,_v | k == :user_data }
1326
1347
  end
1327
1348
  sleep 5
1328
1349
  lc_attempts += 1
@@ -1411,7 +1432,7 @@ module MU
1411
1432
  if lb_name == lb['concurrent_load_balancer']
1412
1433
  lbs << deployed_lb["awsname"] # XXX check for classic
1413
1434
  if deployed_lb.has_key?("targetgroups")
1414
- deployed_lb["targetgroups"].each_pair { |tg_name, tg_arn|
1435
+ deployed_lb["targetgroups"].values.each { |tg_arn|
1415
1436
  tg_arns << tg_arn
1416
1437
  }
1417
1438
  end
@@ -1464,7 +1485,6 @@ module MU
1464
1485
 
1465
1486
 
1466
1487
  if @config['basis']["server"]
1467
- nodes_name = @deploy.getResourceName(@config['basis']["server"])
1468
1488
  srv_name = @config['basis']["server"]
1469
1489
  # XXX cloudformation bits
1470
1490
  if @deploy.deployment['servers'] != nil and
@@ -1473,7 +1493,6 @@ module MU
1473
1493
  end
1474
1494
  elsif @config['basis']["instance_id"]
1475
1495
  # TODO should go fetch the name tag or something
1476
- nodes_name = @deploy.getResourceName(@config['basis']["instance_id"].gsub(/-/, ""))
1477
1496
  # XXX cloudformation bits
1478
1497
  asg_options[:instance_id] = @config['basis']["instance_id"]
1479
1498
  end
@@ -246,7 +246,7 @@ module MU
246
246
  end
247
247
 
248
248
  security_groups.uniq!
249
- resp = MU::Cloud::AWS.efs(region: region).modify_mount_target_security_groups(
249
+ MU::Cloud::AWS.efs(region: region).modify_mount_target_security_groups(
250
250
  mount_target_id: cloud_id,
251
251
  security_groups: security_groups
252
252
  )
@@ -254,7 +254,6 @@ module MU
254
254
 
255
255
  # Register a description of this storage pool with this deployment's metadata.
256
256
  def notify
257
- deploy_struct = {}
258
257
  storage_pool = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).describe_file_systems(
259
258
  creation_token: @mu_name
260
259
  ).file_systems.first
@@ -355,6 +354,8 @@ module MU
355
354
  # @param region [String]: The cloud provider region in which to operate
356
355
  # @return [void]
357
356
  def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
357
+ MU.log "AWS::StoragePool.cleanup: need to support flags['known']", MU::DEBUG, details: flags
358
+
358
359
  supported_regions = %w{us-west-2 us-east-1 eu-west-1}
359
360
  if supported_regions.include?(region)
360
361
  begin
@@ -367,7 +368,6 @@ module MU
367
368
  end
368
369
 
369
370
  our_pools = []
370
- our_replication_group_ids = []
371
371
 
372
372
  if !storage_pools.empty?
373
373
  storage_pools.each{ |pool|
@@ -445,9 +445,9 @@ module MU
445
445
  end
446
446
 
447
447
  # Cloud-specific configuration properties.
448
- # @param config [MU::Config]: The calling MU::Config object
448
+ # @param _config [MU::Config]: The calling MU::Config object
449
449
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
450
- def self.schema(config)
450
+ def self.schema(_config)
451
451
  toplevel_required = []
452
452
  schema = {
453
453
  "ingress_rules" => {
@@ -515,7 +515,6 @@ module MU
515
515
  ok
516
516
  end
517
517
 
518
- private
519
518
  end #class
520
519
  end #class
521
520
  end
@@ -37,7 +37,7 @@ module MU
37
37
  if !@config['use_if_exists']
38
38
  raise MuError, "IAM user #{@mu_name} already exists and use_if_exists is false"
39
39
  end
40
- rescue Aws::IAM::Errors::NoSuchEntity => e
40
+ rescue Aws::IAM::Errors::NoSuchEntity
41
41
  @config['path'] ||= "/"+@deploy.deploy_id+"/"
42
42
  MU.log "Creating IAM user #{@config['path']}/#{@mu_name}"
43
43
  tags = get_tag_params
@@ -120,7 +120,7 @@ module MU
120
120
 
121
121
  if @config['attachable_policies']
122
122
  configured_policies = @config['attachable_policies'].map { |p|
123
- id = if p.is_a?(MU::Config::Ref)
123
+ if p.is_a?(MU::Config::Ref)
124
124
  p.cloud_id
125
125
  else
126
126
  p = MU::Config::Ref.get(p)
@@ -189,9 +189,9 @@ module MU
189
189
  # Remove all users associated with the currently loaded deployment.
190
190
  # @param noop [Boolean]: If true, will only print what would be done
191
191
  # @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
192
- # @param region [String]: The cloud provider region
193
192
  # @return [void]
194
- def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
193
+ def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
194
+ MU.log "AWS::User.cleanup: need to support flags['known']", MU::DEBUG, details: flags
195
195
 
196
196
  # XXX this doesn't belong here; maybe under roles, maybe as its own stupid first-class resource
197
197
  resp = MU::Cloud::AWS.iam(credentials: credentials).list_policies(
@@ -257,7 +257,7 @@ module MU
257
257
  }
258
258
  retry
259
259
  rescue ::Aws::IAM::Errors::NoSuchEntity
260
- rescue Exception => e
260
+ rescue StandardError => e
261
261
  MU.log e.inspect, MU::ERR, details: policy
262
262
  end
263
263
  end
@@ -275,14 +275,17 @@ MU.log e.inspect, MU::ERR, details: policy
275
275
  ).tags
276
276
  has_nodelete = false
277
277
  has_ourdeploy = false
278
+ has_ourmaster = false
278
279
  tags.each { |tag|
279
280
  if tag.key == "MU-ID" and tag.value == MU.deploy_id
280
281
  has_ourdeploy = true
282
+ elsif tag.key == "MU-MASTER-IP" and tag.value == MU.mu_public_ip
283
+ has_ourmaster = true
281
284
  elsif tag.key == "MU-NO-DELETE" and tag.value == "true"
282
285
  has_nodelete = true
283
286
  end
284
287
  }
285
- if has_ourdeploy and !has_nodelete
288
+ if has_ourdeploy and !has_nodelete and (ignoremaster or has_ourmaster)
286
289
  MU.log "Deleting IAM user #{u.path}#{u.user_name}"
287
290
  if !@noop
288
291
  begin
@@ -296,7 +299,7 @@ MU.log e.inspect, MU::ERR, details: policy
296
299
  group_name: g.group_name
297
300
  )
298
301
  }
299
- profile = MU::Cloud::AWS.iam(credentials: credentials).get_login_profile(
302
+ MU::Cloud::AWS.iam(credentials: credentials).get_login_profile(
300
303
  user_name: u.user_name
301
304
  )
302
305
  MU.log "Deleting IAM login profile for #{u.user_name}"
@@ -381,7 +384,7 @@ MU.log e.inspect, MU::ERR, details: policy
381
384
  # Reverse-map our cloud description into a runnable config hash.
382
385
  # We assume that any values we have in +@config+ are placeholders, and
383
386
  # calculate our own accordingly based on what's live in the cloud.
384
- def toKitten(rootparent: nil, billing: nil, habitats: nil)
387
+ def toKitten(**_args)
385
388
  bok = {
386
389
  "cloud" => "AWS",
387
390
  "credentials" => @credentials,
@@ -457,9 +460,9 @@ MU.log e.inspect, MU::ERR, details: policy
457
460
  end
458
461
 
459
462
  # Cloud-specific configuration properties.
460
- # @param config [MU::Config]: The calling MU::Config object
463
+ # @param _config [MU::Config]: The calling MU::Config object
461
464
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
462
- def self.schema(config)
465
+ def self.schema(_config)
463
466
  toplevel_required = []
464
467
  polschema = MU::Config::Role.schema["properties"]["policies"]
465
468
  polschema.deep_merge!(MU::Cloud::AWS::Role.condition_schema)
@@ -38,17 +38,17 @@ module MU
38
38
  vpc_id = @config['vpc_id'] = resp.vpc_id
39
39
 
40
40
  MU::Cloud::AWS.createStandardTags(vpc_id, region: @config['region'], credentials: @config['credentials'])
41
- MU::MommaCat.createTag(vpc_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
41
+ MU::Cloud::AWS.createTag(vpc_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
42
42
 
43
43
  if @config['tags']
44
44
  @config['tags'].each { |tag|
45
- MU::MommaCat.createTag(vpc_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
45
+ MU::Cloud::AWS.createTag(vpc_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
46
46
  }
47
47
  end
48
48
 
49
49
  if @config['optional_tags']
50
50
  MU::MommaCat.listOptionalTags.each { |key, value|
51
- MU::MommaCat.createTag(vpc_id, key, value, region: @config['region'], credentials: @config['credentials'])
51
+ MU::Cloud::AWS.createTag(vpc_id, key, value, region: @config['region'], credentials: @config['credentials'])
52
52
  }
53
53
  end
54
54
 
@@ -68,10 +68,10 @@ module MU
68
68
  ]
69
69
  )
70
70
  resp.route_tables.each { |rtb|
71
- MU::MommaCat.createTag(rtb.route_table_id, "Name", @mu_name+"-#DEFAULTPRIV", region: @config['region'], credentials: @config['credentials'])
71
+ MU::Cloud::AWS.createTag(rtb.route_table_id, "Name", @mu_name+"-#DEFAULTPRIV", region: @config['region'], credentials: @config['credentials'])
72
72
  if @config['tags']
73
73
  @config['tags'].each { |tag|
74
- MU::MommaCat.createTag(rtb.route_table_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
74
+ MU::Cloud::AWS.createTag(rtb.route_table_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
75
75
  }
76
76
  end
77
77
 
@@ -79,7 +79,7 @@ module MU
79
79
 
80
80
  if @config['optional_tags']
81
81
  MU::MommaCat.listOptionalTags.each { |key, value|
82
- MU::MommaCat.createTag(rtb.route_table_id, key, value, region: @config['region'], credentials: @config['credentials'])
82
+ MU::Cloud::AWS.createTag(rtb.route_table_id, key, value, region: @config['region'], credentials: @config['credentials'])
83
83
  }
84
84
  end
85
85
  }
@@ -93,16 +93,16 @@ module MU
93
93
  internet_gateway_id = resp.internet_gateway.internet_gateway_id
94
94
  sleep 5
95
95
  MU::Cloud::AWS.createStandardTags(internet_gateway_id, region: @config['region'], credentials: @config['credentials'])
96
- MU::MommaCat.createTag(internet_gateway_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
96
+ MU::Cloud::AWS.createTag(internet_gateway_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
97
97
  if @config['tags']
98
98
  @config['tags'].each { |tag|
99
- MU::MommaCat.createTag(internet_gateway_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
99
+ MU::Cloud::AWS.createTag(internet_gateway_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
100
100
  }
101
101
  end
102
102
 
103
103
  if @config['optional_tags']
104
104
  MU::MommaCat.listOptionalTags.each { |key, value|
105
- MU::MommaCat.createTag(internet_gateway_id, key, value, region: @config['region'], credentials: @config['credentials'])
105
+ MU::Cloud::AWS.createTag(internet_gateway_id, key, value, region: @config['region'], credentials: @config['credentials'])
106
106
  }
107
107
  end
108
108
 
@@ -168,7 +168,6 @@ module MU
168
168
  nat_gateways = []
169
169
  if !@config['subnets'].nil?
170
170
  allocation_ids = []
171
- subnet_semaphore = Mutex.new
172
171
  subnetthreads = Array.new
173
172
  parent_thread_id = Thread.current.object_id
174
173
  azs = []
@@ -191,16 +190,16 @@ module MU
191
190
  ).subnet
192
191
  subnet_id = subnet['subnet_id'] = resp.subnet_id
193
192
  MU::Cloud::AWS.createStandardTags(subnet_id, region: @config['region'], credentials: @config['credentials'])
194
- MU::MommaCat.createTag(subnet_id, "Name", @mu_name+"-"+subnet['name'], region: @config['region'], credentials: @config['credentials'])
193
+ MU::Cloud::AWS.createTag(subnet_id, "Name", @mu_name+"-"+subnet['name'], region: @config['region'], credentials: @config['credentials'])
195
194
  if @config['tags']
196
195
  @config['tags'].each { |tag|
197
- MU::MommaCat.createTag(subnet_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
196
+ MU::Cloud::AWS.createTag(subnet_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
198
197
  }
199
198
  end
200
199
 
201
200
  if @config['optional_tags']
202
201
  MU::MommaCat.listOptionalTags.each { |key, value|
203
- MU::MommaCat.createTag(subnet_id, key, value, region: @config['region'], credentials: @config['credentials'])
202
+ MU::Cloud::AWS.createTag(subnet_id, key, value, region: @config['region'], credentials: @config['credentials'])
204
203
  }
205
204
  end
206
205
 
@@ -316,7 +315,7 @@ module MU
316
315
  raise MuError, "NAT Gateway failed #{nat_gateway_id}: #{resp}" if resp.state == "failed"
317
316
  nat_gateways << {'id' => nat_gateway_id, 'availability_zone' => subnet['availability_zone']}
318
317
  @tags.each_pair { |k, v|
319
- MU::MommaCat.createTag(nat_gateway_id, k, v, region: @config['region'], credentials: @config['credentials'])
318
+ MU::Cloud::AWS.createTag(nat_gateway_id, k, v, region: @config['region'], credentials: @config['credentials'])
320
319
  }
321
320
  end
322
321
 
@@ -440,17 +439,17 @@ module MU
440
439
  )
441
440
  dhcpopt_id = resp.dhcp_options.dhcp_options_id
442
441
  MU::Cloud::AWS.createStandardTags(dhcpopt_id, region: @config['region'], credentials: @config['credentials'])
443
- MU::MommaCat.createTag(dhcpopt_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
442
+ MU::Cloud::AWS.createTag(dhcpopt_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
444
443
 
445
444
  if @config['tags']
446
445
  @config['tags'].each { |tag|
447
- MU::MommaCat.createTag(dhcpopt_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
446
+ MU::Cloud::AWS.createTag(dhcpopt_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
448
447
  }
449
448
  end
450
449
 
451
450
  if @config['optional_tags']
452
451
  MU::MommaCat.listOptionalTags.each { |key, value|
453
- MU::MommaCat.createTag(dhcpopt_id, key, value, region: @config['region'], credentials: @config['credentials'])
452
+ MU::Cloud::AWS.createTag(dhcpopt_id, key, value, region: @config['region'], credentials: @config['credentials'])
454
453
  }
455
454
  end
456
455
 
@@ -582,17 +581,17 @@ MU.log "wtf", MU::ERR, details: peer if peer_obj.nil? or peer_obj.first.nil?
582
581
  peering_name = @deploy.getResourceName(@config['name']+"-PEER-"+peer['vpc']['id'])
583
582
 
584
583
  MU::Cloud::AWS.createStandardTags(peering_id, region: @config['region'], credentials: @config['credentials'])
585
- MU::MommaCat.createTag(peering_id, "Name", peering_name, region: @config['region'], credentials: @config['credentials'])
584
+ MU::Cloud::AWS.createTag(peering_id, "Name", peering_name, region: @config['region'], credentials: @config['credentials'])
586
585
 
587
586
  if @config['optional_tags']
588
587
  MU::MommaCat.listOptionalTags.each { |key, value|
589
- MU::MommaCat.createTag(peering_id, key, value, region: @config['region'], credentials: @config['credentials'])
588
+ MU::Cloud::AWS.createTag(peering_id, key, value, region: @config['region'], credentials: @config['credentials'])
590
589
  }
591
590
  end
592
591
 
593
592
  if @config['tags']
594
593
  @config['tags'].each { |tag|
595
- MU::MommaCat.createTag(peering_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
594
+ MU::Cloud::AWS.createTag(peering_id, tag['key'], tag['value'], region: @config['region'], credentials: @config['credentials'])
596
595
  }
597
596
  end
598
597
 
@@ -713,7 +712,7 @@ MU.log "wtf", MU::ERR, details: peer if peer_obj.nil? or peer_obj.first.nil?
713
712
  route_config[:instance_id] = nat_instance.cloud_id
714
713
 
715
714
  MU.log "Creating route for #{route['destination_network']} through NAT host #{nat_instance.cloud_id}", details: route_config
716
- resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(route_config)
715
+ MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(route_config)
717
716
  end
718
717
  }
719
718
 
@@ -756,7 +755,7 @@ MU.log "wtf", MU::ERR, details: peer if peer_obj.nil? or peer_obj.first.nil?
756
755
  map[vpc.vpc_id] = vpc
757
756
  }
758
757
  return map
759
- rescue Aws::EC2::Errors::InvalidVpcIDNotFound => e
758
+ rescue Aws::EC2::Errors::InvalidVpcIDNotFound
760
759
  end
761
760
  else
762
761
  resp = MU::Cloud::AWS.ec2(region: args[:region], credentials: args[:credentials]).describe_vpcs
@@ -774,7 +773,7 @@ MU.log "wtf", MU::ERR, details: peer if peer_obj.nil? or peer_obj.first.nil?
774
773
  # Reverse-map our cloud description into a runnable config hash.
775
774
  # We assume that any values we have in +@config+ are placeholders, and
776
775
  # calculate our own accordingly based on what's live in the cloud.
777
- def toKitten(rootparent: nil, billing: nil, habitats: nil)
776
+ def toKitten(**_args)
778
777
  bok = {
779
778
  "cloud" => "AWS",
780
779
  "credentials" => @config['credentials'],
@@ -983,13 +982,14 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
983
982
  def findNat(nat_cloud_id: nil, nat_filter_key: nil, nat_filter_value: nil, region: MU.curRegion, credentials: nil)
984
983
  # Discard the nat_cloud_id if it's an AWS instance ID
985
984
  nat_cloud_id = nil if nat_cloud_id && nat_cloud_id.start_with?("i-")
985
+ credentials ||= @credentials
986
986
 
987
987
  if @gateways.nil?
988
988
  @gateways =
989
989
  if nat_cloud_id
990
- MU::Cloud::AWS.ec2(region: region, credentials: nil).describe_nat_gateways(nat_gateway_ids: [nat_cloud_id])
990
+ MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_nat_gateways(nat_gateway_ids: [nat_cloud_id])
991
991
  elsif nat_filter_key && nat_filter_value
992
- MU::Cloud::AWS.ec2(region: region, credentials: nil).describe_nat_gateways(
992
+ MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_nat_gateways(
993
993
  filter: [
994
994
  {
995
995
  name: nat_filter_key,
@@ -1014,8 +1014,8 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1014
1014
 
1015
1015
  deploy_id = nil
1016
1016
  nat_name = nat_name.to_s if !nat_name.nil? and nat_name.class.to_s == "MU::Config::Tail"
1017
- nat_ip = nat_ip.to_s if !nat_ip.nil? and nat_ip.class.to_s == "MU::Config::Tail"
1018
1017
  nat_cloud_id = nat_cloud_id.to_s if !nat_cloud_id.nil? and nat_cloud_id.class.to_s == "MU::Config::Tail"
1018
+ nat_ip = nat_ip.to_s if !nat_ip.nil? and nat_ip.class.to_s == "MU::Config::Tail"
1019
1019
  nat_tag_key = nat_tag_key.to_s if !nat_tag_key.nil? and nat_tag_key.class.to_s == "MU::Config::Tail"
1020
1020
  nat_tag_value = nat_tag_value.to_s if !nat_tag_value.nil? and nat_tag_value.class.to_s == "MU::Config::Tail"
1021
1021
 
@@ -1042,8 +1042,8 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1042
1042
  found.each { |nat|
1043
1043
  # Try some AWS-specific criteria
1044
1044
  cloud_desc = nat.cloud_desc
1045
- if !nat_host_ip.nil? and
1046
- (cloud_desc.private_ip_address == nat_host_ip or cloud_desc.public_ip_address == nat_host_ip)
1045
+ if !nat_ip.nil? and
1046
+ (cloud_desc.private_ip_address == nat_ip or cloud_desc.public_ip_address == nat_ip)
1047
1047
  return nat
1048
1048
  elsif cloud_desc.vpc_id == @cloud_id
1049
1049
  # XXX Strictly speaking we could have different NATs in different
@@ -1090,7 +1090,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1090
1090
  if instance.nil?
1091
1091
  begin
1092
1092
  instance = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_instances(instance_ids: [instance_id]).reservations.first.instances.first
1093
- rescue NoMethodError, Aws::EC2::Errors::InvalidInstanceIDNotFound => e
1093
+ rescue NoMethodError, Aws::EC2::Errors::InvalidInstanceIDNotFound
1094
1094
  MU.log "Failed to identify instance #{instance_id} in MU::Cloud::AWS::VPC.getInstanceSubnets", MU::WARN
1095
1095
  return []
1096
1096
  end
@@ -1133,7 +1133,6 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1133
1133
  my_subnets = MU::Cloud::AWS::VPC.getInstanceSubnets(instance: MU.myCloudDescriptor)
1134
1134
  target_subnets = MU::Cloud::AWS::VPC.getInstanceSubnets(instance: target_instance, region: region, credentials: credentials)
1135
1135
 
1136
- resp = nil
1137
1136
  my_subnets_key = my_subnets.join(",")
1138
1137
  target_subnets_key = target_subnets.join(",")
1139
1138
  MU::Cloud::AWS::VPC.update_route_tables_cache(my_subnets_key, region: MU.myRegion)
@@ -1280,6 +1279,8 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1280
1279
  # @param region [String]: The cloud provider region
1281
1280
  # @return [void]
1282
1281
  def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
1282
+ MU.log "AWS::VPC.cleanup: need to support flags['known']", MU::DEBUG, details: flags
1283
+
1283
1284
  tagfilters = [
1284
1285
  {name: "tag:MU-ID", values: [MU.deploy_id]}
1285
1286
  ]
@@ -1292,7 +1293,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1292
1293
  begin
1293
1294
  resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_vpcs(filters: tagfilters, max_results: 1000).vpcs
1294
1295
  vpcs = resp if !resp.empty?
1295
- rescue Aws::EC2::Errors::InvalidVpcIDNotFound => e
1296
+ rescue Aws::EC2::Errors::InvalidVpcIDNotFound
1296
1297
  if retries < 5
1297
1298
  sleep 5
1298
1299
  retries += 1
@@ -1322,17 +1323,17 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1322
1323
  purge_vpcs(noop, tagfilters, region: region, credentials: credentials)
1323
1324
  purge_dhcpopts(noop, tagfilters, region: region, credentials: credentials)
1324
1325
 
1325
- unless noop
1326
- MU::Cloud::AWS.iam.list_roles.roles.each{ |role|
1327
- match_string = "#{MU.deploy_id}.*TRAFFIC-LOG"
1328
- }
1329
- end
1326
+ # unless noop
1327
+ # MU::Cloud::AWS.iam.list_roles.roles.each{ |role|
1328
+ # match_string = "#{MU.deploy_id}.*TRAFFIC-LOG"
1329
+ # }
1330
+ # end
1330
1331
  end
1331
1332
 
1332
1333
  # Cloud-specific configuration properties.
1333
- # @param config [MU::Config]: The calling MU::Config object
1334
+ # @param _config [MU::Config]: The calling MU::Config object
1334
1335
  # @return [Array<Array,Hash>]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource
1335
- def self.schema(config)
1336
+ def self.schema(_config)
1336
1337
  toplevel_required = []
1337
1338
  # Flow Logs can be declared at the VPC level or the subnet level
1338
1339
  flowlogs = {
@@ -1428,7 +1429,6 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1428
1429
  end
1429
1430
 
1430
1431
  subnet_routes = Hash.new
1431
- public_routes = Array.new
1432
1432
 
1433
1433
  if vpc['subnets']
1434
1434
  vpc['subnets'].each { |subnet|
@@ -1600,9 +1600,11 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1600
1600
  @my_visible_cidrs[subnets]
1601
1601
  end
1602
1602
 
1603
- private
1604
1603
 
1605
1604
  # List the route tables for each subnet in the given VPC
1605
+ # @param vpc_id [String]:
1606
+ # @param region [String]:
1607
+ # @param credentials [String]:
1606
1608
  def self.listAllSubnetRouteTables(vpc_id, region: MU.curRegion, credentials: nil)
1607
1609
  resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_subnets(
1608
1610
  filters: [
@@ -1645,6 +1647,81 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1645
1647
  return table_ids.uniq
1646
1648
  end
1647
1649
 
1650
+ # Remove all network interfaces associated with the currently loaded deployment.
1651
+ # @param noop [Boolean]: If true, will only print what would be done
1652
+ # @param filters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
1653
+ # @param region [String]: The cloud provider region
1654
+ # @return [void]
1655
+ def self.purge_interfaces(noop = false, filters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
1656
+ resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_network_interfaces(
1657
+ filters: filters
1658
+ )
1659
+ ifaces = resp.data.network_interfaces
1660
+
1661
+ return if ifaces.nil? or ifaces.size == 0
1662
+
1663
+ ifaces.each { |iface|
1664
+ if iface.vpc_id
1665
+ default_sg_resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_security_groups(
1666
+ filters: [
1667
+ { name: "group-name", values: ["default"] },
1668
+ { name: "vpc-id", values: [iface.vpc_id] }
1669
+ ]
1670
+ ).security_groups
1671
+ if default_sg_resp and default_sg_resp.size == 1
1672
+ default_sg = default_sg_resp.first.group_id
1673
+ if iface.groups.size > 1 or
1674
+ iface.groups.first.group_id != default_sg
1675
+ MU.log "Removing extra security groups from ENI #{iface.network_interface_id}"
1676
+ begin
1677
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).modify_network_interface_attribute(
1678
+ network_interface_id: iface.network_interface_id,
1679
+ groups: [default_sg]
1680
+ )
1681
+ rescue ::Aws::EC2::Errors::AuthFailure
1682
+ MU.log "Permission denied attempting to trim Security Group list for #{iface.network_interface_id}", MU::WARN, details: iface.groups.map { |g| g.group_name }.join(",")+" => default"
1683
+ end
1684
+ end
1685
+ end
1686
+ end
1687
+ begin
1688
+ if iface.attachment and iface.attachment.status == "attached"
1689
+ MU.log "Detaching Network Interface #{iface.network_interface_id} from #{iface.attachment.instance_owner_id}"
1690
+ tried_lbs = false
1691
+ begin
1692
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).detach_network_interface(attachment_id: iface.attachment.attachment_id) if !noop
1693
+ rescue Aws::EC2::Errors::OperationNotPermitted => e
1694
+ MU.log "Can't detach #{iface.network_interface_id}: #{e.message}", MU::WARN, details: iface.attachment
1695
+ next
1696
+ rescue Aws::EC2::Errors::InvalidAttachmentIDNotFound => e
1697
+ # suits me just fine
1698
+ rescue Aws::EC2::Errors::AuthFailure => e
1699
+ if !tried_lbs and iface.attachment.instance_owner_id == "amazon-elb"
1700
+ MU::Cloud::AWS::LoadBalancer.cleanup(
1701
+ noop: noop,
1702
+ region: region,
1703
+ credentials: credentials,
1704
+ flags: {"vpc_id" => iface.vpc_id}
1705
+ )
1706
+ tried_lbs = true
1707
+ retry
1708
+ end
1709
+ MU.log e.message, MU::ERR, details: iface.attachment
1710
+ end
1711
+ end
1712
+ MU.log "Deleting Network Interface #{iface.network_interface_id}"
1713
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_network_interface(network_interface_id: iface.network_interface_id) if !noop
1714
+ rescue Aws::EC2::Errors::InvalidNetworkInterfaceIDNotFound
1715
+ # ok then!
1716
+ rescue Aws::EC2::Errors::InvalidParameterValue => e
1717
+ MU.log e.message, MU::ERR, details: iface
1718
+ end
1719
+ }
1720
+ end
1721
+
1722
+
1723
+ private
1724
+
1648
1725
  # Helper method for manufacturing route tables. Expect to be called from
1649
1726
  # {MU::Cloud::AWS::VPC#create} or {MU::Cloud::AWS::VPC#groom}.
1650
1727
  # @param rtb [Hash]: A route table description parsed through {MU::Config::BasketofKittens::vpcs::route_tables}.
@@ -1656,17 +1733,17 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1656
1733
  resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route_table(vpc_id: vpc_id).route_table
1657
1734
  route_table_id = rtb['route_table_id'] = resp.route_table_id
1658
1735
  sleep 5
1659
- MU::MommaCat.createTag(route_table_id, "Name", vpc_name+"-"+rtb['name'].upcase, credentials: @config['credentials'])
1736
+ MU::Cloud::AWS.createTag(route_table_id, "Name", vpc_name+"-"+rtb['name'].upcase, credentials: @config['credentials'])
1660
1737
 
1661
1738
  if @config['tags']
1662
1739
  @config['tags'].each { |tag|
1663
- MU::MommaCat.createTag(route_table_id, tag['key'], tag['value'], credentials: @config['credentials'])
1740
+ MU::Cloud::AWS.createTag(route_table_id, tag['key'], tag['value'], credentials: @config['credentials'])
1664
1741
  }
1665
1742
  end
1666
1743
 
1667
1744
  if @config['optional_tags']
1668
1745
  MU::MommaCat.listOptionalTags.each { |key, value|
1669
- MU::MommaCat.createTag(route_table_id, key, value, region: @config['region'], credentials: @config['credentials'])
1746
+ MU::Cloud::AWS.createTag(route_table_id, key, value, region: @config['region'], credentials: @config['credentials'])
1670
1747
  }
1671
1748
  end
1672
1749
 
@@ -1693,7 +1770,6 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1693
1770
  return rtb
1694
1771
  end
1695
1772
 
1696
-
1697
1773
  # Remove all network gateways associated with the currently loaded deployment.
1698
1774
  # @param noop [Boolean]: If true, will only print what would be done
1699
1775
  # @param region [String]: The cloud provider region
@@ -1746,6 +1822,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1746
1822
  }
1747
1823
  return nil
1748
1824
  end
1825
+ private_class_method :purge_gateways
1749
1826
 
1750
1827
  # Remove all NAT gateways associated with the VPC of the currently loaded deployment.
1751
1828
  # @param noop [Boolean]: If true, will only print what would be done
@@ -1803,6 +1880,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1803
1880
 
1804
1881
  return nil
1805
1882
  end
1883
+ private_class_method :purge_nat_gateways
1806
1884
 
1807
1885
  # Remove all VPC endpoints associated with the VPC of the currently loaded deployment.
1808
1886
  # @param noop [Boolean]: If true, will only print what would be done
@@ -1862,6 +1940,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1862
1940
 
1863
1941
  return nil
1864
1942
  end
1943
+ private_class_method :purge_endpoints
1865
1944
 
1866
1945
  # Remove all route tables associated with the currently loaded deployment.
1867
1946
  # @param noop [Boolean]: If true, will only print what would be done
@@ -1882,7 +1961,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1882
1961
  MU.log "Deleting Network Interface #{route.network_interface_id}"
1883
1962
  begin
1884
1963
  MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_network_interface(network_interface_id: route.network_interface_id) if !noop
1885
- rescue Aws::EC2::Errors::InvalidNetworkInterfaceIDNotFound => e
1964
+ rescue Aws::EC2::Errors::InvalidNetworkInterfaceIDNotFound
1886
1965
  MU.log "Network Interface #{route.network_interface_id} has already been deleted", MU::WARN
1887
1966
  end
1888
1967
  end
@@ -1902,9 +1981,9 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1902
1981
  table.associations.each { |assoc|
1903
1982
  begin
1904
1983
  MU::Cloud::AWS.ec2(credentials: credentials, region: region).disassociate_route_table(association_id: assoc.route_table_association_id) if !noop
1905
- rescue Aws::EC2::Errors::InvalidAssociationIDNotFound => e
1984
+ rescue Aws::EC2::Errors::InvalidAssociationIDNotFound
1906
1985
  MU.log "Route table association #{assoc.route_table_association_id} already removed", MU::WARN
1907
- rescue Aws::EC2::Errors::InvalidParameterValue => e
1986
+ rescue Aws::EC2::Errors::InvalidParameterValue
1908
1987
  # normal and ignorable with the default route table
1909
1988
  can_delete = false
1910
1989
  next
@@ -1920,75 +1999,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
1920
1999
  }
1921
2000
  return nil
1922
2001
  end
1923
-
1924
-
1925
- # Remove all network interfaces associated with the currently loaded deployment.
1926
- # @param noop [Boolean]: If true, will only print what would be done
1927
- # @param filters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
1928
- # @param region [String]: The cloud provider region
1929
- # @return [void]
1930
- def self.purge_interfaces(noop = false, filters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
1931
- resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_network_interfaces(
1932
- filters: filters
1933
- )
1934
- ifaces = resp.data.network_interfaces
1935
-
1936
- return if ifaces.nil? or ifaces.size == 0
1937
-
1938
- ifaces.each { |iface|
1939
- if iface.vpc_id
1940
- default_sg_resp = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_security_groups(
1941
- filters: [
1942
- { name: "group-name", values: ["default"] },
1943
- { name: "vpc-id", values: [iface.vpc_id] }
1944
- ]
1945
- ).security_groups
1946
- if default_sg_resp and default_sg_resp.size == 1
1947
- default_sg = default_sg_resp.first.group_id
1948
- if iface.groups.size != 1 or
1949
- iface.groups.first.group_id != default_sg
1950
- MU.log "Removing extra security groups from ENI #{iface.network_interface_id}"
1951
- MU::Cloud::AWS.ec2(credentials: credentials, region: region).modify_network_interface_attribute(
1952
- network_interface_id: iface.network_interface_id,
1953
- groups: [default_sg]
1954
- )
1955
- end
1956
- end
1957
- end
1958
- begin
1959
- if iface.attachment and iface.attachment.status == "attached"
1960
- MU.log "Detaching Network Interface #{iface.network_interface_id} from #{iface.attachment.instance_owner_id}"
1961
- tried_lbs = false
1962
- begin
1963
- MU::Cloud::AWS.ec2(credentials: credentials, region: region).detach_network_interface(attachment_id: iface.attachment.attachment_id) if !noop
1964
- rescue Aws::EC2::Errors::OperationNotPermitted => e
1965
- MU.log "Can't detach #{iface.network_interface_id}: #{e.message}", MU::WARN, details: iface.attachment
1966
- next
1967
- rescue Aws::EC2::Errors::InvalidAttachmentIDNotFound => e
1968
- # suits me just fine
1969
- rescue Aws::EC2::Errors::AuthFailure => e
1970
- if !tried_lbs and iface.attachment.instance_owner_id == "amazon-elb"
1971
- MU::Cloud::AWS::LoadBalancer.cleanup(
1972
- noop: noop,
1973
- region: region,
1974
- credentials: credentials,
1975
- flags: {"vpc_id" => iface.vpc_id}
1976
- )
1977
- tried_lbs = true
1978
- retry
1979
- end
1980
- MU.log e.message, MU::ERR, details: iface.attachment
1981
- end
1982
- end
1983
- MU.log "Deleting Network Interface #{iface.network_interface_id}"
1984
- MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_network_interface(network_interface_id: iface.network_interface_id) if !noop
1985
- rescue Aws::EC2::Errors::InvalidNetworkInterfaceIDNotFound => e
1986
- # ok then!
1987
- rescue Aws::EC2::Errors::InvalidParameterValue => e
1988
- MU.log e.message, MU::ERR, details: iface
1989
- end
1990
- }
1991
- end
2002
+ private_class_method :purge_routetables
1992
2003
 
1993
2004
  # Remove all subnets associated with the currently loaded deployment.
1994
2005
  # @param noop [Boolean]: If true, will only print what would be done
@@ -2038,6 +2049,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
2038
2049
  end while subnet.state != "available"
2039
2050
  }
2040
2051
  end
2052
+ private_class_method :purge_subnets
2041
2053
 
2042
2054
  # Remove all DHCP options sets associated with the currently loaded
2043
2055
  # deployment.
@@ -2056,7 +2068,9 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
2056
2068
  sets.each { |optset|
2057
2069
  begin
2058
2070
  MU.log "Deleting DHCP Option Set #{optset.dhcp_options_id}"
2059
- MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_dhcp_options(dhcp_options_id: optset.dhcp_options_id)
2071
+ if !noop
2072
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_dhcp_options(dhcp_options_id: optset.dhcp_options_id)
2073
+ end
2060
2074
  rescue Aws::EC2::Errors::DependencyViolation => e
2061
2075
  MU.log e.inspect, MU::ERR
2062
2076
  # rescue Aws::EC2::Errors::InvalidSubnetIDNotFound
@@ -2065,6 +2079,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
2065
2079
  end
2066
2080
  }
2067
2081
  end
2082
+ private_class_method :purge_dhcpopts
2068
2083
 
2069
2084
  # Remove all VPCs associated with the currently loaded deployment.
2070
2085
  # @param noop [Boolean]: If true, will only print what would be done
@@ -2104,7 +2119,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
2104
2119
  resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_route_tables(
2105
2120
  route_table_ids: [rtb_id]
2106
2121
  )
2107
- rescue Aws::EC2::Errors::InvalidRouteTableIDNotFound => e
2122
+ rescue Aws::EC2::Errors::InvalidRouteTableIDNotFound
2108
2123
  next
2109
2124
  end
2110
2125
  resp.route_tables.each { |rtb|
@@ -2125,7 +2140,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
2125
2140
  MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_vpc_peering_connection(
2126
2141
  vpc_peering_connection_id: cnxn.vpc_peering_connection_id
2127
2142
  ) if !noop
2128
- rescue Aws::EC2::Errors::InvalidStateTransition => e
2143
+ rescue Aws::EC2::Errors::InvalidStateTransition
2129
2144
  MU.log "VPC peering connection #{cnxn.vpc_peering_connection_id} not in removable (state #{cnxn.status.code})", MU::WARN
2130
2145
  rescue Aws::EC2::Errors::OperationNotPermitted => e
2131
2146
  MU.log "VPC peering connection #{cnxn.vpc_peering_connection_id} refuses to delete: #{e.message}", MU::WARN
@@ -2166,8 +2181,7 @@ MU.log "association I don't understand in #{@cloud_id}", MU::WARN, details: rtb_
2166
2181
  end
2167
2182
  }
2168
2183
  end
2169
-
2170
- protected
2184
+ private_class_method :purge_vpcs
2171
2185
 
2172
2186
  # Subnets are almost a first-class resource. So let's kinda sorta treat
2173
2187
  # them like one. This should only be invoked on objects that already