cloud-mu 3.1.2 → 3.2.0

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 (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