cloud-mu 2.1.0beta → 3.0.0beta

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.
Files changed (291) hide show
  1. checksums.yaml +5 -5
  2. data/Berksfile +4 -5
  3. data/Berksfile.lock +179 -0
  4. data/README.md +1 -6
  5. data/ansible/roles/geerlingguy.firewall/templates/firewall.bash.j2 +0 -0
  6. data/ansible/roles/mu-installer/README.md +33 -0
  7. data/ansible/roles/mu-installer/defaults/main.yml +2 -0
  8. data/ansible/roles/mu-installer/handlers/main.yml +2 -0
  9. data/ansible/roles/mu-installer/meta/main.yml +60 -0
  10. data/ansible/roles/mu-installer/tasks/main.yml +13 -0
  11. data/ansible/roles/mu-installer/tests/inventory +2 -0
  12. data/ansible/roles/mu-installer/tests/test.yml +5 -0
  13. data/ansible/roles/mu-installer/vars/main.yml +2 -0
  14. data/bin/mu-adopt +125 -0
  15. data/bin/mu-aws-setup +4 -4
  16. data/bin/mu-azure-setup +265 -0
  17. data/bin/mu-azure-tests +43 -0
  18. data/bin/mu-cleanup +20 -8
  19. data/bin/mu-configure +224 -98
  20. data/bin/mu-deploy +8 -3
  21. data/bin/mu-gcp-setup +16 -8
  22. data/bin/mu-gen-docs +92 -8
  23. data/bin/mu-load-config.rb +52 -12
  24. data/bin/mu-momma-cat +36 -0
  25. data/bin/mu-node-manage +34 -27
  26. data/bin/mu-self-update +2 -2
  27. data/bin/mu-ssh +12 -8
  28. data/bin/mu-upload-chef-artifacts +11 -4
  29. data/bin/mu-user-manage +3 -0
  30. data/cloud-mu.gemspec +8 -11
  31. data/cookbooks/firewall/libraries/helpers_iptables.rb +2 -2
  32. data/cookbooks/firewall/metadata.json +1 -1
  33. data/cookbooks/firewall/recipes/default.rb +5 -9
  34. data/cookbooks/mu-firewall/attributes/default.rb +2 -0
  35. data/cookbooks/mu-firewall/metadata.rb +1 -1
  36. data/cookbooks/mu-glusterfs/templates/default/mu-gluster-client.erb +0 -0
  37. data/cookbooks/mu-master/Berksfile +2 -2
  38. data/cookbooks/mu-master/files/default/check_mem.pl +0 -0
  39. data/cookbooks/mu-master/files/default/cloudamatic.png +0 -0
  40. data/cookbooks/mu-master/metadata.rb +5 -4
  41. data/cookbooks/mu-master/recipes/389ds.rb +1 -1
  42. data/cookbooks/mu-master/recipes/basepackages.rb +30 -10
  43. data/cookbooks/mu-master/recipes/default.rb +59 -7
  44. data/cookbooks/mu-master/recipes/firewall-holes.rb +1 -1
  45. data/cookbooks/mu-master/recipes/init.rb +65 -47
  46. data/cookbooks/mu-master/recipes/{eks-kubectl.rb → kubectl.rb} +4 -10
  47. data/cookbooks/mu-master/recipes/sssd.rb +2 -1
  48. data/cookbooks/mu-master/recipes/update_nagios_only.rb +6 -6
  49. data/cookbooks/mu-master/templates/default/web_app.conf.erb +2 -2
  50. data/cookbooks/mu-master/templates/mods/ldap.conf.erb +4 -0
  51. data/cookbooks/mu-php54/Berksfile +1 -2
  52. data/cookbooks/mu-php54/metadata.rb +4 -5
  53. data/cookbooks/mu-php54/recipes/default.rb +1 -1
  54. data/cookbooks/mu-splunk/templates/default/splunk-init.erb +0 -0
  55. data/cookbooks/mu-tools/Berksfile +3 -2
  56. data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
  57. data/cookbooks/mu-tools/libraries/helper.rb +20 -8
  58. data/cookbooks/mu-tools/metadata.rb +5 -2
  59. data/cookbooks/mu-tools/recipes/apply_security.rb +2 -3
  60. data/cookbooks/mu-tools/recipes/eks.rb +1 -1
  61. data/cookbooks/mu-tools/recipes/gcloud.rb +5 -30
  62. data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
  63. data/cookbooks/mu-tools/recipes/rsyslog.rb +1 -0
  64. data/cookbooks/mu-tools/recipes/selinux.rb +19 -0
  65. data/cookbooks/mu-tools/recipes/split_var_partitions.rb +0 -1
  66. data/cookbooks/mu-tools/recipes/windows-client.rb +256 -122
  67. data/cookbooks/mu-tools/resources/disk.rb +3 -1
  68. data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +1 -1
  69. data/cookbooks/mu-tools/templates/default/etc_hosts.erb +1 -1
  70. data/cookbooks/mu-tools/templates/default/{kubeconfig.erb → kubeconfig-eks.erb} +0 -0
  71. data/cookbooks/mu-tools/templates/default/kubeconfig-gke.erb +27 -0
  72. data/cookbooks/mu-tools/templates/windows-10/sshd_config.erb +137 -0
  73. data/cookbooks/mu-utility/recipes/nat.rb +4 -0
  74. data/extras/alpha.png +0 -0
  75. data/extras/beta.png +0 -0
  76. data/extras/clean-stock-amis +2 -2
  77. data/extras/generate-stock-images +131 -0
  78. data/extras/git-fix-permissions-hook +0 -0
  79. data/extras/image-generators/AWS/centos6.yaml +17 -0
  80. data/extras/image-generators/{aws → AWS}/centos7-govcloud.yaml +0 -0
  81. data/extras/image-generators/{aws → AWS}/centos7.yaml +0 -0
  82. data/extras/image-generators/{aws → AWS}/rhel7.yaml +0 -0
  83. data/extras/image-generators/{aws → AWS}/win2k12.yaml +0 -0
  84. data/extras/image-generators/{aws → AWS}/win2k16.yaml +0 -0
  85. data/extras/image-generators/{aws → AWS}/windows.yaml +0 -0
  86. data/extras/image-generators/{gcp → Google}/centos6.yaml +1 -0
  87. data/extras/image-generators/Google/centos7.yaml +18 -0
  88. data/extras/python_rpm/build.sh +0 -0
  89. data/extras/release.png +0 -0
  90. data/extras/ruby_rpm/build.sh +0 -0
  91. data/extras/ruby_rpm/muby.spec +1 -1
  92. data/install/README.md +43 -5
  93. data/install/deprecated-bash-library.sh +0 -0
  94. data/install/installer +1 -1
  95. data/install/jenkinskeys.rb +0 -0
  96. data/install/mu-master.yaml +55 -0
  97. data/modules/mommacat.ru +41 -7
  98. data/modules/mu.rb +444 -149
  99. data/modules/mu/adoption.rb +500 -0
  100. data/modules/mu/cleanup.rb +235 -158
  101. data/modules/mu/cloud.rb +675 -138
  102. data/modules/mu/clouds/aws.rb +156 -24
  103. data/modules/mu/clouds/aws/alarm.rb +4 -14
  104. data/modules/mu/clouds/aws/bucket.rb +60 -18
  105. data/modules/mu/clouds/aws/cache_cluster.rb +8 -20
  106. data/modules/mu/clouds/aws/collection.rb +12 -22
  107. data/modules/mu/clouds/aws/container_cluster.rb +209 -118
  108. data/modules/mu/clouds/aws/database.rb +120 -45
  109. data/modules/mu/clouds/aws/dnszone.rb +7 -18
  110. data/modules/mu/clouds/aws/endpoint.rb +5 -15
  111. data/modules/mu/clouds/aws/firewall_rule.rb +144 -72
  112. data/modules/mu/clouds/aws/folder.rb +4 -11
  113. data/modules/mu/clouds/aws/function.rb +6 -16
  114. data/modules/mu/clouds/aws/group.rb +4 -12
  115. data/modules/mu/clouds/aws/habitat.rb +11 -13
  116. data/modules/mu/clouds/aws/loadbalancer.rb +40 -28
  117. data/modules/mu/clouds/aws/log.rb +5 -13
  118. data/modules/mu/clouds/aws/msg_queue.rb +9 -24
  119. data/modules/mu/clouds/aws/nosqldb.rb +4 -12
  120. data/modules/mu/clouds/aws/notifier.rb +6 -13
  121. data/modules/mu/clouds/aws/role.rb +69 -40
  122. data/modules/mu/clouds/aws/search_domain.rb +17 -20
  123. data/modules/mu/clouds/aws/server.rb +184 -94
  124. data/modules/mu/clouds/aws/server_pool.rb +33 -38
  125. data/modules/mu/clouds/aws/storage_pool.rb +5 -12
  126. data/modules/mu/clouds/aws/user.rb +59 -33
  127. data/modules/mu/clouds/aws/userdata/linux.erb +18 -30
  128. data/modules/mu/clouds/aws/userdata/windows.erb +9 -9
  129. data/modules/mu/clouds/aws/vpc.rb +214 -145
  130. data/modules/mu/clouds/azure.rb +978 -44
  131. data/modules/mu/clouds/azure/container_cluster.rb +413 -0
  132. data/modules/mu/clouds/azure/firewall_rule.rb +500 -0
  133. data/modules/mu/clouds/azure/habitat.rb +167 -0
  134. data/modules/mu/clouds/azure/loadbalancer.rb +205 -0
  135. data/modules/mu/clouds/azure/role.rb +211 -0
  136. data/modules/mu/clouds/azure/server.rb +810 -0
  137. data/modules/mu/clouds/azure/user.rb +257 -0
  138. data/modules/mu/clouds/azure/userdata/README.md +4 -0
  139. data/modules/mu/clouds/azure/userdata/linux.erb +137 -0
  140. data/modules/mu/clouds/azure/userdata/windows.erb +275 -0
  141. data/modules/mu/clouds/azure/vpc.rb +782 -0
  142. data/modules/mu/clouds/cloudformation.rb +12 -9
  143. data/modules/mu/clouds/cloudformation/firewall_rule.rb +5 -13
  144. data/modules/mu/clouds/cloudformation/server.rb +10 -1
  145. data/modules/mu/clouds/cloudformation/server_pool.rb +1 -0
  146. data/modules/mu/clouds/cloudformation/vpc.rb +0 -2
  147. data/modules/mu/clouds/google.rb +554 -117
  148. data/modules/mu/clouds/google/bucket.rb +173 -32
  149. data/modules/mu/clouds/google/container_cluster.rb +1112 -157
  150. data/modules/mu/clouds/google/database.rb +24 -47
  151. data/modules/mu/clouds/google/firewall_rule.rb +344 -89
  152. data/modules/mu/clouds/google/folder.rb +156 -79
  153. data/modules/mu/clouds/google/group.rb +272 -82
  154. data/modules/mu/clouds/google/habitat.rb +177 -52
  155. data/modules/mu/clouds/google/loadbalancer.rb +9 -34
  156. data/modules/mu/clouds/google/role.rb +1211 -0
  157. data/modules/mu/clouds/google/server.rb +491 -227
  158. data/modules/mu/clouds/google/server_pool.rb +233 -48
  159. data/modules/mu/clouds/google/user.rb +479 -125
  160. data/modules/mu/clouds/google/userdata/linux.erb +3 -3
  161. data/modules/mu/clouds/google/userdata/windows.erb +9 -9
  162. data/modules/mu/clouds/google/vpc.rb +381 -223
  163. data/modules/mu/config.rb +689 -214
  164. data/modules/mu/config/bucket.rb +1 -1
  165. data/modules/mu/config/cache_cluster.rb +1 -1
  166. data/modules/mu/config/cache_cluster.yml +0 -4
  167. data/modules/mu/config/container_cluster.rb +18 -9
  168. data/modules/mu/config/database.rb +6 -23
  169. data/modules/mu/config/firewall_rule.rb +9 -15
  170. data/modules/mu/config/folder.rb +22 -21
  171. data/modules/mu/config/habitat.rb +22 -21
  172. data/modules/mu/config/loadbalancer.rb +2 -2
  173. data/modules/mu/config/role.rb +9 -40
  174. data/modules/mu/config/server.rb +26 -5
  175. data/modules/mu/config/server_pool.rb +1 -1
  176. data/modules/mu/config/storage_pool.rb +2 -2
  177. data/modules/mu/config/user.rb +4 -0
  178. data/modules/mu/config/vpc.rb +350 -110
  179. data/modules/mu/defaults/{amazon_images.yaml → AWS.yaml} +37 -39
  180. data/modules/mu/defaults/Azure.yaml +17 -0
  181. data/modules/mu/defaults/Google.yaml +24 -0
  182. data/modules/mu/defaults/README.md +1 -1
  183. data/modules/mu/deploy.rb +168 -125
  184. data/modules/mu/groomer.rb +2 -1
  185. data/modules/mu/groomers/ansible.rb +104 -32
  186. data/modules/mu/groomers/chef.rb +96 -44
  187. data/modules/mu/kittens.rb +20602 -0
  188. data/modules/mu/logger.rb +38 -11
  189. data/modules/mu/master.rb +90 -8
  190. data/modules/mu/master/chef.rb +2 -3
  191. data/modules/mu/master/ldap.rb +0 -1
  192. data/modules/mu/master/ssl.rb +250 -0
  193. data/modules/mu/mommacat.rb +917 -513
  194. data/modules/scratchpad.erb +1 -1
  195. data/modules/tests/super_complex_bok.yml +0 -0
  196. data/modules/tests/super_simple_bok.yml +0 -0
  197. data/roles/mu-master.json +2 -1
  198. data/spec/azure_creds +5 -0
  199. data/spec/mu.yaml +56 -0
  200. data/spec/mu/clouds/azure_spec.rb +164 -27
  201. data/spec/spec_helper.rb +5 -0
  202. data/test/clean_up.py +0 -0
  203. data/test/exec_inspec.py +0 -0
  204. data/test/exec_mu_install.py +0 -0
  205. data/test/exec_retry.py +0 -0
  206. data/test/smoke_test.rb +0 -0
  207. metadata +90 -118
  208. data/cookbooks/mu-jenkins/Berksfile +0 -14
  209. data/cookbooks/mu-jenkins/CHANGELOG.md +0 -13
  210. data/cookbooks/mu-jenkins/LICENSE +0 -37
  211. data/cookbooks/mu-jenkins/README.md +0 -105
  212. data/cookbooks/mu-jenkins/attributes/default.rb +0 -42
  213. data/cookbooks/mu-jenkins/files/default/cleanup_deploy_config.xml +0 -73
  214. data/cookbooks/mu-jenkins/files/default/deploy_config.xml +0 -44
  215. data/cookbooks/mu-jenkins/metadata.rb +0 -21
  216. data/cookbooks/mu-jenkins/recipes/default.rb +0 -195
  217. data/cookbooks/mu-jenkins/recipes/node-ssh-config.rb +0 -54
  218. data/cookbooks/mu-jenkins/recipes/public_key.rb +0 -24
  219. data/cookbooks/mu-jenkins/templates/default/example_job.config.xml.erb +0 -24
  220. data/cookbooks/mu-jenkins/templates/default/org.jvnet.hudson.plugins.SSHBuildWrapper.xml.erb +0 -14
  221. data/cookbooks/mu-jenkins/templates/default/ssh_config.erb +0 -6
  222. data/cookbooks/nagios/Berksfile +0 -11
  223. data/cookbooks/nagios/CHANGELOG.md +0 -589
  224. data/cookbooks/nagios/CONTRIBUTING.md +0 -11
  225. data/cookbooks/nagios/LICENSE +0 -37
  226. data/cookbooks/nagios/README.md +0 -328
  227. data/cookbooks/nagios/TESTING.md +0 -2
  228. data/cookbooks/nagios/attributes/config.rb +0 -171
  229. data/cookbooks/nagios/attributes/default.rb +0 -228
  230. data/cookbooks/nagios/chefignore +0 -102
  231. data/cookbooks/nagios/definitions/command.rb +0 -33
  232. data/cookbooks/nagios/definitions/contact.rb +0 -33
  233. data/cookbooks/nagios/definitions/contactgroup.rb +0 -33
  234. data/cookbooks/nagios/definitions/host.rb +0 -33
  235. data/cookbooks/nagios/definitions/hostdependency.rb +0 -33
  236. data/cookbooks/nagios/definitions/hostescalation.rb +0 -34
  237. data/cookbooks/nagios/definitions/hostgroup.rb +0 -33
  238. data/cookbooks/nagios/definitions/nagios_conf.rb +0 -38
  239. data/cookbooks/nagios/definitions/resource.rb +0 -33
  240. data/cookbooks/nagios/definitions/service.rb +0 -33
  241. data/cookbooks/nagios/definitions/servicedependency.rb +0 -33
  242. data/cookbooks/nagios/definitions/serviceescalation.rb +0 -34
  243. data/cookbooks/nagios/definitions/servicegroup.rb +0 -33
  244. data/cookbooks/nagios/definitions/timeperiod.rb +0 -33
  245. data/cookbooks/nagios/libraries/base.rb +0 -314
  246. data/cookbooks/nagios/libraries/command.rb +0 -91
  247. data/cookbooks/nagios/libraries/contact.rb +0 -230
  248. data/cookbooks/nagios/libraries/contactgroup.rb +0 -112
  249. data/cookbooks/nagios/libraries/custom_option.rb +0 -36
  250. data/cookbooks/nagios/libraries/data_bag_helper.rb +0 -23
  251. data/cookbooks/nagios/libraries/default.rb +0 -90
  252. data/cookbooks/nagios/libraries/host.rb +0 -412
  253. data/cookbooks/nagios/libraries/hostdependency.rb +0 -181
  254. data/cookbooks/nagios/libraries/hostescalation.rb +0 -173
  255. data/cookbooks/nagios/libraries/hostgroup.rb +0 -119
  256. data/cookbooks/nagios/libraries/nagios.rb +0 -282
  257. data/cookbooks/nagios/libraries/resource.rb +0 -59
  258. data/cookbooks/nagios/libraries/service.rb +0 -455
  259. data/cookbooks/nagios/libraries/servicedependency.rb +0 -215
  260. data/cookbooks/nagios/libraries/serviceescalation.rb +0 -195
  261. data/cookbooks/nagios/libraries/servicegroup.rb +0 -144
  262. data/cookbooks/nagios/libraries/timeperiod.rb +0 -160
  263. data/cookbooks/nagios/libraries/users_helper.rb +0 -54
  264. data/cookbooks/nagios/metadata.rb +0 -25
  265. data/cookbooks/nagios/recipes/_load_databag_config.rb +0 -153
  266. data/cookbooks/nagios/recipes/_load_default_config.rb +0 -241
  267. data/cookbooks/nagios/recipes/apache.rb +0 -48
  268. data/cookbooks/nagios/recipes/default.rb +0 -204
  269. data/cookbooks/nagios/recipes/nginx.rb +0 -82
  270. data/cookbooks/nagios/recipes/pagerduty.rb +0 -143
  271. data/cookbooks/nagios/recipes/server_package.rb +0 -40
  272. data/cookbooks/nagios/recipes/server_source.rb +0 -164
  273. data/cookbooks/nagios/templates/default/apache2.conf.erb +0 -96
  274. data/cookbooks/nagios/templates/default/cgi.cfg.erb +0 -266
  275. data/cookbooks/nagios/templates/default/commands.cfg.erb +0 -13
  276. data/cookbooks/nagios/templates/default/contacts.cfg.erb +0 -37
  277. data/cookbooks/nagios/templates/default/hostgroups.cfg.erb +0 -25
  278. data/cookbooks/nagios/templates/default/hosts.cfg.erb +0 -15
  279. data/cookbooks/nagios/templates/default/htpasswd.users.erb +0 -6
  280. data/cookbooks/nagios/templates/default/nagios.cfg.erb +0 -22
  281. data/cookbooks/nagios/templates/default/nginx.conf.erb +0 -62
  282. data/cookbooks/nagios/templates/default/pagerduty.cgi.erb +0 -185
  283. data/cookbooks/nagios/templates/default/resource.cfg.erb +0 -27
  284. data/cookbooks/nagios/templates/default/servicedependencies.cfg.erb +0 -15
  285. data/cookbooks/nagios/templates/default/servicegroups.cfg.erb +0 -14
  286. data/cookbooks/nagios/templates/default/services.cfg.erb +0 -14
  287. data/cookbooks/nagios/templates/default/templates.cfg.erb +0 -31
  288. data/cookbooks/nagios/templates/default/timeperiods.cfg.erb +0 -13
  289. data/extras/image-generators/aws/centos6.yaml +0 -18
  290. data/modules/mu/defaults/google_images.yaml +0 -16
  291. data/roles/mu-master-jenkins.json +0 -24
