cloud-mu 1.9.0.pre.beta → 2.0.0.pre.alpha

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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/Berksfile +16 -54
  3. data/Berksfile.lock +14 -62
  4. data/bin/mu-aws-setup +131 -108
  5. data/bin/mu-configure +311 -74
  6. data/bin/mu-gcp-setup +84 -62
  7. data/bin/mu-load-config.rb +46 -2
  8. data/bin/mu-self-update +11 -9
  9. data/bin/mu-upload-chef-artifacts +4 -4
  10. data/{mu.gemspec → cloud-mu.gemspec} +2 -2
  11. data/cookbooks/awscli/Berksfile +8 -0
  12. data/cookbooks/mu-activedirectory/Berksfile +11 -0
  13. data/cookbooks/mu-firewall/Berksfile +9 -0
  14. data/cookbooks/mu-firewall/metadata.rb +1 -1
  15. data/cookbooks/mu-glusterfs/Berksfile +10 -0
  16. data/cookbooks/mu-jenkins/Berksfile +14 -0
  17. data/cookbooks/mu-master/Berksfile +23 -0
  18. data/cookbooks/mu-master/attributes/default.rb +1 -1
  19. data/cookbooks/mu-master/metadata.rb +2 -2
  20. data/cookbooks/mu-master/recipes/default.rb +1 -1
  21. data/cookbooks/mu-master/recipes/init.rb +7 -3
  22. data/cookbooks/mu-master/recipes/ssl-certs.rb +1 -0
  23. data/cookbooks/mu-mongo/Berksfile +10 -0
  24. data/cookbooks/mu-openvpn/Berksfile +11 -0
  25. data/cookbooks/mu-php54/Berksfile +13 -0
  26. data/cookbooks/mu-splunk/Berksfile +10 -0
  27. data/cookbooks/mu-tools/Berksfile +21 -0
  28. data/cookbooks/mu-tools/files/default/Mu_CA.pem +15 -15
  29. data/cookbooks/mu-utility/Berksfile +9 -0
  30. data/cookbooks/mu-utility/metadata.rb +2 -1
  31. data/cookbooks/nagios/Berksfile +7 -4
  32. data/cookbooks/s3fs/Berksfile +9 -0
  33. data/environments/dev.json +6 -6
  34. data/environments/prod.json +6 -6
  35. data/modules/mu.rb +20 -42
  36. data/modules/mu/cleanup.rb +102 -100
  37. data/modules/mu/cloud.rb +90 -28
  38. data/modules/mu/clouds/aws.rb +449 -218
  39. data/modules/mu/clouds/aws/alarm.rb +29 -17
  40. data/modules/mu/clouds/aws/cache_cluster.rb +78 -64
  41. data/modules/mu/clouds/aws/collection.rb +25 -18
  42. data/modules/mu/clouds/aws/container_cluster.rb +73 -66
  43. data/modules/mu/clouds/aws/database.rb +124 -116
  44. data/modules/mu/clouds/aws/dnszone.rb +27 -20
  45. data/modules/mu/clouds/aws/firewall_rule.rb +30 -22
  46. data/modules/mu/clouds/aws/folder.rb +18 -3
  47. data/modules/mu/clouds/aws/function.rb +77 -23
  48. data/modules/mu/clouds/aws/group.rb +19 -12
  49. data/modules/mu/clouds/aws/habitat.rb +153 -0
  50. data/modules/mu/clouds/aws/loadbalancer.rb +59 -52
  51. data/modules/mu/clouds/aws/log.rb +30 -23
  52. data/modules/mu/clouds/aws/msg_queue.rb +29 -20
  53. data/modules/mu/clouds/aws/notifier.rb +222 -0
  54. data/modules/mu/clouds/aws/role.rb +178 -90
  55. data/modules/mu/clouds/aws/search_domain.rb +40 -24
  56. data/modules/mu/clouds/aws/server.rb +169 -137
  57. data/modules/mu/clouds/aws/server_pool.rb +60 -83
  58. data/modules/mu/clouds/aws/storage_pool.rb +59 -31
  59. data/modules/mu/clouds/aws/user.rb +36 -27
  60. data/modules/mu/clouds/aws/userdata/linux.erb +101 -93
  61. data/modules/mu/clouds/aws/vpc.rb +250 -189
  62. data/modules/mu/clouds/azure.rb +132 -0
  63. data/modules/mu/clouds/cloudformation.rb +65 -1
  64. data/modules/mu/clouds/cloudformation/alarm.rb +8 -0
  65. data/modules/mu/clouds/cloudformation/cache_cluster.rb +7 -0
  66. data/modules/mu/clouds/cloudformation/collection.rb +7 -0
  67. data/modules/mu/clouds/cloudformation/database.rb +7 -0
  68. data/modules/mu/clouds/cloudformation/dnszone.rb +7 -0
  69. data/modules/mu/clouds/cloudformation/firewall_rule.rb +9 -2
  70. data/modules/mu/clouds/cloudformation/loadbalancer.rb +7 -0
  71. data/modules/mu/clouds/cloudformation/log.rb +7 -0
  72. data/modules/mu/clouds/cloudformation/server.rb +7 -0
  73. data/modules/mu/clouds/cloudformation/server_pool.rb +7 -0
  74. data/modules/mu/clouds/cloudformation/vpc.rb +7 -0
  75. data/modules/mu/clouds/google.rb +214 -110
  76. data/modules/mu/clouds/google/container_cluster.rb +42 -24
  77. data/modules/mu/clouds/google/database.rb +15 -6
  78. data/modules/mu/clouds/google/firewall_rule.rb +17 -25
  79. data/modules/mu/clouds/google/group.rb +13 -5
  80. data/modules/mu/clouds/google/habitat.rb +105 -0
  81. data/modules/mu/clouds/google/loadbalancer.rb +28 -20
  82. data/modules/mu/clouds/google/server.rb +93 -354
  83. data/modules/mu/clouds/google/server_pool.rb +18 -10
  84. data/modules/mu/clouds/google/user.rb +22 -14
  85. data/modules/mu/clouds/google/vpc.rb +97 -69
  86. data/modules/mu/config.rb +133 -38
  87. data/modules/mu/config/alarm.rb +25 -0
  88. data/modules/mu/config/cache_cluster.rb +5 -3
  89. data/modules/mu/config/cache_cluster.yml +23 -0
  90. data/modules/mu/config/database.rb +25 -16
  91. data/modules/mu/config/database.yml +3 -3
  92. data/modules/mu/config/function.rb +1 -2
  93. data/modules/mu/config/{project.rb → habitat.rb} +10 -10
  94. data/modules/mu/config/notifier.rb +85 -0
  95. data/modules/mu/config/notifier.yml +9 -0
  96. data/modules/mu/config/role.rb +1 -1
  97. data/modules/mu/config/search_domain.yml +2 -2
  98. data/modules/mu/config/server.rb +13 -1
  99. data/modules/mu/config/server.yml +3 -3
  100. data/modules/mu/config/server_pool.rb +3 -1
  101. data/modules/mu/config/storage_pool.rb +3 -1
  102. data/modules/mu/config/storage_pool.yml +19 -0
  103. data/modules/mu/config/vpc.rb +70 -8
  104. data/modules/mu/groomers/chef.rb +2 -3
  105. data/modules/mu/kittens.rb +500 -122
  106. data/modules/mu/master.rb +5 -5
  107. data/modules/mu/mommacat.rb +151 -91
  108. data/modules/tests/super_complex_bok.yml +12 -0
  109. data/modules/tests/super_simple_bok.yml +12 -0
  110. data/spec/mu/clouds/azure_spec.rb +82 -0
  111. data/spec/spec_helper.rb +105 -0
  112. metadata +26 -5
  113. data/modules/mu/clouds/aws/notification.rb +0 -139
  114. data/modules/mu/config/notification.rb +0 -44
