cloud-mu 3.1.3 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|