@@ -19,28 +19,16 @@ module MU
19
19
  # Creation of Virtual Private Clouds and associated artifacts (routes, subnets, etc).
20
20
  class VPC < MU::Cloud::VPC
21
21
 
22
- @deploy = nil
23
- @config = nil
24
- attr_reader :mu_name
25
- attr_reader :cloud_id
26
- attr_reader :config
27
-
28
- # @param mommacat [MU::MommaCat]: A {MU::Mommacat} object containing the deploy of which this resource is/will be a member.
29
- # @param kitten_cfg [Hash]: The fully parsed and resolved {MU::Config} resource descriptor as defined in {MU::Config::BasketofKittens::vpcs}
30
- def initialize(mommacat: nil, kitten_cfg: nil, mu_name: nil, cloud_id: nil)
31
- @deploy = mommacat
32
- @config = MU::Config.manxify(kitten_cfg)
22
+ # 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.
23
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
24
+ def initialize(**args)
25
+ super
33
26
  @subnets = []
34
27
  @subnetcachesemaphore = Mutex.new
35
- @cloud_id = cloud_id
36
- if !mu_name.nil?
37
- @mu_name = mu_name
38
- loadSubnets if !@cloud_id.nil?
39
- elsif @config['scrub_mu_isms']
40
- @mu_name = @config['name']
41
- else
42
- @mu_name = @deploy.getResourceName(@config['name'])
43
- end
28
+
29
+ loadSubnets if !@cloud_id.nil?
30
+
31
+ @mu_name ||= @deploy.getResourceName(@config['name'])
44
32
  end