@@ -39,7 +39,7 @@ CHEF_SERVER_VERSION="12.17.15-1"
39
39
  CHEF_CLIENT_VERSION="14.4.56"
40
40
  KNIFE_WINDOWS="1.9.0"
41
41
  MU_BASE="/opt/mu"
42
- MU_BRANCH="i_yam_what_i_yam" # GIT HOOK EDITABLE DO NOT TOUCH
42
+ MU_BRANCH="Azure_you_want_azure" # GIT HOOK EDITABLE DO NOT TOUCH
43
43
  realbranch=`cd #{MU_BASE}/lib && git rev-parse --abbrev-ref HEAD`
44
44
 
45
45
  if ENV.key?('MU_BRANCH')
@@ -234,7 +234,7 @@ file "#{MU_BASE}/lib/.git/hooks/pre-commit" do
234
234
  action :delete
235
235
  end
236
236
 
237
- [MU_BASE+"/var", MU_BASE+"/install", MU_BASE+"/deprecated-bash-library.sh"].each do |dir|
237
+ [MU_BASE+"/var", MU_BASE+"/var/ssl"].each do |dir|
238
238
  directory dir do
239
239
  recursive true
240
240
  mode 0755
@@ -308,7 +308,9 @@ rpms.each_pair { |pkg, src|
308
308
  end
309
309
  end
310
310
  }
311
- package "jq"
311
+ package "jq" do
312
+ ignore_failure true # sometimes we can't see EPEL immediately
313
+ end
312
314
  package removepackages do
313
315
  action :remove
314
316
  end
@@ -343,6 +345,7 @@ file "#{MU_BASE}/var/users/mu/email" do
343
345
  content "#{$MU_CFG['mu_admin_email']}\n"
344
346
  else
345
347
  content "root@example.com\n"
348
+ action :create_if_missing
346
349
  end
347
350
  end
348
351
  file "#{MU_BASE}/var/users/mu/realname" do
@@ -350,6 +353,7 @@ file "#{MU_BASE}/var/users/mu/realname" do
350
353
  content "#{$MU_CFG['mu_admin_name']}\n"
351
354
  else
352
355
  content "Mu Administrator\n"
