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.
- checksums.yaml +4 -4
- data/Dockerfile +10 -2
- data/bin/mu-adopt +5 -1
- data/bin/mu-load-config.rb +2 -3
- data/bin/mu-run-tests +112 -27
- data/cloud-mu.gemspec +20 -20
- data/cookbooks/mu-tools/libraries/helper.rb +2 -1
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +5 -15
- data/modules/mu.rb +10 -14
- data/modules/mu/adoption.rb +20 -14
- data/modules/mu/cleanup.rb +13 -9
- data/modules/mu/cloud.rb +26 -26
- data/modules/mu/clouds/aws.rb +100 -59
- data/modules/mu/clouds/aws/alarm.rb +4 -2
- data/modules/mu/clouds/aws/bucket.rb +25 -21
- data/modules/mu/clouds/aws/cache_cluster.rb +25 -23
- data/modules/mu/clouds/aws/collection.rb +21 -20
- data/modules/mu/clouds/aws/container_cluster.rb +47 -26
- data/modules/mu/clouds/aws/database.rb +57 -68
- data/modules/mu/clouds/aws/dnszone.rb +14 -14
- data/modules/mu/clouds/aws/endpoint.rb +20 -16
- data/modules/mu/clouds/aws/firewall_rule.rb +19 -16
- data/modules/mu/clouds/aws/folder.rb +7 -7
- data/modules/mu/clouds/aws/function.rb +15 -12
- data/modules/mu/clouds/aws/group.rb +14 -10
- data/modules/mu/clouds/aws/habitat.rb +16 -13
- data/modules/mu/clouds/aws/loadbalancer.rb +16 -15
- data/modules/mu/clouds/aws/log.rb +13 -10
- data/modules/mu/clouds/aws/msg_queue.rb +15 -8
- data/modules/mu/clouds/aws/nosqldb.rb +18 -11
- data/modules/mu/clouds/aws/notifier.rb +11 -6
- data/modules/mu/clouds/aws/role.rb +87 -70
- data/modules/mu/clouds/aws/search_domain.rb +30 -19
- data/modules/mu/clouds/aws/server.rb +102 -72
- data/modules/mu/clouds/aws/server_pool.rb +47 -28
- data/modules/mu/clouds/aws/storage_pool.rb +5 -6
- data/modules/mu/clouds/aws/user.rb +13 -10
- data/modules/mu/clouds/aws/vpc.rb +135 -121
- data/modules/mu/clouds/azure.rb +16 -9
- data/modules/mu/clouds/azure/container_cluster.rb +2 -3
- data/modules/mu/clouds/azure/firewall_rule.rb +10 -10
- data/modules/mu/clouds/azure/habitat.rb +8 -6
- data/modules/mu/clouds/azure/loadbalancer.rb +5 -5
- data/modules/mu/clouds/azure/role.rb +8 -10
- data/modules/mu/clouds/azure/server.rb +65 -25
- data/modules/mu/clouds/azure/user.rb +5 -7
- data/modules/mu/clouds/azure/vpc.rb +12 -15
- data/modules/mu/clouds/cloudformation.rb +8 -7
- data/modules/mu/clouds/cloudformation/vpc.rb +2 -4
- data/modules/mu/clouds/google.rb +39 -24
- data/modules/mu/clouds/google/bucket.rb +9 -11
- data/modules/mu/clouds/google/container_cluster.rb +27 -42
- data/modules/mu/clouds/google/database.rb +6 -9
- data/modules/mu/clouds/google/firewall_rule.rb +11 -10
- data/modules/mu/clouds/google/folder.rb +16 -9
- data/modules/mu/clouds/google/function.rb +127 -161
- data/modules/mu/clouds/google/group.rb +21 -18
- data/modules/mu/clouds/google/habitat.rb +18 -15
- data/modules/mu/clouds/google/loadbalancer.rb +14 -16
- data/modules/mu/clouds/google/role.rb +48 -31
- data/modules/mu/clouds/google/server.rb +105 -105
- data/modules/mu/clouds/google/server_pool.rb +12 -31
- data/modules/mu/clouds/google/user.rb +67 -13
- data/modules/mu/clouds/google/vpc.rb +58 -65
- data/modules/mu/config.rb +89 -1738
- data/modules/mu/config/bucket.rb +3 -3
- data/modules/mu/config/collection.rb +3 -3
- data/modules/mu/config/container_cluster.rb +2 -2
- data/modules/mu/config/dnszone.rb +5 -5
- data/modules/mu/config/doc_helpers.rb +517 -0
- data/modules/mu/config/endpoint.rb +3 -3
- data/modules/mu/config/firewall_rule.rb +118 -3
- data/modules/mu/config/folder.rb +3 -3
- data/modules/mu/config/function.rb +2 -2
- data/modules/mu/config/group.rb +3 -3
- data/modules/mu/config/habitat.rb +3 -3
- data/modules/mu/config/loadbalancer.rb +3 -3
- data/modules/mu/config/log.rb +3 -3
- data/modules/mu/config/msg_queue.rb +3 -3
- data/modules/mu/config/nosqldb.rb +3 -3
- data/modules/mu/config/notifier.rb +2 -2
- data/modules/mu/config/ref.rb +333 -0
- data/modules/mu/config/role.rb +3 -3
- data/modules/mu/config/schema_helpers.rb +508 -0
- data/modules/mu/config/search_domain.rb +3 -3
- data/modules/mu/config/server.rb +86 -58
- data/modules/mu/config/server_pool.rb +2 -2
- data/modules/mu/config/tail.rb +189 -0
- data/modules/mu/config/user.rb +3 -3
- data/modules/mu/config/vpc.rb +44 -4
- data/modules/mu/defaults/Google.yaml +2 -2
- data/modules/mu/deploy.rb +13 -10
- data/modules/mu/groomer.rb +1 -1
- data/modules/mu/groomers/ansible.rb +69 -24
- data/modules/mu/groomers/chef.rb +52 -44
- data/modules/mu/logger.rb +17 -14
- data/modules/mu/master.rb +317 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -2
- data/modules/mu/mommacat.rb +85 -1766
- data/modules/mu/mommacat/daemon.rb +394 -0
- data/modules/mu/mommacat/naming.rb +366 -0
- data/modules/mu/mommacat/storage.rb +689 -0
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/{win2k12.yaml → needwork/win2k12.yaml} +0 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- 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
|
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::
|
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
|
-
|
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
|
-
|
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(
|
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
|
-
|
516
|
-
|
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
|
-
|
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
|
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(
|
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
|
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,
|
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,
|
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"].
|
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
|
-
|
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
|
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(
|
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
|
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
|
-
|
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,
|
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
|
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
|
-
|
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(
|
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
|
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(
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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
|
-
|
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
|
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(
|
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:
|
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:
|
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 !
|
1046
|
-
(cloud_desc.private_ip_address ==
|
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
|
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
|
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
|
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(
|
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::
|
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::
|
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::
|
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
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|