45
33
 
46
34
  # Called automatically by {MU::Deploy#createResources}
@@ -49,7 +37,7 @@ module MU
49
37
  resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_vpc(cidr_block: @config['ip_block']).vpc
50
38
  vpc_id = @config['vpc_id'] = resp.vpc_id
51
39
 
52
- MU::MommaCat.createStandardTags(vpc_id, region: @config['region'], credentials: @config['credentials'])
40
+ MU::Cloud::AWS.createStandardTags(vpc_id, region: @config['region'], credentials: @config['credentials'])
53
41
  MU::MommaCat.createTag(vpc_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
54
42
 
55
43
  if @config['tags']
@@ -87,7 +75,7 @@ module MU
87
75
  }
88
76
  end
89
77
 
90
- MU::MommaCat.createStandardTags(rtb.route_table_id, region: @config['region'], credentials: @config['credentials'])
78
+ MU::Cloud::AWS.createStandardTags(rtb.route_table_id, region: @config['region'], credentials: @config['credentials'])
91
79
 
92
80
  if @config['optional_tags']
93
81
  MU::MommaCat.listOptionalTags.each { |key, value|
@@ -104,7 +92,7 @@ module MU
104
92
  resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_internet_gateway
105
93
  internet_gateway_id = resp.internet_gateway.internet_gateway_id
106
94
  sleep 5
107
- MU::MommaCat.createStandardTags(internet_gateway_id, region: @config['region'], credentials: @config['credentials'])
95
+ MU::Cloud::AWS.createStandardTags(internet_gateway_id, region: @config['region'], credentials: @config['credentials'])
108
96
  MU::MommaCat.createTag(internet_gateway_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
109
97
  if @config['tags']
110
98
  @config['tags'].each { |tag|
@@ -202,7 +190,7 @@ module MU
202
190
  availability_zone: az
203
191
  ).subnet
204
192
  subnet_id = subnet['subnet_id'] = resp.subnet_id
205
- MU::MommaCat.createStandardTags(subnet_id, region: @config['region'], credentials: @config['credentials'])
193
+ MU::Cloud::AWS.createStandardTags(subnet_id, region: @config['region'], credentials: @config['credentials'])
206
194
  MU::MommaCat.createTag(subnet_id, "Name", @mu_name+"-"+subnet['name'], region: @config['region'], credentials: @config['credentials'])
207
195
  if @config['tags']
208
196
  @config['tags'].each { |tag|
@@ -448,7 +436,7 @@ module MU
448
436
  dhcp_configurations: dhcpopts
449
437
  )
450
438
  dhcpopt_id = resp.dhcp_options.dhcp_options_id
451
- MU::MommaCat.createStandardTags(dhcpopt_id, region: @config['region'], credentials: @config['credentials'])
439
+ MU::Cloud::AWS.createStandardTags(dhcpopt_id, region: @config['region'], credentials: @config['credentials'])
452
440
  MU::MommaCat.createTag(dhcpopt_id, "Name", @mu_name, region: @config['region'], credentials: @config['credentials'])
453
441
 
454
442
  if @config['tags']
@@ -481,6 +469,9 @@ module MU
481
469
  # Canonical Amazon Resource Number for this resource
482
470
  # @return [String]
483
471
  def arn
472
+ puts @config['region']
473
+ puts MU::Cloud::AWS.credToAcct(@config['credentials'])
474
+ puts @cloud_id
484
475
  "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":ec2:"+@config['region']+":"+MU::Cloud::AWS.credToAcct(@config['credentials'])+":vpc/"+@cloud_id
485
476
  end
486
477
 
@@ -499,57 +490,77 @@ module MU
499
490
  @config['peers'].each { |peer|
500
491
  peer_obj = nil
501
492
  peer_id = nil
502
-
503
- begin
504
- # If we know this to be a sibling VPC elsewhere in our stack,
505
- # go fetch it, and fix it if we've been misconfigured with a
506
- # duplicate peering connection
507
- if peer['vpc']['vpc_name'] and !peer['account']
508
- peer_obj = @deploy.findLitterMate(name: peer['vpc']['vpc_name'], type: "vpcs")
509
- if peer_obj
510
- if peer_obj.config['peers']
511
- skipme = false
512
- peer_obj.config['peers'].each { |peerpeer|
513
- if peerpeer['vpc']['vpc_name'] == @config['name'] and
514
- (peer['vpc']['vpc_name'] <=> @config['name']) == -1
515
- skipme = true
516
- MU.log "VPCs #{peer['vpc']['vpc_name']} and #{@config['name']} both declare mutual peering connection, ignoring #{@config['name']}'s redundant declaration", MU::DEBUG
493
+ peer['name'] ||= peer['vpc_name']
494
+ peer['id'] ||= peer['vpc_id']
495
+
496
+ # If we know this to be a sibling VPC elsewhere in our stack,
497
+ # go fetch it, and fix it if we've been misconfigured with a
498
+ # duplicate peering connection
499
+ if peer['vpc']['name'] and !peer['account']
500
+ peer_obj = @deploy.findLitterMate(name: peer['vpc']['name'], type: "vpcs")
501
+ if peer_obj
502
+ if peer_obj.config['peers']
503
+ skipme = false
504
+ peer_obj.config['peers'].each { |peerpeer|
505
+ if peerpeer['vpc']['name'] == @config['name'] and
506
+ (peer['vpc']['name'] <=> @config['name']) == -1
507
+ skipme = true
508
+ MU.log "VPCs #{peer['vpc']['name']} and #{@config['name']} both declare mutual peering connection, ignoring #{@config['name']}'s redundant declaration", MU::DEBUG
517
509
  # XXX and if deploy_id matches or is unset
518
- end
519
- }
520
- end
521
- next if skipme
522
- peer['account'] = MU::Cloud::AWS.credToAcct(peer_obj.credentials)
523
- peer['vpc']['vpc_id'] = peer_obj.cloud_id
510
+ end
511
+ }
524
512
  end
513
+ next if skipme
514
+ peer['account'] = MU::Cloud::AWS.credToAcct(peer_obj.credentials)
515
+ peer['vpc']['id'] = peer_obj.cloud_id
525
516
  end
517
+ end
526
518
 
527
- # If we still don't know our peer's vpc identifier, go fishing
528
- if !peer_obj
529
- tag_key, tag_value = peer['vpc']['tag'].split(/=/, 2) if !peer['vpc']['tag'].nil?
530
- if peer['vpc']['deploy_id'].nil? and peer['vpc']['vpc_id'].nil? and tag_key.nil?
531
- peer['vpc']['deploy_id'] = @deploy.deploy_id
532
- end
533
- peer_obj = MU::MommaCat.findStray(
534
- "AWS",
535
- "vpcs",
536
- deploy_id: peer['vpc']['deploy_id'],
537
- cloud_id: peer['vpc']['vpc_id'],
538
- # XXX we need a credentials argument here... maybe
539
- name: peer['vpc']['vpc_name'],
540
- tag_key: tag_key,
541
- tag_value: tag_value,
542
- dummy_ok: true,
543
- region: peer['vpc']['region']
544
- )
545
- raise MuError, "No result looking for #{@mu_name}'s peer VPCs (#{peer['vpc']})" if peer_obj.nil? or peer_obj.first.nil?
546
- peer_obj = peer_obj.first
547
- peer['account'] ||= MU::Cloud::AWS.credToAcct(peer_obj.credentials)
548
- peer['vpc']['vpc_id'] ||= peer_obj.cloud_id
519
+ # If we still don't know our peer's vpc identifier, go fishing
520
+ if !peer_obj
521
+ tag_key, tag_value = peer['vpc']['tag'].split(/=/, 2) if !peer['vpc']['tag'].nil?
522
+ if peer['vpc']['deploy_id'].nil? and peer['vpc']['id'].nil? and tag_key.nil?
523
+ peer['vpc']['deploy_id'] = @deploy.deploy_id
549
524
  end
525
+ peer_obj = MU::MommaCat.findStray(
526
+ "AWS",
527
+ "vpcs",
528
+ deploy_id: peer['vpc']['deploy_id'],
529
+ cloud_id: peer['vpc']['id'],
530
+ # XXX we need a credentials argument here... maybe
531
+ name: peer['vpc']['name'],
532
+ tag_key: tag_key,
533
+ tag_value: tag_value,
534
+ dummy_ok: true,
535
+ region: peer['vpc']['region']
536
+ )
537
+ MU.log "wtf", MU::ERR, details: peer if peer_obj.nil? or peer_obj.first.nil?
538
+ raise MuError, "No result looking for #{@mu_name}'s peer VPCs (#{peer['vpc']})" if peer_obj.nil? or peer_obj.first.nil?
539
+ peer_obj = peer_obj.first
540
+ peer['account'] ||= MU::Cloud::AWS.credToAcct(peer_obj.credentials)
541
+ peer['vpc']['id'] ||= peer_obj.cloud_id
542
+ end
543
+
544
+ peer_id = peer['vpc']['id']
545
+ peer['account'] ||= MU::Cloud::AWS.account_number
546
+
547
+ # See if the peering connection exists before we bother
548
+ # creating it.
549
+ resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_vpc_peering_connections(
550
+ filters: [
551
+ {
552
+ name: "requester-vpc-info.vpc-id",
553
+ values: [@cloud_id]
554
+ },
555
+ {
556
+ name: "accepter-vpc-info.vpc-id",
557
+ values: [peer_id]
558
+ }
559
+ ]
560
+ )
550
561
 
551
- peer_id = peer['vpc']['vpc_id']
552
- peer['account'] ||= MU::Cloud::AWS.account_number
562
+ peering_id = if !resp or !resp.vpc_peering_connections or
563
+ resp.vpc_peering_connections.empty?
553
564
 
554
565
  MU.log "Setting peering connection from VPC #{@config['name']} (#{@cloud_id} in account #{MU::Cloud::AWS.credToAcct(@config['credentials'])}) to #{peer_id} in account #{peer['account']}", MU::INFO, details: peer
555
566
  resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_vpc_peering_connection(
@@ -557,14 +568,14 @@ module MU
557
568
  peer_vpc_id: peer_id,
558
569
  peer_owner_id: peer['account']
559
570
  )
560
-
561
- rescue Aws::EC2::Errors::VpcPeeringConnectionAlreadyExists => e
562
- MU.log "Attempt to create duplicate peering connection to #{peer_id} from VPC #{@config['name']}", MU::WARN
571
+ resp.vpc_peering_connection.vpc_peering_connection_id
572
+ else
573
+ resp.vpc_peering_connections.first.vpc_peering_connection_id
563
574
  end
564
- peering_name = @deploy.getResourceName(@config['name']+"-PEER-"+peer['vpc']['vpc_id'])
565
575
 
566
- peering_id = resp.vpc_peering_connection.vpc_peering_connection_id
567
- MU::MommaCat.createStandardTags(peering_id, region: @config['region'], credentials: @config['credentials'])
576
+ peering_name = @deploy.getResourceName(@config['name']+"-PEER-"+peer['vpc']['id'])
577
+
578
+ MU::Cloud::AWS.createStandardTags(peering_id, region: @config['region'], credentials: @config['credentials'])
568
579
  MU::MommaCat.createTag(peering_id, "Name", peering_name, region: @config['region'], credentials: @config['credentials'])
569
580
 
570
581
  if @config['optional_tags']
@@ -586,24 +597,24 @@ module MU
586
597
  :destination_cidr_block => peer_obj.cloud_desc.cidr_block,
587
598
  :vpc_peering_connection_id => peering_id
588
599
  }
589
- begin
590
- MU.log "Creating peering route to #{peer_obj.cloud_desc.cidr_block} from VPC #{@config['name']}"
591
- resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(my_route_config)
592
- rescue Aws::EC2::Errors::RouteAlreadyExists => e
593
- rtbdesc = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
594
- route_table_ids: [rtb_id]
595
- ).route_tables.first
596
- rtbdesc.routes.each { |r|
597
- if r.destination_cidr_block == peer_obj.cloud_desc.cidr_block
598
- if r.vpc_peering_connection_id != peering_id
599
- MU.log "Attempt to create duplicate route to #{peer_obj.cloud_desc.cidr_block} from VPC #{@config['name']}", MU::ERR, details: r
600
- raise MuError, "Can't create route via #{peering_id}, a route to #{peer_obj.cloud_desc.cidr_block} already exists"
601
- else
602
- break # this is fine, the route simply already exists
603
- end
600
+ rtbdesc = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
601
+ route_table_ids: [rtb_id]
602
+ ).route_tables.first
603
+ already_exists = false
604
+ rtbdesc.routes.each { |r|
605
+ if r.destination_cidr_block == peer_obj.cloud_desc.cidr_block
606
+ if r.vpc_peering_connection_id != peering_id
607
+ MU.log "Attempt to create duplicate route to #{peer_obj.cloud_desc.cidr_block} from VPC #{@config['name']}", MU::ERR, details: r
608
+ raise MuError, "Can't create route via #{peering_id}, a route to #{peer_obj.cloud_desc.cidr_block} already exists"
609
+ else
610
+ already_exists = true
604
611
  end
605
- }
606
- end
612
+ end
613
+ }
614
+ next if already_exists
615
+
616
+ MU.log "Creating peering route to #{peer_obj.cloud_desc.cidr_block} from VPC #{@config['name']}"
617
+ resp = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).create_route(my_route_config)
607
618
  } # MU::Cloud::AWS::VPC.listAllSubnetRouteTables