356
+ action :create_if_missing
353
357
  end
354
358
  end
355
359
 
@@ -25,6 +25,7 @@
25
25
  include_recipe 'mu-master::firewall-holes'
26
26
  service_certs = ["rsyslog", "mommacat", "ldap", "consul", "vault"]
27
27
 
28
+ directory "#{$MU_CFG['datadir']}"
28
29
  directory "#{$MU_CFG['datadir']}/ssl"
29
30
  template "#{$MU_CFG['datadir']}/ssl/openssl.cnf" do
30
31
  source "openssl.cnf.erb"
@@ -0,0 +1,10 @@
1
+ source 'https://supermarket.chef.io'
2
+ source chef_repo: ".."
3
+
4
+ metadata
5
+
6
+ # Mu Cookbooks
7
+
8
+ # Supermarket Cookbooks
9
+ cookbook 'mongodb', '~> 0.16.2'
10
+ cookbook 'chef-vault', '~> 3.1.1'
@@ -0,0 +1,11 @@
1
+ source 'https://supermarket.chef.io'
2
+ source chef_repo: ".."
3
+
4
+ metadata
5
+
6
+ # Mu Cookbooks
7
+ cookbook 'mu-utility'
8
+ cookbook 'mu-firewall'
9
+
10
+ # Supermarket Cookbooks
11
+ cookbook 'chef-vault', '~> 3.1.1'
@@ -0,0 +1,13 @@
1
+ source 'https://supermarket.chef.io'
2
+ source chef_repo: ".."
3
+
4
+ metadata
5
+
6
+ # Mu Cookbooks
7
+ cookbook 'mu-utility'
8
+
9
+ # Supermarket Cookbooks
10
+ cookbook 'simple_iptables', '~> 0.8.0'
11
+ cookbook 'apache2', '< 4.0'
12
+ cookbook 'mysql', '~> 8.5.1'
13
+ cookbook 'yum-epel', '~> 3.2.0'
@@ -0,0 +1,10 @@
1
+ source 'https://supermarket.chef.io'
2
+ source chef_repo: ".."
3
+
4
+ metadata
5
+
6
+ # Mu Cookbooks
7
+
8
+ # Supermarket Cookbooks
9
+ cookbook 'chef-vault', '~> 3.1.1'
10
+ cookbook 'windows', '~> 5.1.1'
@@ -0,0 +1,21 @@
1
+ source 'https://supermarket.chef.io'
2
+ source chef_repo: ".."
3
+
4
+ metadata
5
+
6
+ # Mu Cookbooks
7
+ cookbook "nagios"
8
+ cookbook "mu-utility"
9
+ cookbook "mu-splunk"
10
+ cookbook "mu-firewall"
11
+ cookbook "mu-activedirectory"
12
+
13
+ # Supermarket Cookbooks
14
+ cookbook "oracle-instantclient", '~> 1.1.0'
15
+ cookbook "database", '~> 6.1.1'
16
+ cookbook "postgresql", '~> 7.1.0'
17
+ cookbook "java", '~> 2.2.0'
18
+ cookbook "windows", '~> 5.1.1'
19
+ cookbook "chef-vault", '~> 3.1.1'
20
+ cookbook "poise-python", '~> 1.7.0'
21
+ cookbook "yum-epel", '~> 3.2.0'
@@ -1,8 +1,8 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIIF2zCCA8OgAwIBAgIJALVaC3iJgQA6MA0GCSqGSIb3DQEBDQUAMF0xFjAUBgNV
2
+ MIIF2zCCA8OgAwIBAgIJAJSp1wu4cHj9MA0GCSqGSIb3DQEBDQUAMF0xFjAUBgNV
3
3
  BAMMDTU0LjE3NS44Ni4xOTQxIDAeBgNVBAsMF011IFNlcnZlciA1NC4xNzUuODYu
4
- MTk0MRQwEgYDVQQKDAtlR2xvYmFsVGVjaDELMAkGA1UEBhMCVVMwHhcNMTgxMjAz
5
- MTM1OTUxWhcNMjEwOTIyMTM1OTUxWjBdMRYwFAYDVQQDDA01NC4xNzUuODYuMTk0
4
+ MTk0MRQwEgYDVQQKDAtlR2xvYmFsVGVjaDELMAkGA1UEBhMCVVMwHhcNMTkwMTIy
5
+ MTUzMjM4WhcNMjExMTExMTUzMjM4WjBdMRYwFAYDVQQDDA01NC4xNzUuODYuMTk0
6
6
  MSAwHgYDVQQLDBdNdSBTZXJ2ZXIgNTQuMTc1Ljg2LjE5NDEUMBIGA1UECgwLZUds
7
7
  b2JhbFRlY2gxCzAJBgNVBAYTAlVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
8
8
  CgKCAgEAo7rntOFj/WPNvh00SN55aJBusppsY9arq7QF5gt/9+cBPsjcXn7jJMu0
