cloud-mu 3.1.6 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/bin/mu-adopt +4 -12
  3. data/bin/mu-azure-tests +57 -0
  4. data/bin/mu-cleanup +2 -4
  5. data/bin/mu-configure +37 -1
  6. data/bin/mu-deploy +3 -3
  7. data/bin/mu-findstray-tests +25 -0
  8. data/bin/mu-gen-docs +2 -4
  9. data/bin/mu-run-tests +23 -10
  10. data/cloud-mu.gemspec +2 -2
  11. data/cookbooks/mu-tools/libraries/helper.rb +1 -1
  12. data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
  13. data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
  14. data/extras/generate-stock-images +1 -0
  15. data/modules/mu.rb +82 -95
  16. data/modules/mu/adoption.rb +356 -56
  17. data/modules/mu/cleanup.rb +21 -20
  18. data/modules/mu/cloud.rb +79 -1753
  19. data/modules/mu/cloud/database.rb +49 -0
  20. data/modules/mu/cloud/dnszone.rb +46 -0
  21. data/modules/mu/cloud/machine_images.rb +212 -0
  22. data/modules/mu/cloud/providers.rb +81 -0
  23. data/modules/mu/cloud/resource_base.rb +920 -0
  24. data/modules/mu/cloud/server.rb +40 -0
  25. data/modules/mu/cloud/server_pool.rb +1 -0
  26. data/modules/mu/cloud/ssh_sessions.rb +228 -0
  27. data/modules/mu/cloud/winrm_sessions.rb +237 -0
  28. data/modules/mu/cloud/wrappers.rb +165 -0
  29. data/modules/mu/config.rb +122 -80
  30. data/modules/mu/config/alarm.rb +2 -6
  31. data/modules/mu/config/bucket.rb +1 -1
  32. data/modules/mu/config/cache_cluster.rb +1 -1
  33. data/modules/mu/config/collection.rb +1 -1
  34. data/modules/mu/config/container_cluster.rb +2 -2
  35. data/modules/mu/config/database.rb +83 -104
  36. data/modules/mu/config/database.yml +1 -2
  37. data/modules/mu/config/dnszone.rb +1 -1
  38. data/modules/mu/config/doc_helpers.rb +4 -5
  39. data/modules/mu/config/endpoint.rb +1 -1
  40. data/modules/mu/config/firewall_rule.rb +3 -19
  41. data/modules/mu/config/folder.rb +1 -1
  42. data/modules/mu/config/function.rb +1 -1
  43. data/modules/mu/config/group.rb +1 -1
  44. data/modules/mu/config/habitat.rb +1 -1
  45. data/modules/mu/config/loadbalancer.rb +57 -11
  46. data/modules/mu/config/log.rb +1 -1
  47. data/modules/mu/config/msg_queue.rb +1 -1
  48. data/modules/mu/config/nosqldb.rb +1 -1
  49. data/modules/mu/config/notifier.rb +1 -1
  50. data/modules/mu/config/ref.rb +30 -4
  51. data/modules/mu/config/role.rb +1 -1
  52. data/modules/mu/config/schema_helpers.rb +30 -34
  53. data/modules/mu/config/search_domain.rb +1 -1
  54. data/modules/mu/config/server.rb +4 -12
  55. data/modules/mu/config/server_pool.rb +3 -7
  56. data/modules/mu/config/storage_pool.rb +1 -1
  57. data/modules/mu/config/tail.rb +10 -0
  58. data/modules/mu/config/user.rb +1 -1
  59. data/modules/mu/config/vpc.rb +12 -17
  60. data/modules/mu/defaults/AWS.yaml +32 -32
  61. data/modules/mu/defaults/Azure.yaml +1 -0
  62. data/modules/mu/defaults/Google.yaml +1 -0
  63. data/modules/mu/deploy.rb +16 -15
  64. data/modules/mu/groomer.rb +15 -0
  65. data/modules/mu/groomers/chef.rb +3 -0
  66. data/modules/mu/logger.rb +120 -144
  67. data/modules/mu/master.rb +1 -1
  68. data/modules/mu/mommacat.rb +54 -25
  69. data/modules/mu/mommacat/daemon.rb +10 -7
  70. data/modules/mu/mommacat/naming.rb +82 -3
  71. data/modules/mu/mommacat/search.rb +47 -15
  72. data/modules/mu/mommacat/storage.rb +72 -41
  73. data/modules/mu/{clouds → providers}/README.md +1 -1
  74. data/modules/mu/{clouds → providers}/aws.rb +114 -47
  75. data/modules/mu/{clouds → providers}/aws/alarm.rb +1 -1
  76. data/modules/mu/{clouds → providers}/aws/bucket.rb +2 -2
  77. data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +10 -46
  78. data/modules/mu/{clouds → providers}/aws/collection.rb +3 -3
  79. data/modules/mu/{clouds → providers}/aws/container_cluster.rb +15 -33
  80. data/modules/mu/providers/aws/database.rb +1744 -0
  81. data/modules/mu/{clouds → providers}/aws/dnszone.rb +2 -5
  82. data/modules/mu/{clouds → providers}/aws/endpoint.rb +2 -11
  83. data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +33 -29
  84. data/modules/mu/{clouds → providers}/aws/folder.rb +0 -0
  85. data/modules/mu/{clouds → providers}/aws/function.rb +2 -10
  86. data/modules/mu/{clouds → providers}/aws/group.rb +9 -13
  87. data/modules/mu/{clouds → providers}/aws/habitat.rb +1 -1
  88. data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +41 -33
  89. data/modules/mu/{clouds → providers}/aws/log.rb +2 -2
  90. data/modules/mu/{clouds → providers}/aws/msg_queue.rb +2 -8
  91. data/modules/mu/{clouds → providers}/aws/nosqldb.rb +0 -0
  92. data/modules/mu/{clouds → providers}/aws/notifier.rb +0 -0
  93. data/modules/mu/{clouds → providers}/aws/role.rb +7 -7
  94. data/modules/mu/{clouds → providers}/aws/search_domain.rb +8 -13
  95. data/modules/mu/{clouds → providers}/aws/server.rb +55 -90
  96. data/modules/mu/{clouds → providers}/aws/server_pool.rb +10 -33
  97. data/modules/mu/{clouds → providers}/aws/storage_pool.rb +19 -36
  98. data/modules/mu/{clouds → providers}/aws/user.rb +8 -12
  99. data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
  100. data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
  101. data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +0 -0
  102. data/modules/mu/{clouds → providers}/aws/vpc.rb +135 -70
  103. data/modules/mu/{clouds → providers}/aws/vpc_subnet.rb +0 -0
  104. data/modules/mu/{clouds → providers}/azure.rb +4 -1
  105. data/modules/mu/{clouds → providers}/azure/container_cluster.rb +1 -5
  106. data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +8 -1
  107. data/modules/mu/{clouds → providers}/azure/habitat.rb +0 -0
  108. data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +0 -0
  109. data/modules/mu/{clouds → providers}/azure/role.rb +0 -0
  110. data/modules/mu/{clouds → providers}/azure/server.rb +30 -23
  111. data/modules/mu/{clouds → providers}/azure/user.rb +1 -1
  112. data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
  113. data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
  114. data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
  115. data/modules/mu/{clouds → providers}/azure/vpc.rb +4 -6
  116. data/modules/mu/{clouds → providers}/cloudformation.rb +1 -1
  117. data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
  118. data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
  119. data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
  120. data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
  121. data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
  122. data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
  123. data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
  124. data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
  125. data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
  126. data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
  127. data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +3 -3
  128. data/modules/mu/{clouds → providers}/docker.rb +0 -0
  129. data/modules/mu/{clouds → providers}/google.rb +14 -6
  130. data/modules/mu/{clouds → providers}/google/bucket.rb +1 -1
  131. data/modules/mu/{clouds → providers}/google/container_cluster.rb +28 -13
  132. data/modules/mu/{clouds → providers}/google/database.rb +1 -8
  133. data/modules/mu/{clouds → providers}/google/firewall_rule.rb +2 -2
  134. data/modules/mu/{clouds → providers}/google/folder.rb +4 -8
  135. data/modules/mu/{clouds → providers}/google/function.rb +3 -3
  136. data/modules/mu/{clouds → providers}/google/group.rb +8 -16
  137. data/modules/mu/{clouds → providers}/google/habitat.rb +3 -7
  138. data/modules/mu/{clouds → providers}/google/loadbalancer.rb +1 -1
  139. data/modules/mu/{clouds → providers}/google/role.rb +42 -34
  140. data/modules/mu/{clouds → providers}/google/server.rb +25 -10
  141. data/modules/mu/{clouds → providers}/google/server_pool.rb +10 -10
  142. data/modules/mu/{clouds → providers}/google/user.rb +31 -21
  143. data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
  144. data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
  145. data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
  146. data/modules/mu/{clouds → providers}/google/vpc.rb +37 -2
  147. data/modules/tests/centos6.yaml +11 -0
  148. data/modules/tests/centos7.yaml +11 -0
  149. data/modules/tests/centos8.yaml +12 -0
  150. data/modules/tests/rds.yaml +108 -0
  151. data/modules/tests/regrooms/rds.yaml +123 -0
  152. data/spec/mu/clouds/azure_spec.rb +2 -2
  153. metadata +108 -89
  154. data/modules/mu/clouds/aws/database.rb +0 -1974