608
619
 
609
620
  begin
@@ -682,13 +693,13 @@ module MU
682
693
  rtb['routes'].each { |route|
683
694
  if !route['nat_host_id'].nil? or !route['nat_host_name'].nil?
684
695
  route_config = {
685
- :route_table_id => route_table_id,
686
- :destination_cidr_block => route['destination_network']
696
+ :route_table_id => route_table_id,
697
+ :destination_cidr_block => route['destination_network']
687
698
  }
688
699
 
689
700
  nat_instance = findBastion(
690
- nat_name: route["nat_host_name"],
691
- nat_cloud_id: route["nat_host_id"]
701
+ nat_name: route["nat_host_name"],
702
+ nat_cloud_id: route["nat_host_id"]
692
703
  )
693
704
  if nat_instance.nil?
694
705
  raise MuError, "VPC #{vpc_name} is configured to use #{route} as a route, but I can't find a matching bastion host!"
@@ -711,7 +722,14 @@ module MU
711
722
  # @param tag_key [String]: A tag key to search.
712
723
  # @param tag_value [String]: The value of the tag specified by tag_key to match when searching by tag.
713
724
  # @return [Array<Hash<String,OpenStruct>>]: The cloud provider's complete descriptions of matching VPCs
714
- def self.find(cloud_id: nil, region: MU.curRegion, tag_key: "Name", tag_value: nil, credentials: nil, flags: {})
725
+ # def self.find(cloud_id: nil, region: MU.curRegion, tag_key: "Name", tag_value: nil, credentials: nil, flags: {})
726
+ def self.find(**args)
727
+ cloud_id = args[:cloud_id]
728
+ region = args[:region] || MU.curRegion
729
+ tag_key = args[:tag_key] || "Name"
730
+ tag_value = args[:tag_value]
731
+ credentials = args[:credentials]
732
+ flags = args[:flags]
715
733
 
716
734
  retries = 0
717
735
  map = {}
@@ -875,7 +893,7 @@ module MU
875
893
  # @param nat_tag_value [String]: A cloud provider tag to help identify the resource, used in conjunction with tag_key.
876
894
  # @param nat_ip [String]: An IP address associated with the NAT instance.
877
895
  def findBastion(nat_name: nil, nat_cloud_id: nil, nat_tag_key: nil, nat_tag_value: nil, nat_ip: nil)
878
- nat = nil
896
+
879
897
  deploy_id = nil
880
898
  nat_name = nat_name.to_s if !nat_name.nil? and nat_name.class.to_s == "MU::Config::Tail"
881
899
  nat_ip = nat_ip.to_s if !nat_ip.nil? and nat_ip.class.to_s == "MU::Config::Tail"
@@ -1013,8 +1031,6 @@ module MU
1013
1031
  return MU::Cloud::AWS::VPC.have_route_peered_vpc?(my_subnets_key, target_subnets_key, instance_id)
1014
1032
  end
1015
1033
 
1016
- @route_cache[instance_id] = false
1017
- return false
1018
1034
  end
1019
1035
 
1020
1036
  # updates the route table cache (@rtb_cache).
@@ -1178,6 +1194,7 @@ module MU
1178
1194
  gwthreads << Thread.new {
1179
1195
  purge_nat_gateways(noop, vpc_id: vpc.vpc_id, region: region, credentials: credentials)
1180
1196
  purge_endpoints(noop, vpc_id: vpc.vpc_id, region: region, credentials: credentials)
1197
+ purge_interfaces(noop, [{name: "vpc-id", values: [vpc.vpc_id]}], region: region, credentials: credentials)
1181
1198
  }
1182
1199
  }
