cloud-mu 3.1.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +15 -3
  3. data/ansible/roles/mu-windows/README.md +33 -0
  4. data/ansible/roles/mu-windows/defaults/main.yml +2 -0
  5. data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
  6. data/ansible/roles/mu-windows/files/config.xml +76 -0
  7. data/ansible/roles/mu-windows/handlers/main.yml +2 -0
  8. data/ansible/roles/mu-windows/meta/main.yml +53 -0
  9. data/ansible/roles/mu-windows/tasks/main.yml +36 -0
  10. data/ansible/roles/mu-windows/tests/inventory +2 -0
  11. data/ansible/roles/mu-windows/tests/test.yml +5 -0
  12. data/ansible/roles/mu-windows/vars/main.yml +2 -0
  13. data/bin/mu-adopt +10 -13
  14. data/bin/mu-azure-tests +57 -0
  15. data/bin/mu-cleanup +2 -4
  16. data/bin/mu-configure +52 -0
  17. data/bin/mu-deploy +3 -3
  18. data/bin/mu-findstray-tests +25 -0
  19. data/bin/mu-gen-docs +2 -4
  20. data/bin/mu-load-config.rb +2 -3
  21. data/bin/mu-node-manage +15 -16
  22. data/bin/mu-run-tests +135 -37
  23. data/cloud-mu.gemspec +22 -20
  24. data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
  25. data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
  26. data/cookbooks/mu-tools/libraries/helper.rb +3 -2
  27. data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
  28. data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
  29. data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
  30. data/cookbooks/mu-tools/recipes/eks.rb +2 -2
  31. data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
  32. data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
  33. data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
  34. data/cookbooks/mu-tools/resources/disk.rb +1 -1
  35. data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
  36. data/extras/clean-stock-amis +25 -19
  37. data/extras/generate-stock-images +1 -0
  38. data/extras/image-generators/AWS/win2k12.yaml +18 -13
  39. data/extras/image-generators/AWS/win2k16.yaml +18 -13
  40. data/extras/image-generators/AWS/win2k19.yaml +21 -0
  41. data/extras/image-generators/Google/centos6.yaml +1 -0
  42. data/extras/image-generators/Google/centos7.yaml +1 -1
  43. data/modules/mommacat.ru +6 -16
  44. data/modules/mu.rb +165 -111
  45. data/modules/mu/adoption.rb +401 -68
  46. data/modules/mu/cleanup.rb +199 -306
  47. data/modules/mu/cloud.rb +100 -1632
  48. data/modules/mu/cloud/database.rb +49 -0
  49. data/modules/mu/cloud/dnszone.rb +46 -0
  50. data/modules/mu/cloud/machine_images.rb +212 -0
  51. data/modules/mu/cloud/providers.rb +81 -0
  52. data/modules/mu/cloud/resource_base.rb +920 -0
  53. data/modules/mu/cloud/server.rb +40 -0
  54. data/modules/mu/cloud/server_pool.rb +1 -0
  55. data/modules/mu/cloud/ssh_sessions.rb +228 -0
  56. data/modules/mu/cloud/winrm_sessions.rb +237 -0
  57. data/modules/mu/cloud/wrappers.rb +165 -0
  58. data/modules/mu/config.rb +171 -1767
  59. data/modules/mu/config/alarm.rb +2 -6
  60. data/modules/mu/config/bucket.rb +4 -4
  61. data/modules/mu/config/cache_cluster.rb +1 -1
  62. data/modules/mu/config/collection.rb +4 -4
  63. data/modules/mu/config/container_cluster.rb +9 -4
  64. data/modules/mu/config/database.rb +83 -104
  65. data/modules/mu/config/database.yml +1 -2
  66. data/modules/mu/config/dnszone.rb +6 -6
  67. data/modules/mu/config/doc_helpers.rb +516 -0
  68. data/modules/mu/config/endpoint.rb +4 -4
  69. data/modules/mu/config/firewall_rule.rb +103 -4
  70. data/modules/mu/config/folder.rb +4 -4
  71. data/modules/mu/config/function.rb +3 -3
  72. data/modules/mu/config/group.rb +4 -4
  73. data/modules/mu/config/habitat.rb +4 -4
  74. data/modules/mu/config/loadbalancer.rb +60 -14
  75. data/modules/mu/config/log.rb +4 -4
  76. data/modules/mu/config/msg_queue.rb +4 -4
  77. data/modules/mu/config/nosqldb.rb +4 -4
  78. data/modules/mu/config/notifier.rb +3 -3
  79. data/modules/mu/config/ref.rb +365 -0
  80. data/modules/mu/config/role.rb +4 -4
  81. data/modules/mu/config/schema_helpers.rb +509 -0
  82. data/modules/mu/config/search_domain.rb +4 -4
  83. data/modules/mu/config/server.rb +97 -70
  84. data/modules/mu/config/server.yml +1 -0
  85. data/modules/mu/config/server_pool.rb +5 -9
  86. data/modules/mu/config/storage_pool.rb +1 -1
  87. data/modules/mu/config/tail.rb +200 -0
  88. data/modules/mu/config/user.rb +4 -4
  89. data/modules/mu/config/vpc.rb +70 -27
  90. data/modules/mu/config/vpc.yml +0 -1
  91. data/modules/mu/defaults/AWS.yaml +83 -60
  92. data/modules/mu/defaults/Azure.yaml +1 -0
  93. data/modules/mu/defaults/Google.yaml +3 -2
  94. data/modules/mu/deploy.rb +30 -26
  95. data/modules/mu/groomer.rb +17 -2
  96. data/modules/mu/groomers/ansible.rb +188 -41
  97. data/modules/mu/groomers/chef.rb +116 -55
  98. data/modules/mu/logger.rb +127 -148
  99. data/modules/mu/master.rb +389 -2
  100. data/modules/mu/master/chef.rb +3 -4
  101. data/modules/mu/master/ldap.rb +3 -3
  102. data/modules/mu/master/ssl.rb +12 -3
  103. data/modules/mu/mommacat.rb +217 -2612
  104. data/modules/mu/mommacat/daemon.rb +397 -0
  105. data/modules/mu/mommacat/naming.rb +473 -0
  106. data/modules/mu/mommacat/search.rb +495 -0
  107. data/modules/mu/mommacat/storage.rb +722 -0
  108. data/modules/mu/{clouds → providers}/README.md +1 -1
  109. data/modules/mu/{clouds → providers}/aws.rb +271 -112
  110. data/modules/mu/{clouds → providers}/aws/alarm.rb +5 -3
  111. data/modules/mu/{clouds → providers}/aws/bucket.rb +26 -22
  112. data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +33 -67
  113. data/modules/mu/{clouds → providers}/aws/collection.rb +24 -23
  114. data/modules/mu/{clouds → providers}/aws/container_cluster.rb +681 -721
  115. data/modules/mu/providers/aws/database.rb +1744 -0
  116. data/modules/mu/{clouds → providers}/aws/dnszone.rb +64 -63
  117. data/modules/mu/{clouds → providers}/aws/endpoint.rb +22 -27
  118. data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +214 -244
  119. data/modules/mu/{clouds → providers}/aws/folder.rb +7 -7
  120. data/modules/mu/{clouds → providers}/aws/function.rb +17 -22
  121. data/modules/mu/{clouds → providers}/aws/group.rb +23 -23
  122. data/modules/mu/{clouds → providers}/aws/habitat.rb +17 -14
  123. data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +57 -48
  124. data/modules/mu/{clouds → providers}/aws/log.rb +15 -12
  125. data/modules/mu/{clouds → providers}/aws/msg_queue.rb +17 -16
  126. data/modules/mu/{clouds → providers}/aws/nosqldb.rb +18 -11
  127. data/modules/mu/{clouds → providers}/aws/notifier.rb +11 -6
  128. data/modules/mu/{clouds → providers}/aws/role.rb +112 -86
  129. data/modules/mu/{clouds → providers}/aws/search_domain.rb +39 -33
  130. data/modules/mu/{clouds → providers}/aws/server.rb +835 -1133
  131. data/modules/mu/{clouds → providers}/aws/server_pool.rb +56 -60
  132. data/modules/mu/{clouds → providers}/aws/storage_pool.rb +24 -42
  133. data/modules/mu/{clouds → providers}/aws/user.rb +21 -22
  134. data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
  135. data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
  136. data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
  137. data/modules/mu/{clouds → providers}/aws/vpc.rb +523 -929
  138. data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
  139. data/modules/mu/{clouds → providers}/azure.rb +29 -9
  140. data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
  141. data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
  142. data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
  143. data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
  144. data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
  145. data/modules/mu/{clouds → providers}/azure/server.rb +95 -48
  146. data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
  147. data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
  148. data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
  149. data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
  150. data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
  151. data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
  152. data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
  153. data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
  154. data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
  155. data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
  156. data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
  157. data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
  158. data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
  159. data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
  160. data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
  161. data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
  162. data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
  163. data/modules/mu/{clouds → providers}/docker.rb +0 -0
  164. data/modules/mu/{clouds → providers}/google.rb +67 -30
  165. data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
  166. data/modules/mu/{clouds → providers}/google/container_cluster.rb +84 -77
  167. data/modules/mu/{clouds → providers}/google/database.rb +10 -20
  168. data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
  169. data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
  170. data/modules/mu/{clouds → providers}/google/function.rb +139 -167
  171. data/modules/mu/{clouds → providers}/google/group.rb +29 -34
  172. data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
  173. data/modules/mu/{clouds → providers}/google/loadbalancer.rb +18 -20
  174. data/modules/mu/{clouds → providers}/google/role.rb +92 -58
  175. data/modules/mu/{clouds → providers}/google/server.rb +242 -155
  176. data/modules/mu/{clouds → providers}/google/server_pool.rb +25 -44
  177. data/modules/mu/{clouds → providers}/google/user.rb +95 -31
  178. data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
  179. data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
  180. data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
  181. data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
  182. data/modules/tests/bucket.yml +4 -0
  183. data/modules/tests/centos6.yaml +11 -0
  184. data/modules/tests/centos7.yaml +11 -0
  185. data/modules/tests/centos8.yaml +12 -0
  186. data/modules/tests/ecs.yaml +23 -0
  187. data/modules/tests/includes-and-params.yaml +2 -1
  188. data/modules/tests/rds.yaml +108 -0
  189. data/modules/tests/regrooms/aws-iam.yaml +201 -0
  190. data/modules/tests/regrooms/bucket.yml +19 -0
  191. data/modules/tests/regrooms/rds.yaml +123 -0
  192. data/modules/tests/server-with-scrub-muisms.yaml +1 -0
  193. data/modules/tests/super_simple_bok.yml +1 -3
  194. data/modules/tests/win2k12.yaml +17 -5
  195. data/modules/tests/win2k16.yaml +25 -0
  196. data/modules/tests/win2k19.yaml +25 -0
  197. data/requirements.txt +1 -0
  198. data/spec/mu/clouds/azure_spec.rb +2 -2
  199. metadata +232 -154
  200. data/extras/image-generators/AWS/windows.yaml +0 -18
  201. data/modules/mu/clouds/aws/database.rb +0 -1985