@@ -19,16 +19,16 @@ e4Q3VnxhRfmkS1NqEzIvPabVLg9qvN419cubpE6HAtBJw/f3ocUCAwEAAaOBnTCB
19
19
  mjBKBgNVHREEQzBBhwQ2r1bCgglsb2NhbGhvc3SHBH8AAAGCGXN0YW5nZS1tdS1k
20
20
  ZXYucGxhdGZvcm0tbXWCDXN0YW5nZS1tdS1kZXYwHQYDVR0OBBYEFK/EmtGebCwd
21
21
  5QpM8y/3EKdYNVbcMB8GA1UdIwQYMBaAFK/EmtGebCwd5QpM8y/3EKdYNVbcMAwG
22
- A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQENBQADggIBAIFFoIWaS2vsiMjEeFo/FXKd
23
- Gy5lrvbBMaKgeFBI7Yqrz7wxmPol5de1KuuYANrcHtgpTuqnNRPMKt4VF6NW6CRY
24
- FTaaG0kwJU0Y3FMAdrmUUFK0bqNhchrwSv3Zqs68ifQ7vxwN0xLZrKJ5kMWjfQCn
25
- XDOImEe14ZQYwAf0kxZXm9qGoVQZK+ObIfNDPTPAOADQ3ZeawRrogZ2M6694mN+4
26
- eS/PDibpcZ4Dl8Cw4nuLIG4ct9Dm/8kZ0XRAoxXTEUfMIrJQpKmjnhux8Kzjy/DU
27
- eovi+530klyeyV0909lN9l8JJmBd3Zw1EArSB2PgSSTfGXrdGN/A6TlE50QahZS6
28
- wlE4/P2ISDCyyc+Zobu9e+6WII7DFcNwzyFuC3WO6h2I2IXnZvUfVCowjipfdSKx
29
- +qQvevSmbprs+AJVfvkyaejKYK5PPe+fGMHJo80Pqc2LiODoChs6NZh10xAG0Sd6
30
- zQ05A4ZUmZjlC0lpFkgVPBaAlUAW28y6CdlRNW6H52KgvctJecGrBYZ52cTdju1b
31
- AXdlwMbPHHoA0HDCT7vGhGb/zUWkWYJVpXQ7EwwQWdCEejegtCRNWqTZC0s4mjUa
32
- Yw4ISVSAaTkzWWxBkizBGJcIxUfukuhnEEGs1G09hqpaXMWyXLg3wf9GkCsn+tD+
33
- PY7N1R6ysc8wA8nByPeR
22
+ A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQENBQADggIBAEQ1l3JqlK7hQHhhA7Y4Odhk
23
+ mGsEJ8m1Kdb6wq9/hMAAOhzFPtzIzxPaDUuN29nGT/d4urTdJ+fSa7f8uhFyzKEL
24
+ retbsal0n4MFD7Iu+QopYBSTsS3w7y9a4HGj2AW6IMrYjWFBtl1QjRMKPymwTV6Y
25
+ ngjfJdJy4ySUP1FTl7hG1LdN+My6Q2ykQznyY/g51RzSNzmreWkK9Qfy/bk7G8ss
26
+ vDPQOqocwQE/5GoO4WqDn+6IFw1bgs+rPt897MOv0YjLZR3B5Q8SYivp+7CVvLZT
27
+ hKhIHL41k3H8R7khmV+Ak6ok9k+hCnT6pWC40g0jMyuy/HnlfeXcz9betiNm0Vhg
28
+ 98pxFjISd7GaSmzqH4L+NbNshgRBhgTA+qm5Nu7hETf5b4tV1gBi0MA/CzpD3cq5
29
+ MadyWDkDnbGnSPqrLHvZwKjvDwUhPYw+6jYU9ejkG8I3G8ntmo4j7el+bYNDa1Yu
30
+ o60AIxVn2LpDIPICibf2cpspOqxQMB0fClAttajklXCwZ73TomQP/9TegjMeLJMl
31
+ p2KreRF3lvflajjrV7KHQ6tm8t9NIqljd3q5KW1RqatRwyMQUBWo8i8DlD6HQ+w0
32
+ gipxlcwMUqjVEIQyUtCNax6RDpysdOsB6uPPkUxb825bRwOWnAHPVCTc/HaTVzmA
33
+ FTNwHY0pyDGREcu+cb/A
34
34
  -----END CERTIFICATE-----
@@ -0,0 +1,9 @@
1
+ source 'https://supermarket.chef.io'
2
+ source chef_repo: ".."
3
+
4
+ metadata
5
+
6
+ # Mu Cookbooks
7
+
8
+ # Supermarket Cookbooks
9
+ cookbook 'windows', '~> 5.1.1'
@@ -13,4 +13,5 @@ version '0.6.0'
13
13
  supports os
14
14
  end
15
15
 
16
- depends 'windows', '~> 5.1.1'
16
+ depends 'windows', '~> 5.1.1'
17
+ depends 'mu-firewall'
@@ -1,8 +1,11 @@
1
1
  source 'https://supermarket.chef.io'
2
+ source chef_repo: ".."
2
3
 
3
4
  metadata
4
5
 