@@ -67,7 +67,7 @@ module MU
67
67
  if target['vpc']["subnet_name"]
68
68
  subnet_obj = vpc.getSubnet(name: target['vpc']["subnet_name"])
69
69
  if subnet_obj.nil?
70
- raise MuError, "Failed to locate subnet from #{subnet} in StoragePool #{@config['name']}:#{target['name']}"
70
+ raise MuError, "Failed to locate subnet from #{target['vpc']["subnet_name"]} in StoragePool #{@config['name']}:#{target['name']}"
71
71
  end
72
72
  target['vpc']['subnet_id'] = subnet_obj.cloud_id
73
73
  end
@@ -261,49 +261,29 @@ module MU
261
261
  targets = {}
262
262
 
263
263
  if @config['mount_points'] && !@config['mount_points'].empty?
264
+ mount_targets = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).describe_mount_targets(
265
+ file_system_id: storage_pool.file_system_id
266
+ ).mount_targets
267
+
264
268
  @config['mount_points'].each { |mp|
265
269
  subnet = nil
266
270
  dependencies
267
- mp_vpc = if mp['vpc'] and mp['vpc']['vpc_name']
268
- @deploy.findLitterMate(type: "vpc", name: mp['vpc']['vpc_name'], credentials: @config['credentials'])
269
- elsif mp['vpc']
270
- MU::MommaCat.findStray(
271
- @config['cloud'],
272
- "vpcs",
273
- deploy_id: mp['vpc']["deploy_id"],
274
- credentials: @config['credentials'],
275
- mu_name: mp['vpc']["mu_name"],
276
- cloud_id: mp['vpc']['vpc_id'],
277
- region: @config['region'],
278
- dummy_ok: false
279
- ).first
280
- # XXX non-sibling, findStray version
281
- end
271
+ mp_vpc = MU::Config::Ref.get(mp['vpc']).kitten
282
272
 
283
- mount_targets = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).describe_mount_targets(
284
- file_system_id: storage_pool.file_system_id
285
- ).mount_targets
286
273
 