@@ -105,7 +105,7 @@ if $opts[:dryrun]
105
105
  Thread.handle_interrupt(MU::Cloud::MuCloudResourceNotImplemented => :never) {
106
106
  begin
107
107
  Thread.handle_interrupt(MU::Cloud::MuCloudResourceNotImplemented => :immediate) {
108
- MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::WARN, verbosity: MU::Logger::NORMAL
108
+ MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::NOTICE, verbosity: MU::Logger::NORMAL
109
109
  Thread.current.exit
110
110
  }
111
111
  ensure
@@ -124,7 +124,7 @@ if $opts[:dryrun]
124
124
  )
125
125
  cost_dummy_deploy.run
126
126
  rescue MU::Cloud::MuCloudResourceNotImplemented, MU::Cloud::MuCloudFlagNotImplemented
127
- MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::WARN, verbosity: MU::Logger::NORMAL
127
+ MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::NOTICE, verbosity: MU::Logger::NORMAL
128
128
  end
129
129
  end
130
130
  exit
@@ -135,7 +135,7 @@ if $opts[:update]
135
135
  # TODO consider whether this is useful/valid
136
136
  # old_conf = JSON.parse(File.read(deploy.deploy_dir+"/basket_of_kittens.json"))
137
137
  # stack_conf = old_conf.merge(stack_conf)