5
- group :integration do
6
- cookbook 'apt'
7
- cookbook 'nagios_test', path: './test/fixtures/cookbooks/nagios_test'
8
- end
6
+ # Mu Cookbooks
7
+
8
+ # Supermarket Cookbooks
9
+ cookbook 'apache2', '< 4.0'
10
+ cookbook 'php', '< 6.0'
11
+ cookbook 'zap', '>= 0.6.0'
@@ -0,0 +1,9 @@
1
+ source 'https://supermarket.chef.io'
2
+ source chef_repo: ".."
3
+
4
+ metadata
5
+
6
+ # Mu Cookbooks
7
+ cookbook "mu-utility"
8
+
9
+ # Supermarket Cookbooks
@@ -1,8 +1,8 @@
1
1
  {
2
- "name": "dev",
3
- "default_attributes": {
4
- },
5
- "json_class": "Chef::Environment",
6
- "description": "Infrastructure development environment",
7
- "chef_type": "environment"
2
+ "name": "DEV",
3
+ "default_attributes": {
4
+ },
5
+ "json_class": "Chef::Environment",
6
+ "description": "Infrastructure development environment",
7
+ "chef_type": "environment"
8
8
  }
@@ -1,8 +1,8 @@
1
1
  {
2
- "name": "prod",
3
- "default_attributes": {
4
- },
5
- "json_class": "Chef::Environment",
6
- "description": "Infrastructure production environment",
7
- "chef_type": "environment"
2
+ "name": "PROD",
3
+ "default_attributes": {
4
+ },
5
+ "json_class": "Chef::Environment",
6
+ "description": "Infrastructure production environment",
7
+ "chef_type": "environment"
8
8
  }
@@ -498,7 +498,7 @@ module MU
498
498
  begin
499
499
  @@myAZ_var ||= MU.myCloudDescriptor.placement.availability_zone
500
500
  rescue Aws::EC2::Errors::InternalError => e
501
- MU.log "Got #{e.inspect} on MU::Cloud::AWS.ec2(#{MU.myRegion}).describe_instances(instance_ids: [#{@@myInstanceId}])", MU::WARN
501
+ MU.log "Got #{e.inspect} on MU::Cloud::AWS.ec2(region: #{MU.myRegion}).describe_instances(instance_ids: [#{@@myInstanceId}])", MU::WARN
502
502
  sleep 10
503
503
  end
504
504
  end
@@ -514,7 +514,7 @@ module MU
514
514
  )
515
515
  elsif MU::Cloud::AWS.hosted?
516
516
  begin
517
- @@myCloudDescriptor = MU::Cloud::AWS.ec2(MU.myRegion).describe_instances(instance_ids: [MU.myInstanceId]).reservations.first.instances.first
517
+ @@myCloudDescriptor = MU::Cloud::AWS.ec2(region: MU.myRegion).describe_instances(instance_ids: [MU.myInstanceId]).reservations.first.instances.first
518
518
  rescue Aws::EC2::Errors::InvalidInstanceIDNotFound => e
519
519
  rescue Aws::Errors::MissingCredentialsError => e
520
520
  MU.log "I'm hosted in AWS, but I can't make API calls. Does this instance have an appropriate IAM profile?", MU::WARN
@@ -536,7 +536,7 @@ module MU
536
536
  nil
537
537
  end
538
538
  rescue Aws::EC2::Errors::InternalError => e
539
- MU.log "Got #{e.inspect} on MU::Cloud::AWS.ec2(#{MU.myRegion}).describe_instances(instance_ids: [#{@@myInstanceId}])", MU::WARN
539
+ MU.log "Got #{e.inspect} on MU::Cloud::AWS.ec2(region: #{MU.myRegion}).describe_instances(instance_ids: [#{@@myInstanceId}])", MU::WARN
540
540
  sleep 10
541
541
  end
542
542
  @@myVPC_var
@@ -546,7 +546,7 @@ module MU
546
546
  # The AWS Subnets associated with the VPC this MU Master is in
547
547
  # XXX account for Google and non-cloud situations
548
548
  def self.mySubnets