287
- # subnet_obj = mp_vpc.subnets.select { |s|
288
- # s.name == mp["vpc"]["subnet_name"] or s.cloud_id == mp["vpc"]["subnet_id"]
289
- # }.first
274
+ subnet_obj = mp_vpc.subnets.select { |s|
275
+ s.name == mp["vpc"]["subnet_name"] or s.cloud_id == mp["vpc"]["subnet_id"]
276
+ }.first
290
277
  mount_target = nil
291
- mp_vpc.subnets.each { |subnet_obj|
292
- mount_targets.map { |t|
293
- subnet_cidr_obj = NetAddr::IPv4Net.parse(subnet_obj.ip_block)
294
- if subnet_cidr_obj.contains(NetAddr::IPv4.parse(t.ip_address))
295
- mount_target = t
296
- subnet = subnet_obj.cloud_desc
297
- end
298
- }
299
- break if mount_target
278
+ mount_targets.each { |t|
279
+ subnet_cidr_obj = NetAddr::IPv4Net.parse(subnet_obj.ip_block)
280
+ if subnet_cidr_obj.contains(NetAddr::IPv4.parse(t.ip_address))
281
+ mount_target = t
282
+ subnet = subnet_obj.cloud_desc
283
+ break
284
+ end
300
285
  }
301
286
 
302
- # mount_target = MU::Cloud::AWS.efs(region: @config['region'], credentials: @config['credentials']).describe_mount_targets(
303
- # mount_target_id: mp["cloud_id"]
304
- # ).mount_targets.first
305
-
306
-
307
287
  targets[mp["name"]] = {
308
288
  "owner_id" => mount_target.owner_id,
309
289
  "cloud_id" => mount_target.mount_target_id,
@@ -493,6 +473,9 @@ module MU
493
473
 
494
474
  if pool['mount_points'] && !pool['mount_points'].empty?
495
475
  pool['mount_points'].each{ |mp|
476
+ if mp['vpc'] and mp['vpc']['name']
477
+ MU::Config.addDependency(pool, mp['vpc']['name'], "vpc")
478
+ end
496
479
  if mp['ingress_rules']
497
480
  fwname = "storage-#{mp['name']}"
498
481
  acl = {
@@ -109,7 +109,7 @@ module MU
109
109
  # Create these if necessary, then append them to the list of
110
110
  # attachable_policies
111
111
  if @config['raw_policies']
112
- pol_arns = MU::Cloud::AWS::Role.manageRawPolicies(
112
+ pol_arns = MU::Cloud.resourceClass("AWS", "Role").manageRawPolicies(
113
113
  @config['raw_policies'],
114
114
  basename: @deploy.getResourceName(@config['name']),
115
115
  credentials: @credentials
@@ -135,7 +135,7 @@ module MU
135
135
  attached_policies.each { |a|
136
136
  if !configured_policies.include?(a.policy_arn)
137
137
  MU.log "Removing IAM policy #{a.policy_arn} from user #{@mu_name}", MU::NOTICE
138
- MU::Cloud::AWS::Role.purgePolicy(a.policy_arn, @credentials)
138
+ MU::Cloud.resourceClass("AWS", "Role").purgePolicy(a.policy_arn, @credentials)
139
139
  else
140
140
  configured_policies.delete(a.policy_arn)
141
141
  end
@@ -151,7 +151,7 @@ module MU
151
151
  end
152
152
 
153
153
  if @config['inline_policies']
154
- docs = MU::Cloud::AWS::Role.genPolicyDocument(@config['inline_policies'], deploy_obj: @deploy)
154
+ docs = MU::Cloud.resourceClass("AWS", "Role").genPolicyDocument(@config['inline_policies'], deploy_obj: @deploy)
155
155
  docs.each { |doc|
156
156
  MU.log "Putting user policy #{doc.keys.first} to user #{@cloud_id} "
157
157
  MU::Cloud::AWS.iam(credentials: @credentials).put_user_policy(
@@ -431,7 +431,7 @@ MU.log e.inspect, MU::ERR, details: policy
431
431
  resp.policy_names.each { |pol_name|
432
432
  pol = MU::Cloud::AWS.iam(credentials: @credentials).get_user_policy(user_name: @cloud_id, policy_name: pol_name)
433
433
  doc = JSON.parse(URI.decode(pol.policy_document))
434
- bok["inline_policies"] = MU::Cloud::AWS::Role.doc2MuPolicies(pol.policy_name, doc, bok["inline_policies"])
434
+ bok["inline_policies"] = MU::Cloud.resourceClass("AWS", "Role").doc2MuPolicies(pol.policy_name, doc, bok["inline_policies"])
435
435
  }
436
436
  end
437
437
 
@@ -465,7 +465,7 @@ MU.log e.inspect, MU::ERR, details: policy
465
465
  def self.schema(_config)
466
466
  toplevel_required = []
467
467
  polschema = MU::Config::Role.schema["properties"]["policies"]
468
- polschema.deep_merge!(MU::Cloud::AWS::Role.condition_schema)
468
+ polschema.deep_merge!(MU::Cloud.resourceClass("AWS", "Role").condition_schema)
469
469
 
470
470
  schema = {
471
471
  "inline_policies" => polschema,
@@ -517,7 +517,7 @@ style long name, like +IAMTESTS-DEV-2018112815-IS-USER-FOO+"
517
517
  # If we're attaching some managed policies, make sure all of the ones
518
518
  # that should already exist do indeed exist
519
519
  if user['attachable_policies']
520
- ok = false if !MU::Cloud::AWS::Role.validateAttachablePolicies(
520
+ ok = false if !MU::Cloud.resourceClass("AWS", "Role").validateAttachablePolicies(
521
521
  user['attachable_policies'],
522
522
  credentials: user['credentials'],
523
523
  region: user['region']
@@ -530,7 +530,7 @@ style long name, like +IAMTESTS-DEV-2018112815-IS-USER-FOO+"
530
530
  if configurator.haveLitterMate?(group, "groups")
531
531
  need_dependency = true
532
532
  else
533
- found = MU::Cloud::AWS::Group.find(cloud_id: group)
533
+ found = MU::Cloud.resourceClass("AWS", "Group").find(cloud_id: group)
534
534
  if found.nil? or found.empty? or (configurator.updating and
535
535
  found.values.first.group.path == "/"+configurator.updating+"/")
536
536
  groupdesc = {
@@ -542,11 +542,7 @@ style long name, like +IAMTESTS-DEV-2018112815-IS-USER-FOO+"
542
542
  end
543
543
 
544
544
  if need_dependency
545
- user["dependencies"] ||= []
546
- user["dependencies"] << {
547
- "type" => "group",
548
- "name" => group
549
- }
545
+ MU::Config.addDependency(user, group, "group")
550
546
  end
551
547
  }
552
548
  end
@@ -18,7 +18,7 @@ module MU
18
18
 
19
19
  # Creation of Virtual Private Clouds and associated artifacts (routes, subnets, etc).
20
20
  class VPC < MU::Cloud::VPC
21
- require 'mu/clouds/aws/vpc_subnet'
21
+ require 'mu/providers/aws/vpc_subnet'
22
22
 
23
23
  # Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like +@vpc+, for us.
24
24
  # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
@@ -209,7 +209,7 @@ module MU
209
209
  if !MU::Cloud::AWS.isGovCloud?(@config['region'])
210
210
  mu_zone = MU::Cloud::DNSZone.find(cloud_id: "platform-mu", credentials: @config['credentials']).values.first
211
211
  if !mu_zone.nil?
212
- MU::Cloud::AWS::DNSZone.toggleVPCAccess(id: mu_zone.id, vpc_id: @cloud_id, region: @config['region'], credentials: @config['credentials'])
212
+ MU::Cloud.resourceClass("AWS", "DNSZone").toggleVPCAccess(id: mu_zone.id, vpc_id: @cloud_id, region: @config['region'], credentials: @config['credentials'])
213
213
  end
214
214
  end
215
215
  loadSubnets
@@ -838,9 +838,23 @@ module MU
838
838
  vpcs = resp if !resp.empty?
839
839
  }
840
840
 
841
+ # resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_vpc_peering_connections(
842
+ # filters: [
843
+ # {
844
+ # name: "requester-vpc-info.vpc-id",
845
+ # values: [@cloud_id]
846
+ # },
847
+ # {
848
+ # name: "accepter-vpc-info.vpc-id",
849
+ # values: [peer_id.to_s]
850
+ # }
851
+ # ]
852
+ # )
853
+
841
854
  if !vpcs.empty?
842
855
  gwthreads = []
843
856
  vpcs.each { |vpc|
857
+ purge_peering_connections(noop, vpc.vpc_id, region: region, credentials: credentials)
844
858
  # NAT gateways don't have any tags, and we can't assign them a name. Lets find them based on a VPC ID
845
859
  gwthreads << Thread.new {
846
860
  purge_nat_gateways(noop, vpc_id: vpc.vpc_id, region: region, credentials: credentials)
@@ -916,11 +930,7 @@ module MU
916
930
  logdesc["tags"] = vpc["tags"] if !vpc["tags"].nil?
917
931
  # logdesc["optional_tags"] = vpc["optional_tags"] if !vpc["optional_tags"].nil?
918
932
  configurator.insertKitten(logdesc, "logs")
919
- vpc['dependencies'] ||= []
920
- vpc['dependencies'] << {
921
- "type" => "log",
922
- "name" => vpc['name']+"loggroup"
923
- }
933
+ MU::Config.addDependency(vpc, vpc['name']+"loggroup", "log")
924
934
 
925
935
  roledesc = {
926
936
  "name" => vpc['name']+"logrole",
@@ -958,11 +968,7 @@ module MU
958
968
  roledesc["tags"] = vpc["tags"] if !vpc["tags"].nil?
959
969
  roledesc["optional_tags"] = vpc["optional_tags"] if !vpc["optional_tags"].nil?
960
970
  configurator.insertKitten(roledesc, "roles")
961
- vpc['dependencies'] ||= []
962
- vpc['dependencies'] << {
963
- "type" => "role",
964
- "name" => vpc['name']+"logrole"
965
- }
971
+ MU::Config.addDependency(vpc, vpc['name']+"logrole", "role")
966
972
  end
967
973
 
968
974
  subnet_routes = Hash.new
@@ -1013,10 +1019,7 @@ module MU
1013
1019
  subnet_routes[table['name']].each { |subnet|
1014
1020
  nat_routes[subnet] = route['nat_host_name']
1015
1021
  }
1016
- vpc['dependencies'] << {
1017
- "type" => "server",
1018
- "name" => route['nat_host_name']
1019
- }
1022
+ MU::Config.addDependency(vpc, route['nat_host_name'], "server", no_create_wait: true)
1020
1023
  elsif route['gateway'] == '#NAT'
1021
1024
  vpc['create_nat_gateway'] = true
1022
1025
  private_rtbs << table['name']
@@ -1225,7 +1228,7 @@ module MU
1225
1228
  # suits me just fine
1226
1229
  rescue Aws::EC2::Errors::AuthFailure => e
1227
1230
  if !tried_lbs and iface.attachment.instance_owner_id == "amazon-elb"
1228
- MU::Cloud::AWS::LoadBalancer.cleanup(
1231
+ MU::Cloud.resourceClass("AWS", "LoadBalancer").cleanup(
1229
1232
  noop: noop,
1230
1233
  region: region,
1231
1234
  credentials: credentials,
@@ -1265,6 +1268,63 @@ module MU
1265
1268
  nil
1266
1269
  end
1267
1270
 
1271
+ # Try to locate the default VPC for a region, and return a BoK-style
1272
+ # config fragment for something that might want to live in it.
1273
+ def self.defaultVpc(region, credentials)
1274
+ cfg_fragment = nil
1275
+ MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_vpcs.vpcs.each { |vpc|
1276
+ if vpc.is_default
1277
+ cfg_fragment = {
1278
+ "id" => vpc.vpc_id,
1279
+ "cloud" => "AWS",
1280
+ "region" => region,
1281
+ "credentials" => credentials
1282
+ }
1283
+ cfg_fragment['subnets'] = MU::Cloud::AWS.ec2(region: region, credentials: credentials).describe_subnets(
1284
+ filters: [
1285
+ {
1286
+ name: "vpc-id",
1287
+ values: [vpc.vpc_id]
1288
+ }
1289
+ ]
1290
+ ).subnets.map { |s| { "subnet_id" => s.subnet_id } }
1291
+ break
1292
+ end
1293
+ }
1294
+
1295
+ cfg_fragment
1296
+ end
1297
+
1298
+ # Return a {MU::Config::Ref} that indicates this VPC.
1299
+ # @param subnet_ids [Array<String>]: Optional list of subnet ids with which to infer a +subnet_pref+ parameter.
1300
+ # @return [MU::Config::Ref]
1301
+ def getReference(subnet_ids = [])
1302
+ have_private = have_public = false
1303
+ subnets.each { |s|
1304
+ next if subnet_ids and !subnet_ids.empty? and !subnet_ids.include?(s.cloud_id)
1305
+ if s.private?
1306
+ have_private = true
1307
+ else
1308
+ have_public = true
1309
+ end
1310
+ }
1311
+ subnet_pref = if have_private == have_public
1312
+ "any"
1313
+ elsif have_private
1314
+ "all_private"
1315
+ elsif have_public
1316
+ "all_public"
1317
+ end
1318
+ MU::Config::Ref.get(
1319
+ id: @cloud_id,
1320
+ cloud: "AWS",
1321
+ credentials: @credentials,
1322
+ region: @config['region'],
1323
+ type: "vpcs",
1324
+ subnet_pref: subnet_pref
1325
+ )
1326
+ end
1327
+
1268
1328
  private
1269
1329
 
1270
1330
  def peerWith(peer)
@@ -1683,6 +1743,61 @@ module MU
1683
1743
  end
1684
1744
  private_class_method :purge_dhcpopts
1685
1745
 
1746
+ def self.purge_peering_connections(noop, vpc_id, region: MU.curRegion, credentials: nil)
1747
+ my_peer_conns = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_peering_connections(
1748
+ filters: [
1749
+ {
1750
+ name: "requester-vpc-info.vpc-id",
1751
+ values: [vpc_id]
1752
+ }
1753
+ ]
1754
+ ).vpc_peering_connections
1755
+ my_peer_conns.concat(MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_peering_connections(
1756
+ filters: [
1757
+ {
1758
+ name: "accepter-vpc-info.vpc-id",
1759
+ values: [vpc_id]
1760
+ }
1761
+ ]
1762
+ ).vpc_peering_connections)
1763
+
1764
+ my_peer_conns.each { |cnxn|
1765
+ [cnxn.accepter_vpc_info.vpc_id, cnxn.requester_vpc_info.vpc_id].each { |peer_vpc|
1766
+ MU::Cloud::AWS::VPC.listAllSubnetRouteTables(peer_vpc, region: region, credentials: credentials).each { |rtb_id|
1767
+ begin
1768
+ resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_route_tables(
1769
+ route_table_ids: [rtb_id]
1770
+ )
1771
+ rescue Aws::EC2::Errors::InvalidRouteTableIDNotFound
1772
+ next
1773
+ end
1774
+ resp.route_tables.each { |rtb|
1775
+ rtb.routes.each { |route|
1776
+ if route.vpc_peering_connection_id == cnxn.vpc_peering_connection_id
1777
+ MU.log "Removing route #{route.destination_cidr_block} from route table #{rtb_id} in VPC #{peer_vpc}"
1778
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_route(
1779
+ route_table_id: rtb_id,
1780
+ destination_cidr_block: route.destination_cidr_block
1781
+ ) if !noop
1782
+ end
1783
+ }
1784
+ }
1785
+ }
1786
+ }
1787
+ MU.log "Deleting VPC peering connection #{cnxn.vpc_peering_connection_id}"
1788
+ begin
1789
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_vpc_peering_connection(
1790
+ vpc_peering_connection_id: cnxn.vpc_peering_connection_id
1791
+ ) if !noop
1792
+ rescue Aws::EC2::Errors::InvalidStateTransition
1793
+ MU.log "VPC peering connection #{cnxn.vpc_peering_connection_id} not in removable (state #{cnxn.status.code})", MU::WARN
1794
+ rescue Aws::EC2::Errors::OperationNotPermitted => e
1795
+ MU.log "VPC peering connection #{cnxn.vpc_peering_connection_id} refuses to delete: #{e.message}", MU::WARN
1796
+ end
1797
+ }
1798
+ end
1799
+ private_class_method :purge_peering_connections
1800
+
1686
1801
  # Remove all VPCs associated with the currently loaded deployment.
1687
1802
  # @param noop [Boolean]: If true, will only print what would be done
1688
1803
  # @param tagfilters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
@@ -1697,60 +1812,10 @@ module MU
1697
1812
  return if vpcs.nil? or vpcs.size == 0
1698
1813
 
1699
1814
  vpcs.each { |vpc|
1700
- my_peer_conns = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_peering_connections(
1701
- filters: [
1702
- {
1703
- name: "requester-vpc-info.vpc-id",
1704
- values: [vpc.vpc_id]
1705
- }
1706
- ]
1707
- ).vpc_peering_connections
1708
- my_peer_conns.concat(MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_vpc_peering_connections(
1709
- filters: [
1710
- {
1711
- name: "accepter-vpc-info.vpc-id",
1712
- values: [vpc.vpc_id]
1713
- }
1714
- ]
1715
- ).vpc_peering_connections)
1716
- my_peer_conns.each { |cnxn|
1717
-
1718
- [cnxn.accepter_vpc_info.vpc_id, cnxn.requester_vpc_info.vpc_id].each { |peer_vpc|
1719
- MU::Cloud::AWS::VPC.listAllSubnetRouteTables(peer_vpc, region: region, credentials: credentials).each { |rtb_id|
1720
- begin
1721
- resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_route_tables(
1722
- route_table_ids: [rtb_id]
1723
- )
1724
- rescue Aws::EC2::Errors::InvalidRouteTableIDNotFound
1725
- next
1726
- end
1727
- resp.route_tables.each { |rtb|
1728
- rtb.routes.each { |route|
1729
- if route.vpc_peering_connection_id == cnxn.vpc_peering_connection_id
1730
- MU.log "Removing route #{route.destination_cidr_block} from route table #{rtb_id} in VPC #{peer_vpc}"
1731
- MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_route(
1732
- route_table_id: rtb_id,
1733
- destination_cidr_block: route.destination_cidr_block
1734
- ) if !noop
1735
- end
1736
- }
1737
- }
1738
- }
1739
- }
1740
- MU.log "Deleting VPC peering connection #{cnxn.vpc_peering_connection_id}"
1741
- begin
1742
- MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_vpc_peering_connection(
1743
- vpc_peering_connection_id: cnxn.vpc_peering_connection_id
1744
- ) if !noop
1745
- rescue Aws::EC2::Errors::InvalidStateTransition
1746
- MU.log "VPC peering connection #{cnxn.vpc_peering_connection_id} not in removable (state #{cnxn.status.code})", MU::WARN
1747
- rescue Aws::EC2::Errors::OperationNotPermitted => e
1748
- MU.log "VPC peering connection #{cnxn.vpc_peering_connection_id} refuses to delete: #{e.message}", MU::WARN
1749
- end
1750
- }
1815
+ purge_peering_connections(noop, vpc.vpc_id, region: region, credentials: credentials)
1751
1816
 
1752
1817
  on_retry = Proc.new {
1753
- MU::Cloud::AWS::FirewallRule.cleanup(
1818
+ MU::Cloud.resourceClass("AWS", "FirewallRule").cleanup(
1754
1819
  noop: noop,
1755
1820
  region: region,
1756
1821
  credentials: credentials,
@@ -1767,7 +1832,7 @@ module MU
1767
1832
  if !MU::Cloud::AWS.isGovCloud?(region)
1768
1833
  mu_zone = MU::Cloud::DNSZone.find(cloud_id: "platform-mu", region: region, credentials: credentials).values.first
1769
1834
  if !mu_zone.nil?
1770
- MU::Cloud::AWS::DNSZone.toggleVPCAccess(id: mu_zone.id, vpc_id: vpc.vpc_id, remove: true, credentials: credentials)
1835
+ MU::Cloud.resourceClass("AWS", "DNSZone").toggleVPCAccess(id: mu_zone.id, vpc_id: vpc.vpc_id, remove: true, credentials: credentials)
1771
1836
  end
1772
1837
  end
1773
1838
  }
@@ -48,7 +48,7 @@ module MU
48
48
  end
49
49
 
50
50
  # List all Azure subscriptions available to our credentials
51
- def self.listHabitats(credentials = nil)
51
+ def self.listHabitats(credentials = nil, use_cache: true)
52
52
  []
53
53
  end
54
54
 
@@ -284,6 +284,9 @@ module MU
284
284
  end
285
285
  raise e
286
286
  end
287
+ if !sdk_response
288
+ raise MuError, "Nil response from Azure API attempting list_locations(#{subscription})"
289
+ end
287
290
 
288
291
  sdk_response.value.each do | region |
289
292
  @@regions.push(region.name)