138
- deploy.updateBasketofKittens(stack_conf)
138
+ deploy.updateBasketofKittens(stack_conf, skip_validation: true)
139
139
  deployer = MU::Deploy.new(
140
140
  deploy.environment,
141
141
  verbosity: verbosity,
@@ -0,0 +1,25 @@
1
+ #!/usr/local/ruby-current/bin/ruby
2
+ # Copyright:: Copyright (c) 2014 eGlobalTech, Inc., all rights reserved
3
+ #
4
+ # Licensed under the BSD-3 license (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License in the root of the project or at
7
+ #
8
+ # http://egt-labs.com/mu/LICENSE.html
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'rubygems'
17
+ require 'bundler/setup'
18
+ require 'json'
19
+ require 'erb'
20
+ require 'optimist'
21
+ require 'json-schema'
22
+ require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
23
+ require 'mu'
24
+
25
+ MU::MommaCat.findStray("AWS", "firewall_rule", region: MU.myRegion, dummy_ok: true, debug: true)
@@ -79,8 +79,7 @@ EOF
79
79
  impl_counts[type] ||= 0
80
80
  [a, b].each { |cloud|
81
81
  begin
82
- myclass = Object.const_get("MU").const_get("Cloud").const_get(cloud).const_get(type)
83
- case myclass.quality
82
+ case MU::Cloud.resourceClass(cloud, type).quality
84
83
  when MU::Cloud::RELEASE
85
84
  cloud_is_useful[cloud] = true
86
85
  counts[cloud] += 4
@@ -114,8 +113,7 @@ EOF
114
113
  cloudlist.each { |cloud|
115
114
  readme += "<td><center>"
116
115
  begin
117
- myclass = Object.const_get("MU").const_get("Cloud").const_get(cloud).const_get(type)
118
- case myclass.quality
116
+ case MU::Cloud.resourceClass(cloud, type).quality
119
117
  when MU::Cloud::RELEASE
120
118
  readme += "<img src='release.png' style='#{icon_style}' title='Release Quality' alt='[Release Quality]'>"
121
119
  when MU::Cloud::BETA
@@ -36,8 +36,7 @@ def validateClouds(cfg)
36
36
  cfg[cloud]["default"]["default"] = true
37
37
  found_default = true
38
38
  else
39
- missing_alias = false
40
- cfg[cloud].each_pair { |acctalias, acct|
39
+ cfg[cloud].values.each { |acct|
41
40
  if acct["default"]
42
41
  if found_default
43
42
  puts "Multiple accounts have 'default' set in #{cloud}"
@@ -205,7 +204,7 @@ def cfgPath
205
204
  end
206
205
  end
207
206
  home = Etc.getpwuid(Process.uid).dir
208
- username = Etc.getpwuid(Process.uid).name
207
+ Etc.getpwuid(Process.uid).name # validates existence of a username
209
208
  if Process.uid == 0 and !in_gem
210
209
  if ENV.include?('MU_INSTALLDIR')
211
210
  ENV['MU_INSTALLDIR']+"/etc/mu.yaml"
@@ -29,9 +29,9 @@ Usage:
29
29
  opt :all, "Operate on all nodes/deploys. Use with caution.", :require => false, :default => false, :type => :boolean
30
30
  opt :platform, "Operate exclusively on one nodes of a particular operating system. Can be used in conjunction with -a or -d. Valid platforms: linux, windows", :require => false, :type => :string
31
31
  opt :environment, "Operate exclusively on one nodes with a particular environment (e.g. dev, prod). Can be used in conjunction with -a or -d.", :require => false, :type => :string
32
- opt :override_chef_runlist, "An alternate runlist to pass to Chef, in chefrun mode.", :require => false, :type => :string
32
+ opt :override_chef_runlist, "An alternate runlist to pass to Chef, in groomeronly mode.", :require => false, :type => :string
33
33
  opt :xecute, "Run a shell command on matching nodes. Overrides --mode and suppresses some informational output in favor of scriptability.", :require => false, :type => :string
34
- opt :mode, "Action to perform on matching nodes. Valid actions: groom, chefrun, awsmeta, vaults, certs, chefupgrade", :require => false, :default => "chefrun", :type => :string
34
+ opt :mode, "Action to perform on matching nodes. Valid actions: groom, groomeronly, awsmeta, vaults, certs, chefupgrade", :require => false, :default => "groomeronly", :type => :string
35
35
  opt :verbose, "Show output from Chef runs, etc", :require => false, :default => false, :type => :boolean
36
36
  opt :winrm, "Force WinRM connection. Disable SSH fallback", :require => false, :default => false, :type => :boolean
37
37
  opt :info, "List a particular node attribute", :require => false, :default => 'nodename', :type => :string
@@ -39,8 +39,10 @@ end
39
39
 
40
40
  MU.setLogging(MU::Logger::LOUD) if $opts[:verbose]
41
41
 
42
- if !["groom", "chefrun", "vaults", "userdata", "awsmeta", "certs", "chefupgrade"].include?($opts[:mode])
43
- Optimist::die(:mode, "--mode must be one of: groom, chefrun, awsmeta, vaults, certs, chefupgrade")
42
+ $opts[:mode] = "groomeronly" if $opts[:mode] == "chefrun"
43
+
44
+ if !["groom", "groomeronly", "vaults", "userdata", "awsmeta", "certs", "chefupgrade"].include?($opts[:mode])
45
+ Optimist::die(:mode, "--mode must be one of: groom, groomeronly, awsmeta, vaults, certs, chefupgrade")
44
46
  end
45
47
  if $opts[:platform] and !["linux", "windows"].include?($opts[:platform])
46
48
  Optimist::die(:platform, "--platform must be one of: linux, windows")
@@ -176,7 +178,7 @@ end
176
178
  exit 1 if !ok
177
179
 
178
180
 
179
- def reGroom(deploys = MU::MommaCat.listDeploys, nodes = [], vaults_only: false)
181
+ def reGroom(deploys = MU::MommaCat.listDeploys, nodes = [], vaults_only: false, groomeronly: false)
180
182
  badnodes = []
181
183
  count = 0
182
184
  deploys.each { |muid|
@@ -196,6 +198,8 @@ def reGroom(deploys = MU::MommaCat.listDeploys, nodes = [], vaults_only: false)
196
198
  server.config["vault_access"].each { |v|
197
199
  MU::Groomer::Chef.grantSecretAccess(mu_name, v['vault'], v['item'])
198
200
  }
201
+ elsif groomeronly
202
+ server.groomer.run
199
203
  else
200
204
  mommacat.groomNode(server.cloud_id, nodeclass, type, mu_name: mu_name)
201
205
  end
@@ -227,7 +231,7 @@ def reGroom(deploys = MU::MommaCat.listDeploys, nodes = [], vaults_only: false)
227
231
  end
228
232
  end
229
233
 
230
- def runCommand(deploys = MU::MommaCat.listDeploys, nodes = [], cmd = nil, print_output: $opts[:verbose], noop: false, chefrun: false, chef_runlist: nil)
234
+ def runCommand(deploys = MU::MommaCat.listDeploys, nodes = [], cmd = nil, print_output: $opts[:verbose], noop: false)
231
235
  badnodes = []
232
236
  count = 0
233
237
  deploys.each { |muid|
@@ -247,12 +251,6 @@ def runCommand(deploys = MU::MommaCat.listDeploys, nodes = [], cmd = nil, print_
247
251
  next
248
252
  end
249
253
 
250
- # Generate the command if attemting a chef run
251
- if chefrun
252
- cmd = serverobj.windows? ? "powershell -Command chef-client" : "chef-client || sudo chef-client"
253
- cmd += " -o '#{chef_runlist}'" if chef_runlist
254
- end
255
-
256
254
  MU.log "Running '#{cmd}' on #{nodename} (##{count})" if !print_output
257
255
 
258
256
  # Set Variables to catch the output and exit code of the execution
@@ -363,7 +361,7 @@ def runCommand(deploys = MU::MommaCat.listDeploys, nodes = [], cmd = nil, print_
363
361
  }
364
362
 
365
363
  if badnodes.size > 0
366
- cmd = "Chef" if $opts[:mode] == "chefrun"
364
+ cmd = "Chef" if $opts[:mode] == "groomeronly"
367
365
  if !print_output
368
366
  MU.log "Not all `#{cmd}` runs exited cleanly", MU::WARN, details: badnodes
369
367
  else
@@ -687,12 +685,13 @@ elsif $opts[:mode] == "vaults"
687
685
  reGroom(do_deploys, do_nodes, vaults_only: true)
688
686
  elsif $opts[:mode] == "chefupgrade"
689
687
  chefUpgrade(do_deploys, do_nodes)
690
- elsif $opts[:mode] == "chefrun"
688
+ elsif $opts[:mode] == "groomeronly"
691
689
  print_output = $opts[:verbose] || do_nodes.size == 1
692
690
  if $opts[:override_chef_runlist]
693
- runCommand(do_deploys, do_nodes, chef_runlist: $opts[:override_chef_runlist], chefrun: true, print_output: print_output)
691
+ # runCommand(do_deploys, do_nodes, chef_runlist: $opts[:override_chef_runlist], groomeronly: true, print_output: print_output)
694
692
  else
695
- runCommand(do_deploys, do_nodes, chefrun: true, print_output: print_output)
693
+ # runCommand(do_deploys, do_nodes, groomeronly: true, print_output: print_output)
694
+ reGroom(do_deploys, do_nodes, groomeronly: true)
696
695
  end
697
696
  elsif $opts[:mode] == "userdata" or $opts[:mode] == "awsmeta"
698
697
  # Need Google equiv and to select nodes correctly based on what cloud they're in
@@ -13,53 +13,139 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ bindir = File.realpath(File.expand_path(File.dirname(__FILE__)))
17
+ dir = File.realpath(File.expand_path(bindir+"/../modules/tests"))
18
+ Dir.chdir(dir)
19
+
16
20
  require 'colorize'
17
21
  require 'optimist'
18
- bindir = File.realpath(File.expand_path(File.dirname(__FILE__)))
19
22
  require bindir+"/mu-load-config.rb"
20
23
  require 'mu'
21
24
 
25
+ require 'rubygems'
26
+ require 'bundler/setup'
27
+ require 'json'
28
+ require 'erb'
29
+ require 'json-schema'
30
+
22
31
  $opts = Optimist::options do
23
32
  banner <<-EOS
24
33
  Usage:
25
- #{$0} [-e <environment>] [-r region] [-v] [-d] [-w] [-c] [-n] [-s] [-j] [-p parameter=value] /path/to/stack/config.[json|yaml] [-u deploy_id [-l]] [-r deploy_id]
34
+ #{$0} [-m <#>] [-f] [-v] [specific test BoK to run [...]]
26
35
  EOS
27
36
  opt :max_threads, "Environment to set on creation.", :require => false, :default => 3, :type => :integer
28
37
  opt :full, "Actually run deploys, instead of --dryrun", :require => false, :default => false
38
+ opt :verbose, "Show more information while running", :require => false, :default => false
29
39
  end
30
40
 
31
- dir = File.realpath(File.expand_path(bindir+"/../modules/tests"))
32
- Dir.chdir(dir)
41
+ only = ARGV
33
42
 
34
43
  files = Dir.glob("*.yaml", base: dir)
35
44
  files.concat(Dir.glob("*.yml", base: dir))
36
- baseclouds = MU::Cloud.supportedClouds.reject { |c| c == "CloudFormation" }
45
+ baseclouds = MU::Cloud.availableClouds.reject { |c| c == "CloudFormation" }
37
46
 
38
47
  commands = {}
48
+ failures = []
49
+ if only and only.size > 0
50
+ files.reject! { |f| !only.include?(f) }
51
+ if files.size == 0
52
+ MU.log "No files in #{dir} matched requested list", MU::WARN, details: only
53
+ exit 1
54
+ end
55
+ end
39
56
 
40
57
  files.each { |f|
41
58
  clouds = baseclouds.dup
59
+ groomer_match = true
42
60
  File.open(dir+"/"+f).readlines.each { |l|
43
61
  l.chomp!
44
- next if !l.match(/^\s*#\s*clouds: (.*)/)
45
- clouds = []
46
- cloudstr = Regexp.last_match[1]
47
- cloudstr.split(/\s*,\s*/).each { |c|
48
- baseclouds.each { |cloud|
49
- if cloud.match(/^#{Regexp.quote(c)}$/i)
50
- clouds << cloud
62
+ if l.match(/^\s*#\s*clouds: (.*)/)
63
+ clouds = []
64
+ cloudstr = Regexp.last_match[1]
65
+ cloudstr.split(/\s*,\s*/).each { |c|
66
+ baseclouds.each { |cloud|
67
+ if cloud.match(/^#{Regexp.quote(c)}$/i)
68
+ clouds << cloud
69
+ end
70
+ }
71
+ }
72
+ elsif l.match(/^\s*#\s*groomers: (.*)/)
73
+ groomerstr = Regexp.last_match[1]
74
+ groomerstr.split(/\s*,\s*/).each { |g|
75
+ if !MU::Groomer.availableGroomers.include?(g)
76
+ MU.log "#{f} requires groomer #{g}, which is not available. This test will be skipped.", MU::NOTICE
77
+ groomer_match = false
51
78
  end
52
79
  }
53
- }
54
- break
80
+ end
55
81
  }
82
+ if !groomer_match
83
+ next
84
+ end
85
+
56
86
  clouds.each { |cloud|
57
- commands["mu-deploy #{f} --cloud #{cloud} #{$opts[:full] ? "" : "--dryrun"}"] = { "file" => f, "cloud" => cloud }
87
+ cmd = "mu-deploy #{f} --cloud #{cloud} #{$opts[:full] ? "" : "--dryrun"}"
88
+ commands[cmd] = {
89
+ "file" => f,
90
+ "cloud" => cloud,
91
+ }
92
+ if $opts[:full]
93
+ $environment = "dev"
94
+ begin
95
+ conf_engine = MU::Config.new(f, cloud: cloud)
96
+ rescue StandardError => e
97
+ MU.log e.message+" parsing "+f+" with cloud "+cloud, MU::WARN, details: e.backtrace
98
+ failures << f+" ("+commands[cmd]["cloud"]+")"
99
+ next
100
+ end
101
+ parsed = MU::Config.stripConfig(conf_engine.config)
102
+ types = []
103
+ MU::Cloud.resource_types.values.each { |attrs|
104
+ if parsed.has_key?(attrs[:cfg_plural])
105
+ types << attrs[:cfg_plural]
106
+ end
107
+ }
108
+ commands[cmd]["parsed"] = parsed
109
+ commands[cmd]["types"] = types
110
+ end
58
111
  }
59
112
  }
60
113
 
61
114
  puts "Running #{commands.size.to_s.bold} #{$opts[:full] ? "full deploy" : "parse"} tests from #{files.size.to_s.bold} Baskets of Kittens across #{baseclouds.size.to_s.bold} clouds"
62
115
 
116
+ @output_semaphore = Mutex.new
117
+
118
+ def execCommand(cmd, results_stash)
119
+ @output_semaphore.synchronize {
120
+ puts cmd if $opts[:verbose]
121
+ }
122
+
123
+ ok = true
124
+ output = %x{#{cmd} 2>&1}
125
+ ok = false if $?.exitstatus != 0
126
+
127
+ results_stash["output"] += output
128
+
129
+ @output_semaphore.synchronize {
130
+ if ok
131
+ if $opts[:verbose]
132
+ puts "#{cmd} SUCCEEDED".green
133
+ else
134
+ print ".".green
135
+ end
136
+ else
137
+ if $opts[:verbose]
138
+ puts "#{cmd} FAILED:".light_red
139
+ puts output
140
+ else
141
+ print ".".light_red
142
+ end
143
+ end
144
+ }
145
+
146
+ ok
147
+ end
148
+
63
149
  threads = []
64
150
  results = {}
65
151
  commands.keys.each { |cmd|
@@ -72,21 +158,40 @@ commands.keys.each { |cmd|
72
158
  end
73
159
 
74
160
  threads << Thread.new(cmd) { |cmd_thr|
75
- results[cmd_thr] = {}
76
- puts %Q{#{cmd_thr} 2>&1}
77
- results[cmd_thr]["output"] = %x{#{cmd_thr} 2>&1}
78
- if $?.exitstatus != 0
79
- results[cmd_thr]["status"] = false
80
- print ".".light_red
81
- else
82
- results[cmd_thr]["status"] = true
83
- print ".".green
161
+ results[cmd_thr] = { "output" => "", "failed" => [] }
162
+ if !execCommand(cmd_thr, results[cmd_thr])
163
+ results[cmd_thr]["failed"] << "main"
84
164
  end
165
+
85
166
  if $opts[:full] and results[cmd_thr]["output"].match(/deploy - Deployment id: .*? \((.*?)\)/)
86
167
  deploy_id = Regexp.last_match[1]
87
- results[cmd_thr]["output"] += %x{mu-cleanup #{deploy_id} --skipsnapshots}
88
- if $?.exitstatus != 0
89
- results[cmd_thr]["status"] = false
168
+ adoptdir = Dir.mktmpdir(commands[cmd_thr]["file"].gsub(/[^a-z0-9]|yaml$/i, ""))
169
+ if commands[cmd_thr]["types"] and commands[cmd_thr]["types"].size > 0
170
+ adopt = "cd #{adoptdir} && mu-adopt --appname adoptone --grouping omnibus --clouds #{commands[cmd_thr]["cloud"]} --types #{commands[cmd_thr]["types"].join(" ")} 2>&1"
171
+ if !execCommand(adopt, results[cmd_thr])
172
+ results[cmd_thr]["failed"] << "adopt"
173
+ end
174
+ end
175
+
176
+ if File.exist?(dir+"/regrooms/"+commands[cmd_thr]["file"])
177
+ regroom = "mu-deploy regrooms/#{commands[cmd_thr]["file"]} --cloud #{commands[cmd_thr]["cloud"]} --update #{deploy_id} 2>&1"
178
+ if !execCommand(regroom, results[cmd_thr])
179
+ results[cmd_thr]["failed"] << "regroom"
180
+ end
181
+ if commands[cmd_thr]["types"] and commands[cmd_thr]["types"].size > 0
182
+ re_adopt = "cd #{adoptdir} && mu-adopt --appname adopttwo --grouping omnibus --clouds #{commands[cmd_thr]["cloud"]} --types #{commands[cmd_thr]["types"].join(" ")} 2>&1"
183
+ if !execCommand(re_adopt, results[cmd_thr])
184
+ results[cmd_thr]["failed"] << "second adopt"
185
+ end
186
+ end
187
+ # TODO big flex is to read back both adopted BoKs and .diff them, but without
188
+ # all resources having implemented adoption this isn't much of a test yet
189
+ end
190
+
191
+ FileUtils.remove_entry(adoptdir)
192
+ cleanup = %Q{mu-cleanup #{deploy_id} --skipsnapshots}
193
+ if !execCommand(cleanup, results[cmd_thr])
194
+ results[cmd_thr]["failed"] << "cleanup"
90
195
  end
91
196
  end
92
197
  }
@@ -96,21 +201,14 @@ threads.each { |t|
96
201
  }
97
202
  puts ""
98
203
 
99
- failures = []
100
204
  results.keys.sort { |a, b|
101
- if results[b]["status"] and !results[a]["status"]
102
- 1
103
- elsif !results[b]["status"] and results[a]["status"]
104
- -1
105
- else
106
- 0
107
- end
205
+ results[b]["failed"].size <=> results[a]["failed"].size
108
206
  }.each { |cmd|
109
- if !results[cmd]["status"]
207
+ if results[cmd]["failed"].size > 0
110
208
  puts cmd+" failed:".light_red
111
209
  puts results[cmd]["output"].yellow
112
210
  puts "^ #{cmd}".light_red
113
- failures << commands[cmd]["file"]+" ("+commands[cmd]["cloud"]+")"
211
+ failures << commands[cmd]["file"]+" in "+commands[cmd]["cloud"]+" ("+results[cmd]["failed"].join(", ")+")"
114
212
  else
115
213
  puts cmd+" passed".green
116
214
  end
@@ -17,8 +17,8 @@ end
17
17
 
18
18
  Gem::Specification.new do |s|
19
19
  s.name = 'cloud-mu'
20
- s.version = '3.1.2'
21
- s.date = '2020-01-27'
20
+ s.version = '3.2.0'
21
+ s.date = '2020-06-16'
22
22
  s.require_paths = ['modules']
23
23
  s.required_ruby_version = '>= 2.4'
24
24
  s.summary = "The eGTLabs Mu toolkit for unified cloud deployments"
@@ -35,31 +35,33 @@ EOF
35
35
  s.homepage =
36
36
  'https://github.com/cloudamatic/mu'
37
37
  s.license = 'BSD-3-Clause-Attribution'
38
- s.add_runtime_dependency 'erubis', "~> 2.7"
39
- s.add_runtime_dependency 'inifile', "~> 3.0"
40
- s.add_runtime_dependency 'bundler', "~> 1.17"
41
- s.add_runtime_dependency 'yard', "~> 0.9"
42
- s.add_runtime_dependency 'ruby-graphviz', "~> 1.2"
38
+ s.add_runtime_dependency 'addressable', '~> 2.5'
43
39
  s.add_runtime_dependency "aws-sdk-core", "< 3"
40
+ s.add_runtime_dependency 'azure_sdk', "~> 0.52"
41
+ s.add_runtime_dependency 'bundler', "~> 1.17"
44
42
  s.add_runtime_dependency 'chronic_duration', "~> 0.10"
45
- s.add_runtime_dependency 'simple-password-gen', "~> 0.1"
46
- s.add_runtime_dependency 'optimist', "~> 3.0"
47
- s.add_runtime_dependency 'json-schema', "~> 2.8"
48
- s.add_runtime_dependency 'colorize', "~> 0.8"
49
43
  s.add_runtime_dependency 'color', "~> 1.8"
50
- s.add_runtime_dependency 'netaddr', '~> 2.0'
51
- s.add_runtime_dependency 'nokogiri', "~> 1.10"
52
- s.add_runtime_dependency 'solve', '~> 4.0'
44
+ s.add_runtime_dependency 'colorize', "~> 0.8"
45
+ s.add_runtime_dependency 'erubis', "~> 2.7"
46
+ s.add_runtime_dependency 'google-api-client', "~> 0.36.4"
47
+ s.add_runtime_dependency 'googleauth', "~> 0.6"
48
+ s.add_runtime_dependency 'inifile', "~> 3.0"
49
+ s.add_runtime_dependency 'json-schema', "~> 2.8"
53
50
  s.add_runtime_dependency 'net-ldap', "~> 0.16"
54
51
  s.add_runtime_dependency 'net-ssh', "~> 4.2"
55
52
  s.add_runtime_dependency 'net-ssh-multi', '~> 1.2', '>= 1.2.1'
56
- s.add_runtime_dependency 'googleauth', "~> 0.6"
57
- s.add_runtime_dependency 'google-api-client', "~> 0.36.4"
53
+ s.add_runtime_dependency 'netaddr', '~> 2.0'
54
+ s.add_runtime_dependency 'nokogiri', "~> 1.10"
55
+ s.add_runtime_dependency 'openssl-oaep', "~> 0.1"
56
+ s.add_runtime_dependency 'optimist', "~> 3.0"
57
+ s.add_runtime_dependency 'rack', "~> 2.0"
58
+ s.add_runtime_dependency 'ruby-graphviz', "~> 1.2"
58
59
  s.add_runtime_dependency 'rubocop', '~> 0.58'
59
- s.add_runtime_dependency 'addressable', '~> 2.5'
60
+ s.add_runtime_dependency 'rubyzip', "~> 2.0"
61
+ s.add_runtime_dependency 'simple-password-gen', "~> 0.1"
60
62
  s.add_runtime_dependency 'slack-notifier', "~> 2.3"
61
- s.add_runtime_dependency 'azure_sdk', "~> 0.37"
62
- s.add_runtime_dependency 'rack', "~> 2.0"
63
+ s.add_runtime_dependency 'solve', '~> 4.0'
63
64
  s.add_runtime_dependency 'thin', "~> 1.7"
64
- s.add_runtime_dependency 'rubyzip', "~> 2.0"
65
+ s.add_runtime_dependency 'winrm', "~> 2.3", ">= 2.3.4"
66
+ s.add_runtime_dependency 'yard', "~> 0.9"
65
67
  end