549
- @@mySubnets_var ||= MU::Cloud::AWS.ec2(MU.myRegion).describe_subnets(
549
+ @@mySubnets_var ||= MU::Cloud::AWS.ec2(region: MU.myRegion).describe_subnets(
550
550
  filters: [
551
551
  {
552
552
  name: "vpc-id",
@@ -678,47 +678,25 @@ module MU
678
678
  end
679
679
 
680
680
 
681
- # Return the name of the S3 Mu log and key bucket for this Mu server.
681
+ # Return the name of the Mu log and key bucket for this Mu server. Not
682
+ # necessarily in any specific cloud provider.
682
683
  # @return [String]
683
- # XXX account for Google and non-cloud situations
684
- def self.adminBucketName
685
- bucketname = $MU_CFG['aws']['log_bucket_name']
686
- if bucketname.nil? or bucketname.empty?
687
- bucketname = "Mu_Logs_"+Socket.gethostname+"_"+MU::Cloud::AWS.getAWSMetaData("instance-id")
688
- end
684
+ def self.adminBucketName(platform = nil, credentials: nil)
685
+ return nil if platform and !MU::Cloud.supportedClouds.include?(platform)
686
+
687
+ clouds = platform.nil? ? MU::Cloud.supportedClouds : [platform]
688
+ clouds.each { |cloud|
689
+ cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
690
+ bucketname = cloudclass.adminBucketName(credentials)
691
+ begin
692
+ if platform or (cloudclass.hosted? and platform.nil?) or cloud == MU::Config.defaultCloud
693
+ return bucketname
694
+ end
695
+ end
696
+ }
697
+
689
698
  return bucketname
690
699
  end
691
700
 
692
- # Log bucket policy for enabling CloudTrail logging to our log bucket in S3.
693
- CLOUDTRAIL_BUCKET_POLICY = '{
694
- "Version": "2012-10-17",
695
- "Statement": [
696
- {
697
- "Sid": "AWSCloudTrailAclCheck20131101",
698
- "Effect": "Allow",
699
- "Principal": {
700
- "AWS": "arn:'+(MU::Cloud::AWS.isGovCloud? ? "aws-us-gov" : "aws")+':iam::<%= MU.account_number %>:root",
701
- "Service": "cloudtrail.amazonaws.com"
702
- },
703
- "Action": "s3:GetBucketAcl",
704
- "Resource": "arn:'+(MU::Cloud::AWS.isGovCloud? ? "aws-us-gov" : "aws")+':s3:::<%= $bucketname %>"
705
- },
706
- {
707
- "Sid": "AWSCloudTrailWrite20131101",
708
- "Effect": "Allow",
709
- "Principal": {
710
- "AWS": "arn:'+(MU::Cloud::AWS.isGovCloud? ? "aws-us-gov" : "aws")+':iam::<%= MU.account_number %>:root",
711
- "Service": "cloudtrail.amazonaws.com"
712
- },
713
- "Action": "s3:PutObject",
714
- "Resource": "arn:'+(MU::Cloud::AWS.isGovCloud? ? "aws-us-gov" : "aws")+':s3:::<%= $bucketname %>/AWSLogs/<%= MU.account_number %>/*",
715
- "Condition": {
716
- "StringEquals": {
717
- "s3:x-amz-acl": "bucket-owner-full-control"
718
- }
719
- }
720
- }
721
- ]
722
- }'
723
701
 
724
702
  end
@@ -60,6 +60,10 @@ module MU
60
60
  MU.setVar("dataDir", MU.mainDataDir)
61
61
  end
62
62
 
63
+
64
+ # XXX AWS needs to check MU::Cloud::AWS.isGovCloud? on some things, or gracefully handle the API not existing
65
+ types_in_order = ["Collection", "Function", "ServerPool", "ContainerCluster", "SearchDomain", "Server", "MsgQueue", "Database", "CacheCluster", "StoragePool", "LoadBalancer", "FirewallRule", "Alarm", "Notifier", "Log", "VPC", "DNSZone", "Collection"]
66
+
63
67
  # Load up our deployment metadata
64
68
  if !mommacat.nil?
65
69
  @mommacat = mommacat
@@ -82,124 +86,122 @@ module MU
82
86
  end
83
87
  end
84
88
 
85
- projects = {
86
- "Google" => MU::Cloud::Google.listProjects,
87
- "AWS" => ["dummy"]
88
- }
89
-
90
89
  if !@skipcloud
90
+ creds = {}
91
+ MU::Cloud.supportedClouds.each { |cloud|
92
+ if $MU_CFG[cloud.downcase] and $MU_CFG[cloud.downcase].size > 0
93
+ cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
94
+ creds[cloud] ||= {}
95
+ $MU_CFG[cloud.downcase].keys.each { |credset|
96
+ creds[cloud][credset] = cloudclass.listRegions(credentials: credset)
97
+ }
98
+ end
99
+ }
91
100
  parent_thread_id = Thread.current.object_id
92
- regions = {}
93
- regions['AWS'] = MU::Cloud::AWS.listRegions
94
- regions['Google'] = MU::Cloud::Google.listRegions
95
101
  deleted_nodes = 0
96
102
  @regionthreads = []
97
103
  keyname = "deploy-#{MU.deploy_id}"
98
104
  # XXX blindly checking for all of these resources in all clouds is now prohibitively slow. We should only do this when we don't see deployment metadata to work from.
99
- regions.each_pair { |provider, list|
100
- list.each { |r|
101
- @regionthreads << Thread.new {
102
- MU.dupGlobals(parent_thread_id)
103
- MU.setVar("curRegion", r)
104
- if projects[provider].size == 1
105
- MU.log "Checking for #{provider} resources from #{MU.deploy_id} in #{r}", MU::NOTICE
106
- end
107
-
108
- # We do these in an order that unrolls dependent resources
109
- # sensibly, and we hit :Collection twice because AWS
110
- # CloudFormation sometimes fails internally.
111
- projectthreads = []
112
- projects[provider].each { |project|
113
- projectthreads << Thread.new {
114
- MU.dupGlobals(parent_thread_id)
115
- MU.setVar("curRegion", r)
116
- if projects[provider].size > 1
117
- MU.log "Checking for #{provider} resources from #{MU.deploy_id} in #{r}, project #{project}", MU::NOTICE
118
- end
119
- MU.dupGlobals(parent_thread_id)
120
- flags = { "project" => project }
121
- MU::Cloud::Collection.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Collection"]) > 0
122
- MU::Cloud::Function.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Function"]) > 0
123
- MU::Cloud::ServerPool.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["ServerPool"]) > 0
124
- begin
125
- MU::Cloud::ContainerCluster.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["ContainerCluster"]) > 0
126
- rescue Seahorse::Client::NetworkingError => e
127
- MU.log "Service not available in AWS region #{r}, skipping", MU::DEBUG, details: e.message
128
- end
129
- MU::Cloud::SearchDomain.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["SearchDomain"]) > 0
130
- MU::Cloud::Server.cleanup(skipsnapshots: @skipsnapshots, onlycloud: @onlycloud, noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Server"]) > 0
131
- if provider == "AWS"
132
- MU::Cloud::MsgQueue.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["MsgQueue"]) > 0
133
- MU::Cloud::Database.cleanup(skipsnapshots: @skipsnapshots, noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Database"]) > 0
134
- end
135
- MU::Cloud::CacheCluster.cleanup(skipsnapshots: @skipsnapshots, noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["CacheCluster"]) > 0
136
- MU::Cloud::StoragePool.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["StoragePool"]) > 0
137
- if provider == "AWS"
138
- MU::Cloud::FirewallRule.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["FirewallRule", "Server", "ServerPool", "Database", "StoragePool"]) > 0
139
- end
140
- if @mommacat.nil? or @mommacat.numKittens(types: ["LoadBalancer"]) > 0
141
- MU::Cloud::LoadBalancer.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags)
142
- if provider == "AWS"
143
- MU::Cloud::FirewallRule.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags)
105
+ creds.each_pair { |provider, credsets|
106
+ credsets.each_pair { |credset, regions|
107
+ global_vs_region_semaphore = Mutex.new
108
+ global_done = []
109
+ regions.each { |r|
110
+ @regionthreads << Thread.new {
111
+ MU.dupGlobals(parent_thread_id)
112
+ MU.setVar("curRegion", r)
113
+ projects = []
114
+ if $MU_CFG[provider.downcase][credset]["project"]
115
+ # XXX GCP credential schema needs an array for projects
116
+ projects << $MU_CFG[provider.downcase][credset]["project"]
117
+ end
118
+
119
+ if projects == [""]
120
+ MU.log "Checking for #{provider}/#{credset} resources from #{MU.deploy_id} in #{r}", MU::NOTICE
121
+ end
122
+
123
+ # We do these in an order that unrolls dependent resources
124
+ # sensibly, and we hit :Collection twice because AWS
125
+ # CloudFormation sometimes fails internally.
126
+ projectthreads = []
127
+ projects.each { |project|
128
+ projectthreads << Thread.new {
129
+ MU.dupGlobals(parent_thread_id)
130
+ MU.setVar("curRegion", r)
131
+ if project != ""
132
+ MU.log "Checking for #{provider}/#{credset} resources from #{MU.deploy_id} in #{r}, project #{project}", MU::NOTICE
144
133
  end
145
- end
146
- MU::Cloud::Alarm.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Alarm"]) > 0 # XXX other resources can make these appear, I think- which ones?
147
- MU::Cloud::Notification.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Notification"]) > 0 # XXX other resources can make these appear, I think- which ones?
148
- MU::Cloud::Log.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Log"]) > 0 # XXX other resources can make these appear, I think- which ones?
149
- if provider == "AWS" and (@mommacat.nil? or @mommacat.numKittens(types: ["VPC"]) > 0)
150
- MU::Cloud::FirewallRule.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags)
151
- MU::Cloud::VPC.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, cloud: provider, flags: flags)
152
- end
153
- MU::Cloud::Collection.cleanup(noop: @noop, ignoremaster: @ignoremaster, region: r, wait: true, cloud: provider, flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Collection"]) > 0
154
- }
155
- }
156
- projectthreads.each do |t|
157
- t.join
158
- end
159
134
 
160
- if provider == "AWS"
161
- resp = MU::Cloud::AWS.ec2(r).describe_key_pairs(
162
- filters: [{name: "key-name", values: [keyname]}]
163
- )
164
- resp.data.key_pairs.each { |keypair|
165
- MU.log "Deleting key pair #{keypair.key_name} from #{r}"
166
- MU::Cloud::AWS.ec2(r).delete_key_pair(key_name: keypair.key_name) if !@noop
135
+ MU.dupGlobals(parent_thread_id)
136
+ flags = {
137
+ "project" => project,
138
+ "onlycloud" => @onlycloud,
139
+ "skipsnapshots" => @skipsnapshots,
140
+ }
141
+ types_in_order.each { |t|
142
+ begin
143
+ skipme = false
144
+ global_vs_region_semaphore.synchronize {
145
+ if Object.const_get("MU").const_get("Cloud").const_get(provider).const_get(t).isGlobal?
146
+ if !global_done.include?(t)
147
+ global_done << t
148
+ flags['global'] = true
149
+ else
150
+ skipme = true
151
+ end
152
+ end
153
+ }
154
+ next if skipme
155
+ rescue MU::Cloud::MuCloudResourceNotImplemented => e
156
+ next
157
+ rescue MU::MuError, NoMethodError => e
158
+ MU.log e.message, MU::WARN
159
+ next
160
+ end
161
+
162
+ if @mommacat.nil? or @mommacat.numKittens(types: [t]) > 0
163
+ begin
164
+ resclass = Object.const_get("MU").const_get("Cloud").const_get(t)
165
+ resclass.cleanup(
166
+ noop: @noop,
167
+ ignoremaster: @ignoremaster,
168
+ region: r,
169
+ cloud: provider,
170
+ flags: flags,
171
+ credentials: credset
172
+ )
173
+ rescue Seahorse::Client::NetworkingError => e
174
+ MU.log "Service not available in AWS region #{r}, skipping", MU::DEBUG, details: e.message
175
+ end
176
+ end
177
+ }
178
+ }
167
179
  }
168
- end
180
+ projectthreads.each do |t|
181
+ t.join
182
+ end
183
+
184
+ # XXX move to MU::AWS
185
+ if provider == "AWS"
186
+ resp = MU::Cloud::AWS.ec2(region: r, credentials: credset).describe_key_pairs(
187
+ filters: [{name: "key-name", values: [keyname]}]
188
+ )
189
+ resp.data.key_pairs.each { |keypair|
190
+ MU.log "Deleting key pair #{keypair.key_name} from #{r}"
191
+ MU::Cloud::AWS.ec2(region: r, credentials: credset).delete_key_pair(key_name: keypair.key_name) if !@noop
192
+ }
193
+ end
194
+ }
169
195
  }
170
196
  }
171
- MU::Cloud::Role.cleanup(noop: @noop, ignoremaster: @ignoremaster, cloud: provider) if @mommacat.nil? or @mommacat.numKittens(types: ["Role"]) > 0
172
- MU::Cloud::Group.cleanup(noop: @noop, ignoremaster: @ignoremaster, cloud: provider) if @mommacat.nil? or @mommacat.numKittens(types: ["Group"]) > 0
173
- MU::Cloud::User.cleanup(noop: @noop, ignoremaster: @ignoremaster, cloud: provider) if @mommacat.nil? or @mommacat.numKittens(types: ["User"]) > 0
174
197
  }