1183
1200
  gwthreads.each { |t|
@@ -1241,19 +1258,6 @@ module MU
1241
1258
  def self.validateConfig(vpc, configurator)
1242
1259
  ok = true
1243
1260
 
1244
- if (!vpc['route_tables'] or vpc['route_tables'].size == 0) and vpc['create_standard_subnets']
1245
- vpc['route_tables'] = [
1246
- {
1247
- "name" => "internet",
1248
- "routes" => [ { "destination_network" => "0.0.0.0/0", "gateway" => "#INTERNET" } ]
1249
- },
1250
- {
1251
- "name" => "private",
1252
- "routes" => [ { "destination_network" => "0.0.0.0/0", "gateway" => "#NAT" } ]
1253
- }
1254
- ]
1255
- end
1256
-
1257
1261
  if vpc["enable_traffic_logging"]
1258
1262
  logdesc = {
1259
1263
  "name" => vpc['name']+"loggroup",
@@ -1364,6 +1368,7 @@ module MU
1364
1368
  "name" => route['nat_host_name']
1365
1369
  }
1366
1370
  elsif route['gateway'] == '#NAT'
1371
+ vpc['create_nat_gateway'] = true
1367
1372
  private_rtbs << table['name']
1368
1373
  elsif route['gateway'] == '#INTERNET'
1369
1374
  public_rtbs << table['name']
@@ -1409,11 +1414,12 @@ module MU
1409
1414
 
1410
1415
  if (!vpc['subnets'] or vpc['subnets'].empty?) and vpc['create_standard_subnets']
1411
1416
  if vpc['availability_zones'].nil? or vpc['availability_zones'].empty?
1412
- vpc['availability_zones'] = MU::Cloud::AWS.listAZs(region: vpc['region'])
1417
+ vpc['availability_zones'] = MU::Cloud::AWS.listAZs(region: vpc['region'], credentials: vpc['credentials'])
1413
1418
  else
1414
1419
  # turn into a hash so we can use list parameters easily
1415
1420
  vpc['availability_zones'] = vpc['availability_zones'].map { |val| val['zone'] }
1416
1421
  end
1422
+
1417
1423
  subnets = configurator.divideNetwork(vpc['ip_block'], vpc['availability_zones'].size*vpc['route_tables'].size, 28)
1418
1424
 
1419
1425
  ok = false if subnets.nil?
@@ -1455,26 +1461,32 @@ module MU
1455
1461
  ok
1456
1462
  end
1457
1463
 
1458
- # Remove all network interfaces associated with the currently loaded deployment.
1459
- # @param noop [Boolean]: If true, will only print what would be done
1460
- # @param tagfilters [Array<Hash>]: EC2 tags to filter against when search for resources to purge
1461
- # @param region [String]: The cloud provider region
1462
- # @return [void]
1463
- def self.purge_interfaces(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
1464
- resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_network_interfaces(
1465
- filters: tagfilters
1464
+ # List the CIDR blocks to which these VPC has routes. Exclude obvious
1465
+ # things like +0.0.0.0/0+.
1466
+ # @param subnets [Array<String>]: Only return the routes relevant to these subnet ids
1467
+ def routes(subnets: [])
1468
+ @my_visible_cidrs ||= {}
1469
+ return @my_visible_cidrs[subnets] if @my_visible_cidrs[subnets]
1470
+ filters = [{ :name => "vpc-id", :values => [@cloud_id] }]
1471
+ if subnets and subnets.size > 0
1472
+ filters << { :name => "association.subnet-id", :values => subnets }
1473
+ end
1474
+ tables = MU::Cloud::AWS.ec2(region: @config['region'], credentials: @config['credentials']).describe_route_tables(
1475
+ filters: filters
1466
1476
  )
1467
- ifaces = resp.data.network_interfaces
1468
-
1469
- return if ifaces.nil? or ifaces.size == 0
1470
-
1471
- ifaces.each { |iface|
1472
- MU.log "Deleting Network Interface #{iface.network_interface_id}"
1473
- MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_network_interface(network_interface_id: iface.network_interface_id)
1474
- }
1477
+ cidrs = []
1478
+ if tables and tables.route_tables
1479
+ tables.route_tables.each { |rtb|
1480
+ rtb.routes.each { |route|
1481
+ next if route.destination_cidr_block == "0.0.0.0/0"
1482
+ cidrs << route.destination_cidr_block
1483
+ }
1484
+ }
1485
+ end
1486
+ @my_visible_cidrs[subnets] = cidrs.uniq.sort
1487
+ @my_visible_cidrs[subnets]
1475
1488
  end
1476
1489
 
1477
-
1478
1490
  private
1479
1491
 
1480
1492
  # List the route tables for each subnet in the given VPC
@@ -1545,12 +1557,12 @@ module MU
1545
1557
  }
1546
1558
  end
1547
1559
 
1548
- MU::MommaCat.createStandardTags(route_table_id, credentials: @config['credentials'])
1560
+ MU::Cloud::AWS.createStandardTags(route_table_id, credentials: @config['credentials'])
1549
1561
  rtb['routes'].each { |route|
1550
1562
  if route['nat_host_id'].nil? and route['nat_host_name'].nil?
1551
1563
  route_config = {
1552
- :route_table_id => route_table_id,
1553
- :destination_cidr_block => route['destination_network']
1564
+ :route_table_id => route_table_id,
1565
+ :destination_cidr_block => route['destination_network']
1554
1566
  }
1555
1567
  if !route['peer_id'].nil?
1556
1568
  route_config[:vpc_peering_connection_id] = route['peer_id']
@@ -1575,25 +1587,46 @@ module MU
1575
1587
  # @return [void]
1576
1588
  def self.purge_gateways(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
1577
1589
  resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_internet_gateways(
1578
- filters: tagfilters
1590
+ filters: tagfilters
1579
1591
  )
1580
1592
  gateways = resp.data.internet_gateways
1581
1593
 
1582
1594
  gateways.each { |gateway|
1595
+ vpc_id = nil
1583
1596
  gateway.attachments.each { |attachment|
1584
- MU.log "Detaching Internet Gateway #{gateway.internet_gateway_id} from #{attachment.vpc_id}"
1597
+ vpc_id = attachment.vpc_id
1598
+ tried_interfaces = false
1585
1599
  begin
1600
+ MU.log "Detaching Internet Gateway #{gateway.internet_gateway_id} from #{attachment.vpc_id}"
1586
1601
  MU::Cloud::AWS.ec2(credentials: credentials, region: region).detach_internet_gateway(
1587
- internet_gateway_id: gateway.internet_gateway_id,
1588
- vpc_id: attachment.vpc_id
1602
+ internet_gateway_id: gateway.internet_gateway_id,
1603
+ vpc_id: attachment.vpc_id
1589
1604
  ) if !noop
1605
+ rescue Aws::EC2::Errors::DependencyViolation => e
1606
+ if !tried_interfaces
1607
+ purge_interfaces(noop, [{name: "vpc-id", values: [attachment.vpc_id]}], region: region, credentials: credentials)
1608
+ tried_interfaces = true
1609
+ sleep 2
1610
+ retry
1611
+ end
1612
+ MU.log e.message, MU::ERR
1590
1613
  rescue Aws::EC2::Errors::GatewayNotAttached => e
1591
1614
  MU.log "Gateway #{gateway.internet_gateway_id} was already detached", MU::WARN
1592
1615
  end
1593
1616
  }
1594
- MU.log "Deleting Internet Gateway #{gateway.internet_gateway_id}"
1617
+
1618
+ tried_interfaces = false
1595
1619
  begin
1620
+ MU.log "Deleting Internet Gateway #{gateway.internet_gateway_id}"
1596
1621
  MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_internet_gateway(internet_gateway_id: gateway.internet_gateway_id) if !noop
1622
+ rescue Aws::EC2::Errors::DependencyViolation => e
1623
+ if !tried_interfaces and vpc_id
1624
+ purge_interfaces(noop, [{name: "vpc-id", values: [vpc_id]}], region: region, credentials: credentials)
1625
+ tried_interfaces = true
1626
+ sleep 2
1627
+ retry
1628
+ end
1629
+ MU.log e.message, MU::ERR
1597
1630
  rescue Aws::EC2::Errors::InvalidInternetGatewayIDNotFound
1598
1631
  MU.log "Gateway #{gateway.internet_gateway_id} was already destroyed by the time I got to it", MU::WARN
1599
1632
  end
@@ -1783,15 +1816,42 @@ module MU
1783
1816
  # @return [void]
1784
1817
  def self.purge_interfaces(noop = false, tagfilters = [{name: "tag:MU-ID", values: [MU.deploy_id]}], region: MU.curRegion, credentials: nil)
1785
1818
  resp = MU::Cloud::AWS.ec2(credentials: credentials, region: region).describe_network_interfaces(
1786
- filters: tagfilters
1819
+ filters: tagfilters
1787
1820
  )
1788
1821
  ifaces = resp.data.network_interfaces
1789
1822
 
1790
1823
  return if ifaces.nil? or ifaces.size == 0
1791
1824
 
1792
1825
  ifaces.each { |iface|
1793
- MU.log "Deleting Network Interface #{iface.network_interface_id}"
1794
- MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_network_interface(network_interface_id: iface.network_interface_id)
1826
+ begin
1827
+ if iface.attachment and iface.attachment.status == "attached"
1828
+ MU.log "Detaching Network Interface #{iface.network_interface_id} from #{iface.attachment.instance_owner_id}"
1829
+ tried_lbs = false
1830
+ begin
1831
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).detach_network_interface(attachment_id: iface.attachment.attachment_id) if !noop
1832
+ rescue Aws::EC2::Errors::InvalidAttachmentIDNotFound => e
1833
+ # suits me just fine
1834
+ rescue Aws::EC2::Errors::AuthFailure => e
1835
+ if !tried_lbs and iface.attachment.instance_owner_id == "amazon-elb"
1836
+ MU::Cloud::AWS::LoadBalancer.cleanup(
1837
+ noop: noop,
1838
+ region: region,
1839
+ credentials: credentials,
1840
+ flags: {"vpc_id" => iface.vpc_id}
1841
+ )
1842
+ tried_lbs = true
1843
+ retry
1844
+ end
1845
+ MU.log e.message, MU::ERR, details: iface.attachment
1846
+ end
1847
+ end
1848
+ MU.log "Deleting Network Interface #{iface.network_interface_id}"
1849
+ MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_network_interface(network_interface_id: iface.network_interface_id) if !noop
1850
+ rescue Aws::EC2::Errors::InvalidNetworkInterfaceIDNotFound => e
1851
+ # ok then!
1852
+ rescue Aws::EC2::Errors::InvalidParameterValue => e
1853
+ MU.log e.message, MU::ERR, details: iface
1854
+ end
1795
1855
  }
1796
1856
  end
1797
1857
 
@@ -1927,19 +1987,28 @@ module MU
1927
1987
  end
1928
1988
  }
1929
1989
 
1930
- MU.log "Deleting VPC #{vpc.vpc_id}"
1931
1990
  retries = 0
1932
1991
  begin
1992
+ MU.log "Deleting VPC #{vpc.vpc_id}"
1933
1993
  MU::Cloud::AWS.ec2(credentials: credentials, region: region).delete_vpc(vpc_id: vpc.vpc_id) if !noop
1934
1994
  rescue Aws::EC2::Errors::InvalidVpcIDNotFound
1935
1995
  MU.log "VPC #{vpc.vpc_id} has already been deleted", MU::WARN
1936
1996
  rescue Aws::EC2::Errors::DependencyViolation => e
1937
- MU.log "Couldn't delete VPC #{vpc.vpc_id} from #{region}: #{e.inspect}", MU::ERR#, details: caller
1938
1997
  if retries < 5
1998
+ MU.log "#{vpc.vpc_id} in #{region} had hidden dependencies, will try to remove them", MU::NOTICE
1939
1999
  retries += 1
2000
+ # fry some common rogue resources
2001
+ MU::Cloud::AWS::FirewallRule.cleanup(
2002
+ noop: noop,
2003
+ region: region,
2004
+ credentials: credentials,
2005
+ flags: { "vpc_id" => vpc.vpc_id }
2006
+ )
2007
+ purge_gateways(noop, tagfilters, region: region, credentials: credentials)
1940
2008
  sleep 10
1941
2009
  retry
1942
2010
  else
2011
+ MU.log "Failed to remove #{vpc.vpc_id} in #{region}: #{e.message}", MU::ERR
1943
2012
  next
1944
2013
  end
1945
2014
  end