175
198
 
176
- # knock over region-agnostic resources
177
-
178
199
  @regionthreads.each do |t|
179
200
  t.join
180
201
  end
181
202
  @projectthreads = []
182
203
 
183
204
 
184
- projects["Google"].each { |project|
185
- @projectthreads << Thread.new {
186
- MU.dupGlobals(parent_thread_id)
187
- flags = { "global" => true, "project" => project }
188
- MU::Cloud::ServerPool.cleanup(noop: @noop, ignoremaster: @ignoremaster, cloud: "Google", flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["ServerPool"]) > 0
189
- MU::Cloud::FirewallRule.cleanup(noop: @noop, ignoremaster: @ignoremaster, cloud: "Google", flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["FirewallRule"]) > 0
190
- MU::Cloud::LoadBalancer.cleanup(noop: @noop, ignoremaster: @ignoremaster, cloud: "Google", flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["LoadBalancer"]) > 0
191
- MU::Cloud::Database.cleanup(skipsnapshots: @skipsnapshots, noop: @noop, ignoremaster: @ignoremaster, cloud: "Google", flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["Database"]) > 0
192
- MU::Cloud::VPC.cleanup(noop: @noop, ignoremaster: @ignoremaster, cloud: "Google", flags: flags) if @mommacat.nil? or @mommacat.numKittens(types: ["VPC"]) > 0
193
-
194
- }
195
- }
196
-
197
- if !MU::Cloud::AWS.isGovCloud?
198
- if $MU_CFG['aws'] and $MU_CFG['aws']['account_number']
199
- MU::Cloud::DNSZone.cleanup(noop: @noop, cloud: "AWS", ignoremaster: @ignoremaster) if @mommacat.nil? or @mommacat.numKittens(types: ["DNSZone"]) > 0
200
- end
201
- end
202
-
203
205
  @projectthreads.each do |t|
204
206
  t.join
205
207
  end
@@ -310,7 +312,7 @@ module MU
310
312
 
311
313
  if !@noop and !@skipcloud
312
314
  if $MU_CFG['aws'] and $MU_CFG['aws']['account_number']
313
- MU::Cloud::AWS.s3(MU.myRegion).delete_object(
315
+ MU::Cloud::AWS.s3(region: MU.myRegion).delete_object(
314
316
  bucket: MU.adminBucketName,
315
317
  key: "#{MU.deploy_id}-secret"
316
318
  )