cloud-mu 2.1.0beta → 3.0.0beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (291) hide show
  1. checksums.yaml +5 -5
  2. data/Berksfile +4 -5
  3. data/Berksfile.lock +179 -0
  4. data/README.md +1 -6
  5. data/ansible/roles/geerlingguy.firewall/templates/firewall.bash.j2 +0 -0
  6. data/ansible/roles/mu-installer/README.md +33 -0
  7. data/ansible/roles/mu-installer/defaults/main.yml +2 -0
  8. data/ansible/roles/mu-installer/handlers/main.yml +2 -0
  9. data/ansible/roles/mu-installer/meta/main.yml +60 -0
  10. data/ansible/roles/mu-installer/tasks/main.yml +13 -0
  11. data/ansible/roles/mu-installer/tests/inventory +2 -0
  12. data/ansible/roles/mu-installer/tests/test.yml +5 -0
  13. data/ansible/roles/mu-installer/vars/main.yml +2 -0
  14. data/bin/mu-adopt +125 -0
  15. data/bin/mu-aws-setup +4 -4
  16. data/bin/mu-azure-setup +265 -0
  17. data/bin/mu-azure-tests +43 -0
  18. data/bin/mu-cleanup +20 -8
  19. data/bin/mu-configure +224 -98
  20. data/bin/mu-deploy +8 -3
  21. data/bin/mu-gcp-setup +16 -8
  22. data/bin/mu-gen-docs +92 -8
  23. data/bin/mu-load-config.rb +52 -12
  24. data/bin/mu-momma-cat +36 -0
  25. data/bin/mu-node-manage +34 -27
  26. data/bin/mu-self-update +2 -2
  27. data/bin/mu-ssh +12 -8
  28. data/bin/mu-upload-chef-artifacts +11 -4
  29. data/bin/mu-user-manage +3 -0
  30. data/cloud-mu.gemspec +8 -11
  31. data/cookbooks/firewall/libraries/helpers_iptables.rb +2 -2
  32. data/cookbooks/firewall/metadata.json +1 -1
  33. data/cookbooks/firewall/recipes/default.rb +5 -9
  34. data/cookbooks/mu-firewall/attributes/default.rb +2 -0
  35. data/cookbooks/mu-firewall/metadata.rb +1 -1
  36. data/cookbooks/mu-glusterfs/templates/default/mu-gluster-client.erb +0 -0
  37. data/cookbooks/mu-master/Berksfile +2 -2
  38. data/cookbooks/mu-master/files/default/check_mem.pl +0 -0
  39. data/cookbooks/mu-master/files/default/cloudamatic.png +0 -0
  40. data/cookbooks/mu-master/metadata.rb +5 -4
  41. data/cookbooks/mu-master/recipes/389ds.rb +1 -1
  42. data/cookbooks/mu-master/recipes/basepackages.rb +30 -10
  43. data/cookbooks/mu-master/recipes/default.rb +59 -7
  44. data/cookbooks/mu-master/recipes/firewall-holes.rb +1 -1
  45. data/cookbooks/mu-master/recipes/init.rb +65 -47
  46. data/cookbooks/mu-master/recipes/{eks-kubectl.rb → kubectl.rb} +4 -10
  47. data/cookbooks/mu-master/recipes/sssd.rb +2 -1
  48. data/cookbooks/mu-master/recipes/update_nagios_only.rb +6 -6
  49. data/cookbooks/mu-master/templates/default/web_app.conf.erb +2 -2
  50. data/cookbooks/mu-master/templates/mods/ldap.conf.erb +4 -0
  51. data/cookbooks/mu-php54/Berksfile +1 -2
  52. data/cookbooks/mu-php54/metadata.rb +4 -5
  53. data/cookbooks/mu-php54/recipes/default.rb +1 -1
  54. data/cookbooks/mu-splunk/templates/default/splunk-init.erb +0 -0
  55. data/cookbooks/mu-tools/Berksfile +3 -2
  56. data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
  57. data/cookbooks/mu-tools/libraries/helper.rb +20 -8
  58. data/cookbooks/mu-tools/metadata.rb +5 -2
  59. data/cookbooks/mu-tools/recipes/apply_security.rb +2 -3
  60. data/cookbooks/mu-tools/recipes/eks.rb +1 -1
  61. data/cookbooks/mu-tools/recipes/gcloud.rb +5 -30
  62. data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
  63. data/cookbooks/mu-tools/recipes/rsyslog.rb +1 -0
  64. data/cookbooks/mu-tools/recipes/selinux.rb +19 -0
  65. data/cookbooks/mu-tools/recipes/split_var_partitions.rb +0 -1
  66. data/cookbooks/mu-tools/recipes/windows-client.rb +256 -122
  67. data/cookbooks/mu-tools/resources/disk.rb +3 -1
  68. data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +1 -1
  69. data/cookbooks/mu-tools/templates/default/etc_hosts.erb +1 -1
  70. data/cookbooks/mu-tools/templates/default/{kubeconfig.erb → kubeconfig-eks.erb} +0 -0
  71. data/cookbooks/mu-tools/templates/default/kubeconfig-gke.erb +27 -0
  72. data/cookbooks/mu-tools/templates/windows-10/sshd_config.erb +137 -0
  73. data/cookbooks/mu-utility/recipes/nat.rb +4 -0
  74. data/extras/alpha.png +0 -0
  75. data/extras/beta.png +0 -0
  76. data/extras/clean-stock-amis +2 -2
  77. data/extras/generate-stock-images +131 -0
  78. data/extras/git-fix-permissions-hook +0 -0
  79. data/extras/image-generators/AWS/centos6.yaml +17 -0
  80. data/extras/image-generators/{aws → AWS}/centos7-govcloud.yaml +0 -0
  81. data/extras/image-generators/{aws → AWS}/centos7.yaml +0 -0
  82. data/extras/image-generators/{aws → AWS}/rhel7.yaml +0 -0
  83. data/extras/image-generators/{aws → AWS}/win2k12.yaml +0 -0
  84. data/extras/image-generators/{aws → AWS}/win2k16.yaml +0 -0
  85. data/extras/image-generators/{aws → AWS}/windows.yaml +0 -0
  86. data/extras/image-generators/{gcp → Google}/centos6.yaml +1 -0
  87. data/extras/image-generators/Google/centos7.yaml +18 -0
  88. data/extras/python_rpm/build.sh +0 -0
  89. data/extras/release.png +0 -0
  90. data/extras/ruby_rpm/build.sh +0 -0
  91. data/extras/ruby_rpm/muby.spec +1 -1
  92. data/install/README.md +43 -5
  93. data/install/deprecated-bash-library.sh +0 -0
  94. data/install/installer +1 -1
  95. data/install/jenkinskeys.rb +0 -0
  96. data/install/mu-master.yaml +55 -0
  97. data/modules/mommacat.ru +41 -7
  98. data/modules/mu.rb +444 -149
  99. data/modules/mu/adoption.rb +500 -0
  100. data/modules/mu/cleanup.rb +235 -158
  101. data/modules/mu/cloud.rb +675 -138
  102. data/modules/mu/clouds/aws.rb +156 -24
  103. data/modules/mu/clouds/aws/alarm.rb +4 -14
  104. data/modules/mu/clouds/aws/bucket.rb +60 -18
  105. data/modules/mu/clouds/aws/cache_cluster.rb +8 -20
  106. data/modules/mu/clouds/aws/collection.rb +12 -22
  107. data/modules/mu/clouds/aws/container_cluster.rb +209 -118
  108. data/modules/mu/clouds/aws/database.rb +120 -45
  109. data/modules/mu/clouds/aws/dnszone.rb +7 -18
  110. data/modules/mu/clouds/aws/endpoint.rb +5 -15
  111. data/modules/mu/clouds/aws/firewall_rule.rb +144 -72
  112. data/modules/mu/clouds/aws/folder.rb +4 -11
  113. data/modules/mu/clouds/aws/function.rb +6 -16
  114. data/modules/mu/clouds/aws/group.rb +4 -12
  115. data/modules/mu/clouds/aws/habitat.rb +11 -13
  116. data/modules/mu/clouds/aws/loadbalancer.rb +40 -28
  117. data/modules/mu/clouds/aws/log.rb +5 -13
  118. data/modules/mu/clouds/aws/msg_queue.rb +9 -24
  119. data/modules/mu/clouds/aws/nosqldb.rb +4 -12
  120. data/modules/mu/clouds/aws/notifier.rb +6 -13
  121. data/modules/mu/clouds/aws/role.rb +69 -40
  122. data/modules/mu/clouds/aws/search_domain.rb +17 -20
  123. data/modules/mu/clouds/aws/server.rb +184 -94
  124. data/modules/mu/clouds/aws/server_pool.rb +33 -38
  125. data/modules/mu/clouds/aws/storage_pool.rb +5 -12
  126. data/modules/mu/clouds/aws/user.rb +59 -33
  127. data/modules/mu/clouds/aws/userdata/linux.erb +18 -30
  128. data/modules/mu/clouds/aws/userdata/windows.erb +9 -9
  129. data/modules/mu/clouds/aws/vpc.rb +214 -145
  130. data/modules/mu/clouds/azure.rb +978 -44
  131. data/modules/mu/clouds/azure/container_cluster.rb +413 -0
  132. data/modules/mu/clouds/azure/firewall_rule.rb +500 -0
  133. data/modules/mu/clouds/azure/habitat.rb +167 -0
  134. data/modules/mu/clouds/azure/loadbalancer.rb +205 -0
  135. data/modules/mu/clouds/azure/role.rb +211 -0
  136. data/modules/mu/clouds/azure/server.rb +810 -0
  137. data/modules/mu/clouds/azure/user.rb +257 -0
  138. data/modules/mu/clouds/azure/userdata/README.md +4 -0
  139. data/modules/mu/clouds/azure/userdata/linux.erb +137 -0
  140. data/modules/mu/clouds/azure/userdata/windows.erb +275 -0
  141. data/modules/mu/clouds/azure/vpc.rb +782 -0
  142. data/modules/mu/clouds/cloudformation.rb +12 -9
  143. data/modules/mu/clouds/cloudformation/firewall_rule.rb +5 -13
  144. data/modules/mu/clouds/cloudformation/server.rb +10 -1
  145. data/modules/mu/clouds/cloudformation/server_pool.rb +1 -0
  146. data/modules/mu/clouds/cloudformation/vpc.rb +0 -2
  147. data/modules/mu/clouds/google.rb +554 -117
  148. data/modules/mu/clouds/google/bucket.rb +173 -32
  149. data/modules/mu/clouds/google/container_cluster.rb +1112 -157
  150. data/modules/mu/clouds/google/database.rb +24 -47
  151. data/modules/mu/clouds/google/firewall_rule.rb +344 -89
  152. data/modules/mu/clouds/google/folder.rb +156 -79
  153. data/modules/mu/clouds/google/group.rb +272 -82
  154. data/modules/mu/clouds/google/habitat.rb +177 -52
  155. data/modules/mu/clouds/google/loadbalancer.rb +9 -34
  156. data/modules/mu/clouds/google/role.rb +1211 -0
  157. data/modules/mu/clouds/google/server.rb +491 -227
  158. data/modules/mu/clouds/google/server_pool.rb +233 -48
  159. data/modules/mu/clouds/google/user.rb +479 -125
  160. data/modules/mu/clouds/google/userdata/linux.erb +3 -3
  161. data/modules/mu/clouds/google/userdata/windows.erb +9 -9
  162. data/modules/mu/clouds/google/vpc.rb +381 -223
  163. data/modules/mu/config.rb +689 -214
  164. data/modules/mu/config/bucket.rb +1 -1
  165. data/modules/mu/config/cache_cluster.rb +1 -1
  166. data/modules/mu/config/cache_cluster.yml +0 -4
  167. data/modules/mu/config/container_cluster.rb +18 -9
  168. data/modules/mu/config/database.rb +6 -23
  169. data/modules/mu/config/firewall_rule.rb +9 -15
  170. data/modules/mu/config/folder.rb +22 -21
  171. data/modules/mu/config/habitat.rb +22 -21
  172. data/modules/mu/config/loadbalancer.rb +2 -2
  173. data/modules/mu/config/role.rb +9 -40
  174. data/modules/mu/config/server.rb +26 -5
  175. data/modules/mu/config/server_pool.rb +1 -1
  176. data/modules/mu/config/storage_pool.rb +2 -2
  177. data/modules/mu/config/user.rb +4 -0
  178. data/modules/mu/config/vpc.rb +350 -110
  179. data/modules/mu/defaults/{amazon_images.yaml → AWS.yaml} +37 -39
  180. data/modules/mu/defaults/Azure.yaml +17 -0
  181. data/modules/mu/defaults/Google.yaml +24 -0
  182. data/modules/mu/defaults/README.md +1 -1
  183. data/modules/mu/deploy.rb +168 -125
  184. data/modules/mu/groomer.rb +2 -1
  185. data/modules/mu/groomers/ansible.rb +104 -32
  186. data/modules/mu/groomers/chef.rb +96 -44
  187. data/modules/mu/kittens.rb +20602 -0
  188. data/modules/mu/logger.rb +38 -11
  189. data/modules/mu/master.rb +90 -8
  190. data/modules/mu/master/chef.rb +2 -3
  191. data/modules/mu/master/ldap.rb +0 -1
  192. data/modules/mu/master/ssl.rb +250 -0
  193. data/modules/mu/mommacat.rb +917 -513
  194. data/modules/scratchpad.erb +1 -1
  195. data/modules/tests/super_complex_bok.yml +0 -0
  196. data/modules/tests/super_simple_bok.yml +0 -0
  197. data/roles/mu-master.json +2 -1
  198. data/spec/azure_creds +5 -0
  199. data/spec/mu.yaml +56 -0
  200. data/spec/mu/clouds/azure_spec.rb +164 -27
  201. data/spec/spec_helper.rb +5 -0
  202. data/test/clean_up.py +0 -0
  203. data/test/exec_inspec.py +0 -0
  204. data/test/exec_mu_install.py +0 -0
  205. data/test/exec_retry.py +0 -0
  206. data/test/smoke_test.rb +0 -0
  207. metadata +90 -118
  208. data/cookbooks/mu-jenkins/Berksfile +0 -14
  209. data/cookbooks/mu-jenkins/CHANGELOG.md +0 -13
  210. data/cookbooks/mu-jenkins/LICENSE +0 -37
  211. data/cookbooks/mu-jenkins/README.md +0 -105
  212. data/cookbooks/mu-jenkins/attributes/default.rb +0 -42
  213. data/cookbooks/mu-jenkins/files/default/cleanup_deploy_config.xml +0 -73
  214. data/cookbooks/mu-jenkins/files/default/deploy_config.xml +0 -44
  215. data/cookbooks/mu-jenkins/metadata.rb +0 -21
  216. data/cookbooks/mu-jenkins/recipes/default.rb +0 -195
  217. data/cookbooks/mu-jenkins/recipes/node-ssh-config.rb +0 -54
  218. data/cookbooks/mu-jenkins/recipes/public_key.rb +0 -24
  219. data/cookbooks/mu-jenkins/templates/default/example_job.config.xml.erb +0 -24
  220. data/cookbooks/mu-jenkins/templates/default/org.jvnet.hudson.plugins.SSHBuildWrapper.xml.erb +0 -14
  221. data/cookbooks/mu-jenkins/templates/default/ssh_config.erb +0 -6
  222. data/cookbooks/nagios/Berksfile +0 -11
  223. data/cookbooks/nagios/CHANGELOG.md +0 -589
  224. data/cookbooks/nagios/CONTRIBUTING.md +0 -11
  225. data/cookbooks/nagios/LICENSE +0 -37
  226. data/cookbooks/nagios/README.md +0 -328
  227. data/cookbooks/nagios/TESTING.md +0 -2
  228. data/cookbooks/nagios/attributes/config.rb +0 -171
  229. data/cookbooks/nagios/attributes/default.rb +0 -228
  230. data/cookbooks/nagios/chefignore +0 -102
  231. data/cookbooks/nagios/definitions/command.rb +0 -33
  232. data/cookbooks/nagios/definitions/contact.rb +0 -33
  233. data/cookbooks/nagios/definitions/contactgroup.rb +0 -33
  234. data/cookbooks/nagios/definitions/host.rb +0 -33
  235. data/cookbooks/nagios/definitions/hostdependency.rb +0 -33
  236. data/cookbooks/nagios/definitions/hostescalation.rb +0 -34
  237. data/cookbooks/nagios/definitions/hostgroup.rb +0 -33
  238. data/cookbooks/nagios/definitions/nagios_conf.rb +0 -38
  239. data/cookbooks/nagios/definitions/resource.rb +0 -33
  240. data/cookbooks/nagios/definitions/service.rb +0 -33
  241. data/cookbooks/nagios/definitions/servicedependency.rb +0 -33
  242. data/cookbooks/nagios/definitions/serviceescalation.rb +0 -34
  243. data/cookbooks/nagios/definitions/servicegroup.rb +0 -33
  244. data/cookbooks/nagios/definitions/timeperiod.rb +0 -33
  245. data/cookbooks/nagios/libraries/base.rb +0 -314
  246. data/cookbooks/nagios/libraries/command.rb +0 -91
  247. data/cookbooks/nagios/libraries/contact.rb +0 -230
  248. data/cookbooks/nagios/libraries/contactgroup.rb +0 -112
  249. data/cookbooks/nagios/libraries/custom_option.rb +0 -36
  250. data/cookbooks/nagios/libraries/data_bag_helper.rb +0 -23
  251. data/cookbooks/nagios/libraries/default.rb +0 -90
  252. data/cookbooks/nagios/libraries/host.rb +0 -412
  253. data/cookbooks/nagios/libraries/hostdependency.rb +0 -181
  254. data/cookbooks/nagios/libraries/hostescalation.rb +0 -173
  255. data/cookbooks/nagios/libraries/hostgroup.rb +0 -119
  256. data/cookbooks/nagios/libraries/nagios.rb +0 -282
  257. data/cookbooks/nagios/libraries/resource.rb +0 -59
  258. data/cookbooks/nagios/libraries/service.rb +0 -455
  259. data/cookbooks/nagios/libraries/servicedependency.rb +0 -215
  260. data/cookbooks/nagios/libraries/serviceescalation.rb +0 -195
  261. data/cookbooks/nagios/libraries/servicegroup.rb +0 -144
  262. data/cookbooks/nagios/libraries/timeperiod.rb +0 -160
  263. data/cookbooks/nagios/libraries/users_helper.rb +0 -54
  264. data/cookbooks/nagios/metadata.rb +0 -25
  265. data/cookbooks/nagios/recipes/_load_databag_config.rb +0 -153
  266. data/cookbooks/nagios/recipes/_load_default_config.rb +0 -241
  267. data/cookbooks/nagios/recipes/apache.rb +0 -48
  268. data/cookbooks/nagios/recipes/default.rb +0 -204
  269. data/cookbooks/nagios/recipes/nginx.rb +0 -82
  270. data/cookbooks/nagios/recipes/pagerduty.rb +0 -143
  271. data/cookbooks/nagios/recipes/server_package.rb +0 -40
  272. data/cookbooks/nagios/recipes/server_source.rb +0 -164
  273. data/cookbooks/nagios/templates/default/apache2.conf.erb +0 -96
  274. data/cookbooks/nagios/templates/default/cgi.cfg.erb +0 -266
  275. data/cookbooks/nagios/templates/default/commands.cfg.erb +0 -13
  276. data/cookbooks/nagios/templates/default/contacts.cfg.erb +0 -37
  277. data/cookbooks/nagios/templates/default/hostgroups.cfg.erb +0 -25
  278. data/cookbooks/nagios/templates/default/hosts.cfg.erb +0 -15
  279. data/cookbooks/nagios/templates/default/htpasswd.users.erb +0 -6
  280. data/cookbooks/nagios/templates/default/nagios.cfg.erb +0 -22
  281. data/cookbooks/nagios/templates/default/nginx.conf.erb +0 -62
  282. data/cookbooks/nagios/templates/default/pagerduty.cgi.erb +0 -185
  283. data/cookbooks/nagios/templates/default/resource.cfg.erb +0 -27
  284. data/cookbooks/nagios/templates/default/servicedependencies.cfg.erb +0 -15
  285. data/cookbooks/nagios/templates/default/servicegroups.cfg.erb +0 -14
  286. data/cookbooks/nagios/templates/default/services.cfg.erb +0 -14
  287. data/cookbooks/nagios/templates/default/templates.cfg.erb +0 -31
  288. data/cookbooks/nagios/templates/default/timeperiods.cfg.erb +0 -13
  289. data/extras/image-generators/aws/centos6.yaml +0 -18
  290. data/modules/mu/defaults/google_images.yaml +0 -16
  291. data/roles/mu-master-jenkins.json +0 -24
@@ -18,7 +18,7 @@ module MU
18
18
  class Groomer
19
19
 
20
20
  # An exception denoting a Groomer run that has failed
21
- class RunError < MuError
21
+ class RunError < StandardError
22
22
  end
23
23
 
24
24
  # An exception denoting nonexistent secret
@@ -49,6 +49,7 @@ module MU
49
49
  # @param groomer [String]: The grooming agent to load.
50
50
  # @return [Class]: The class object implementing this groomer agent
51
51
  def self.loadGroomer(groomer)
52
+ return nil if !groomer
52
53
  if !File.size?(MU.myRoot+"/modules/mu/groomers/#{groomer.downcase}.rb")
53
54
  raise MuError, "Requested to use unsupported grooming agent #{groomer}"
54
55
  end
@@ -20,11 +20,17 @@ module MU
20
20
  # Support for Ansible as a host configuration management layer.
21
21
  class Ansible
22
22
 
23
+ # Failure to load or create a deploy
24
+ class NoAnsibleExecError < MuError;
25
+ end
23
26
 
24
- # Location in which we'll find our Ansible executables
27
+ # Location in which we'll find our Ansible executables. This only applies
28
+ # to full-grown Mu masters; minimalist gem installs will have to make do
29
+ # with whatever Ansible executables they can find in $PATH.
25
30
  BINDIR = "/usr/local/python-current/bin"
26
31
  @@pwfile_semaphore = Mutex.new
27
32
 
33
+
28
34
  # @param node [MU::Cloud::Server]: The server object on which we'll be operating
29
35
  def initialize(node)
30
36
  @config = node.config
@@ -32,9 +38,14 @@ module MU
32
38
  @inventory = Inventory.new(node.deploy)
33
39
  @mu_user = node.deploy.mu_user
34
40
  @ansible_path = node.deploy.deploy_dir+"/ansible"
41
+ @ansible_execs = MU::Groomer::Ansible.ansibleExecDir
42
+
43
+ if !@ansible_execs or @ansible_execs.empty?
44
+ raise NoAnsibleExecError, "No Ansible executables found in visible paths"
45
+ end
35
46
 
36
47
  [@ansible_path, @ansible_path+"/roles", @ansible_path+"/vars", @ansible_path+"/group_vars", @ansible_path+"/vaults"].each { |dir|
37
- if !Dir.exists?(dir)
48
+ if !Dir.exist?(dir)
38
49
  MU.log "Creating #{dir}", MU::DEBUG
39
50
  Dir.mkdir(dir, 0755)
40
51
  end
@@ -77,19 +88,20 @@ module MU
77
88
  end
78
89
  path = dir+"/"+item
79
90
 
80
- if !Dir.exists?(dir)
91
+ if !Dir.exist?(dir)
81
92
  FileUtils.mkdir_p(dir, mode: 0700)
82
93
  end
83
94
 
84
- if File.exists?(path)
95
+ if File.exist?(path)
85
96
  MU.log "Overwriting existing vault #{vault} item #{item}"
86
97
  end
87
98
  File.open(path, File::CREAT|File::RDWR|File::TRUNC, 0600) { |f|
88
99
  f.write data
89
100
  }
90
- cmd = %Q{#{BINDIR}/ansible-vault encrypt #{path} --vault-id #{pwfile}}
101
+
102
+ cmd = %Q{#{ansibleExecDir}/ansible-vault encrypt #{path} --vault-password-file #{pwfile}}
91
103
  MU.log cmd
92
- system(cmd)
104
+ raise MuError, "Failed Ansible command: #{cmd}" if !system(cmd)
93
105
  end
94
106
 
95
107
  # see {MU::Groomer::Ansible.saveSecret}
@@ -110,17 +122,17 @@ module MU
110
122
 
111
123
  pwfile = vaultPasswordFile
112
124
  dir = secret_dir+"/"+vault
113
- if !Dir.exists?(dir)
125
+ if !Dir.exist?(dir)
114
126
  raise MuNoSuchSecret, "No such vault #{vault}"
115
127
  end
116
128
 
117
129
  data = nil
118
130
  if item
119
131
  itempath = dir+"/"+item
120
- if !File.exists?(itempath)
132
+ if !File.exist?(itempath)
121
133
  raise MuNoSuchSecret, "No such item #{item} in vault #{vault}"
122
134
  end
123
- cmd = %Q{#{BINDIR}/ansible-vault view #{itempath} --vault-id #{pwfile}}
135
+ cmd = %Q{#{ansibleExecDir}/ansible-vault view #{itempath} --vault-password-file #{pwfile}}
124
136
  MU.log cmd
125
137
  a = `#{cmd}`
126
138
  # If we happen to have stored recognizeable JSON, return it as parsed,
@@ -158,14 +170,14 @@ module MU
158
170
  raise MuError, "Must call deleteSecret with at least a vault name"
159
171
  end
160
172
  dir = secret_dir+"/"+vault
161
- if !Dir.exists?(dir)
173
+ if !Dir.exist?(dir)
162
174
  raise MuNoSuchSecret, "No such vault #{vault}"
163
175
  end
164
176
 
165
177
  data = nil
166
178
  if item
167
179
  itempath = dir+"/"+item
168
- if !File.exists?(itempath)
180
+ if !File.exist?(itempath)
169
181
  raise MuNoSuchSecret, "No such item #{item} in vault #{vault}"
170
182
  end
171
183
  MU.log "Deleting Ansible vault #{vault} item #{item}", MU::NOTICE
@@ -189,13 +201,28 @@ module MU
189
201
  # @param output [Boolean]: Display Ansible's regular (non-error) output to the console
190
202
  # @param override_runlist [String]: Use the specified run list instead of the node's configured list
191
203
  def run(purpose: "Ansible run", update_runlist: true, max_retries: 5, output: true, override_runlist: nil, reboot_first_fail: false, timeout: 1800)
204
+ bootstrap
192
205
  pwfile = MU::Groomer::Ansible.vaultPasswordFile
193
206
  stashHostSSLCertSecret
194
207
 
195
- cmd = %Q{cd #{@ansible_path} && #{BINDIR}/ansible-playbook -i hosts #{@server.config['name']}.yml --limit=#{@server.mu_name} --vault-id #{pwfile} --vault-id #{@ansible_path}/.vault_pw}
208
+ ssh_user = @server.config['ssh_user'] || "root"
196
209
 
197
- MU.log cmd
198
- system(cmd)
210
+ cmd = %Q{cd #{@ansible_path} && #{@ansible_execs}/ansible-playbook -i hosts #{@server.config['name']}.yml --limit=#{@server.mu_name} --vault-password-file #{pwfile} --vault-password-file #{@ansible_path}/.vault_pw -u #{ssh_user}}
211
+
212
+ retries = 0
213
+ begin
214
+ MU.log cmd
215
+ raise MU::Groomer::RunError, "Failed Ansible command: #{cmd}" if !system(cmd)
216
+ rescue MU::Groomer::RunError => e
217
+ if retries < max_retries
218
+ sleep 30
219
+ retries += 1
220
+ MU.log "Failed Ansible run, will retry (#{retries.to_s}/#{max_retries.to_s})", MU::NOTICE, details: cmd
221
+ retry
222
+ else
223
+ raise MuError, "Failed Ansible command: #{cmd}"
224
+ end
225
+ end
199
226
  end
200
227
 
201
228
  # This is a stub; since Ansible is effectively agentless, this operation
@@ -224,6 +251,10 @@ module MU
224
251
  play["roles"] = @server.config['run_list']
225
252
  end
226
253
 
254
+ if @server.config['ansible_vars']
255
+ play["vars"] = @server.config['ansible_vars']
256
+ end
257
+
227
258
  File.open(@ansible_path+"/"+@server.config['name']+".yml", File::CREAT|File::RDWR|File::TRUNC, 0600) { |f|
228
259
  f.flock(File::LOCK_EX)
229
260
  f.puts [play].to_yaml
@@ -237,12 +268,13 @@ module MU
237
268
  @server.describe(update_cache: true) # Make sure we're fresh
238
269
 
239
270
  allvars = {
240
- "deployment" => @server.deploy.deployment,
241
- "service_name" => @config["name"],
242
- "windows_admin_username" => @config['windows_admin_username'],
243
- "mu_environment" => MU.environment.downcase,
271
+ "mu_deployment" => MU.structToHash(@server.deploy.deployment),
272
+ "mu_service_name" => @config["name"],
273
+ "mu_canonical_ip" => @server.canonicalIP,
274
+ "mu_admin_email" => $MU_CFG['mu_admin_email'],
275
+ "mu_environment" => MU.environment.downcase
244
276
  }
245
- allvars['deployment']['ssh_public_key'] = @server.deploy.ssh_public_key
277
+ allvars['mu_deployment']['ssh_public_key'] = @server.deploy.ssh_public_key
246
278
 
247
279
  if @server.config['cloud'] == "AWS"
248
280
  allvars["ec2"] = MU.structToHash(@server.cloud_desc, stringify_keys: true)
@@ -262,7 +294,7 @@ module MU
262
294
  f.flock(File::LOCK_UN)
263
295
  }
264
296
 
265
- groupvars = {}
297
+ groupvars = allvars.dup
266
298
  if @server.deploy.original_config.has_key?('parameters')
267
299
  groupvars["mu_parameters"] = @server.deploy.original_config['parameters']
268
300
  end
@@ -312,18 +344,41 @@ module MU
312
344
  # @param for_user [String]: Encrypt using the Vault password of the specified Mu user
313
345
  def self.encryptString(name, string, for_user = nil)
314
346
  pwfile = vaultPasswordFile
315
- cmd = %Q{#{BINDIR}/ansible-vault}
316
- system(cmd, "encrypt_string", string, "--name", name, "--vault-id", pwfile)
347
+ cmd = %Q{#{ansibleExecDir}/ansible-vault}
348
+ if !system(cmd, "encrypt_string", string, "--name", name, "--vault-password-file", pwfile)
349
+ raise MuError, "Failed Ansible command: #{cmd} encrypt_string <redacted> --name #{name} --vault-password-file"
350
+ end
317
351
  end
318
352
 
319
353
  private
320
354
 
355
+ def self.ansibleExecDir
356
+ path = nil
357
+ if File.exist?(BINDIR+"/ansible-playbook")
358
+ path = BINDIR
359
+ else
360
+ ENV['PATH'].split(/:/).each { |bindir|
361
+ if File.exist?(bindir+"/ansible-playbook")
362
+ path = bindir
363
+ if !File.exist?(bindir+"/ansible-vault")
364
+ MU.log "Found ansible-playbook executable in #{bindir}, but no ansible-vault. Vault functionality will not work!", MU::WARN
365
+ end
366
+ if !File.exist?(bindir+"/ansible-galaxy")
367
+ MU.log "Found ansible-playbook executable in #{bindir}, but no ansible-galaxy. Automatic community role fetch will not work!", MU::WARN
368
+ end
369
+ break
370
+ end
371
+ }
372
+ end
373
+ path
374
+ end
375
+
321
376
  # Get the +.vault_pw+ file for the appropriate user. If it doesn't exist,
322
377
  # generate one.
323
378
  def self.vaultPasswordFile(for_user = nil, pwfile: nil)
324
379
  pwfile ||= secret_dir(for_user)+"/.vault_pw"
325
380
  @@pwfile_semaphore.synchronize {
326
- if !File.exists?(pwfile)
381
+ if !File.exist?(pwfile)
327
382
  MU.log "Generating Ansible vault password file at #{pwfile}", MU::DEBUG
328
383
  File.open(pwfile, File::CREAT|File::RDWR|File::TRUNC, 0400) { |f|
329
384
  f.write Password.random(12..14)
@@ -341,7 +396,7 @@ module MU
341
396
  # Figure out where our main stash of secrets is, and make sure it exists
342
397
  def self.secret_dir(user = MU.mu_user)
343
398
  path = MU.dataDir(user) + "/ansible-secrets"
344
- Dir.mkdir(path, 0755) if !Dir.exists?(path)
399
+ Dir.mkdir(path, 0755) if !Dir.exist?(path)
345
400
 
346
401
  path
347
402
  end
@@ -350,6 +405,7 @@ module MU
350
405
  # artifacts, since 'roles' is an awfully generic name for a directory.
351
406
  # Short of a full, slow syntax check, this is the best we're liable to do.
352
407
  def isAnsibleRole?(path)
408
+ begin
353
409
  Dir.foreach(path) { |entry|
354
410
  if File.directory?(path+"/"+entry) and
355
411
  ["tasks", "vars"].include?(entry)
@@ -358,6 +414,8 @@ module MU
358
414
  return false
359
415
  end
360
416
  }
417
+ rescue Errno::ENOTDIR
418
+ end
361
419
  false
362
420
  end
363
421
 
@@ -368,20 +426,34 @@ module MU
368
426
 
369
427
  canon_links = {}
370
428
 
429
+ repodirs = []
430
+
431
+ # Make sure we search the global ansible_dir, if any is set
432
+ if $MU_CFG and $MU_CFG['ansible_dir'] and !$MU_CFG['ansible_dir'].empty?
433
+ if !Dir.exist?($MU_CFG['ansible_dir'])
434
+ MU.log "Config lists an Ansible directory at #{$MU_CFG['ansible_dir']}, but I see no such directory", MU::WARN
435
+ else
436
+ repodirs << $MU_CFG['ansible_dir']
437
+ end
438
+ end
439
+
371
440
  # Hook up any Ansible roles listed in our platform repos
372
441
  $MU_CFG['repos'].each { |repo|
373
442
  repo.match(/\/([^\/]+?)(\.git)?$/)
374
443
  shortname = Regexp.last_match(1)
375
- repodir = MU.dataDir + "/" + shortname
444
+ repodirs << MU.dataDir + "/" + shortname
445
+ }
446
+
447
+ repodirs.each { |repodir|
376
448
  ["roles", "ansible/roles"].each { |subdir|
377
- next if !Dir.exists?(repodir+"/"+subdir)
449
+ next if !Dir.exist?(repodir+"/"+subdir)
378
450
  Dir.foreach(repodir+"/"+subdir) { |role|
379
451
  next if [".", ".."].include?(role)
380
452
  realpath = repodir+"/"+subdir+"/"+role
381
453
  link = roledir+"/"+role
382
454
 
383
455
  if isAnsibleRole?(realpath)
384
- if !File.exists?(link)
456
+ if !File.exist?(link)
385
457
  File.symlink(realpath, link)
386
458
  canon_links[role] = realpath
387
459
  elsif File.symlink?(link)
@@ -402,16 +474,16 @@ module MU
402
474
  # Now layer on everything bundled in the main Mu repo
403
475
  Dir.foreach(MU.myRoot+"/ansible/roles") { |role|
404
476
  next if [".", ".."].include?(role)
405
- next if File.exists?(roledir+"/"+role)
477
+ next if File.exist?(roledir+"/"+role)
406
478
  File.symlink(MU.myRoot+"/ansible/roles/"+role, roledir+"/"+role)
407
479
  }
408
480
 
409
481
  if @server.config['run_list']
410
482
  @server.config['run_list'].each { |role|
411
483
  found = false
412
- if !File.exists?(roledir+"/"+role)
484
+ if !File.exist?(roledir+"/"+role)
413
485
  if role.match(/[^\.]\.[^\.]/) and @server.config['groomer_autofetch']
414
- system(%Q{#{BINDIR}/ansible-galaxy}, "--roles-path", roledir, "install", role)
486
+ system(%Q{#{@ansible_execs}/ansible-galaxy}, "--roles-path", roledir, "install", role)
415
487
  found = true
416
488
  # XXX check return value
417
489
  else
@@ -455,7 +527,7 @@ module MU
455
527
  def initialize(deploy)
456
528
  @deploy = deploy
457
529
  @ansible_path = @deploy.deploy_dir+"/ansible"
458
- if !Dir.exists?(@ansible_path)
530
+ if !Dir.exist?(@ansible_path)
459
531
  Dir.mkdir(@ansible_path, 0755)
460
532
  end
461
533
 
@@ -528,7 +600,7 @@ module MU
528
600
 
529
601
  def read
530
602
  @inv = {}
531
- if File.exists?(@ansible_path+"/hosts")
603
+ if File.exist?(@ansible_path+"/hosts")
532
604
  section = nil
533
605
  File.readlines(@ansible_path+"/hosts").each { |l|
534
606
  l.chomp!
@@ -71,7 +71,7 @@ module MU
71
71
  require 'chef/knife/bootstrap_windows_winrm'
72
72
  require 'chef/knife/bootstrap_windows_ssh'
73
73
  ::Chef::Config[:chef_server_url] = "https://#{MU.mu_public_addr}:7443/organizations/#{user}"
74
- if File.exists?("#{Etc.getpwnam(mu_user).dir}/.chef/knife.rb")
74
+ if File.exist?("#{Etc.getpwnam(mu_user).dir}/.chef/knife.rb")
75
75
  MU.log "Loading Chef configuration from #{Etc.getpwnam(mu_user).dir}/.chef/knife.rb", MU::DEBUG
76
76
  ::Chef::Config.from_file("#{Etc.getpwnam(mu_user).dir}/.chef/knife.rb")
77
77
  end
@@ -218,7 +218,7 @@ module MU
218
218
  loadChefLib
219
219
  raise MuError, "No vault specified, nothing to delete" if vault.nil?
220
220
  MU.log "Deleting #{vault}:#{item} from vaults"
221
- knife_db = nil
221
+
222
222
  knife_cmds = []
223
223
  if item.nil?
224
224
  knife_cmds << ::Chef::Knife::DataBagDelete.new(['data', 'bag', 'delete', vault])
@@ -270,7 +270,7 @@ module MU
270
270
 
271
271
  retries = 0
272
272
  try_upgrade = false
273
- output = []
273
+ output_lines = []
274
274
  error_signal = "CHEF EXITED BADLY: "+(0...25).map { ('a'..'z').to_a[rand(26)] }.join
275
275
  runstart = nil
276
276
  cmd = nil
@@ -294,9 +294,26 @@ module MU
294
294
  Timeout::timeout(timeout) {
295
295
  retval = ssh.exec!(cmd) { |ch, stream, data|
296
296
  puts data
297
- output << data
298
- raise MU::Cloud::BootstrapTempFail if data.match(/REBOOT_SCHEDULED| WARN: Reboot requested:/)
299
- raise MU::Groomer::RunError, output.grep(/ ERROR: /).last if data.match(/#{error_signal}/)
297
+ output_lines << data
298
+ raise MU::Cloud::BootstrapTempFail if data.match(/REBOOT_SCHEDULED| WARN: Reboot requested:|Rebooting server at a recipe's request|Chef::Exceptions::Reboot/)
299
+ if data.match(/#{error_signal}/)
300
+ error_msg = ""
301
+ clip = false
302
+ output_lines.each { |chunk|
303
+ chunk.split(/\n/).each { |line|
304
+ if !clip and line.match(/^========+/)
305
+ clip = true
306
+ elsif clip and line.match(/^Running handlers:/)
307
+ break
308
+ end
309
+
310
+ if clip and line.match(/[a-z0-9]/)
311
+ error_msg += line.gsub(/\e\[(\d+)m/, '')+"\n"
312
+ end
313
+ }
314
+ }
315
+ raise MU::Groomer::RunError, error_msg
316
+ end
300
317
  }
301
318
  }
302
319
  else
@@ -314,7 +331,7 @@ module MU
314
331
  if try_upgrade
315
332
  pp winrm.run("Invoke-WebRequest -useb https://omnitruck.chef.io/install.ps1 | Invoke-Expression; Install-Project -version:#{MU.chefVersion} -download_directory:$HOME")
316
333
  end
317
- output = []
334
+ output_lines = []
318
335
  cmd = "c:/opscode/chef/bin/chef-client.bat --color"
319
336
  if override_runlist
320
337
  cmd = cmd + " -o '#{override_runlist}'"
@@ -324,20 +341,20 @@ module MU
324
341
  resp = winrm.run(cmd) do |stdout, stderr|
325
342
  if stdout
326
343
  print stdout if output
327
- output << stdout
344
+ output_lines << stdout
328
345
  end
329
346
  if stderr
330
347
  MU.log stderr, MU::ERR
331
- output << stderr
348
+ output_lines << stderr
332
349
  end
333
350
  end
334
351
  }
335
352
 
336
- if resp.exitcode == 1 and output.join("\n").match(/Chef Client finished/)
353
+ if resp.exitcode == 1 and output_lines.join("\n").match(/Chef Client finished/)
337
354
  MU.log "resp.exit code 1"
338
355
  elsif resp.exitcode != 0
339
- raise MU::Cloud::BootstrapTempFail if resp.exitcode == 35 or output.join("\n").match(/REBOOT_SCHEDULED| WARN: Reboot requested:/)
340
- raise MU::Groomer::RunError, output.slice(output.length-50, output.length).join("")
356
+ raise MU::Cloud::BootstrapTempFail if resp.exitcode == 35 or output_lines.join("\n").match(/REBOOT_SCHEDULED| WARN: Reboot requested:|Rebooting server at a recipe's request|Chef::Exceptions::Reboot/)
357
+ raise MU::Groomer::RunError, output_lines.slice(output_lines.length-50, output_lines.length).join("")
341
358
  end
342
359
  end
343
360
  rescue MU::Cloud::BootstrapTempFail
@@ -397,10 +414,12 @@ module MU
397
414
  sleep 30
398
415
  retry
399
416
  else
417
+ @server.deploy.sendAdminSlack("Chef run '#{purpose}' failed on `#{@server.mu_name}` :crying_cat_face:", msg: e.message)
400
418
  raise MU::Groomer::RunError, "#{@server.mu_name}: Chef run '#{purpose}' failed #{max_retries} times, last error was: #{e.message}"
401
419
  end
402
420
  rescue Exception => e
403
- raise MU::Groomer::RunError, "Caught unexpected #{e.inspect} on #{@server.mu_name} in @groomer.run"
421
+ @server.deploy.sendAdminSlack("Chef run '#{purpose}' failed on `#{@server.mu_name}` :crying_cat_face:", msg: e.inspect)
422
+ raise MU::Groomer::RunError, "Caught unexpected #{e.inspect} on #{@server.mu_name} in @groomer.run at #{e.backtrace[0]}"
404
423
 
405
424
  end
406
425
 
@@ -440,20 +459,33 @@ module MU
440
459
  end
441
460
  guardfile = "/opt/mu_installed_chef"
442
461
 
443
- ssh = @server.getSSHSession(15)
444
- if leave_ours
445
- MU.log "Expunging pre-existing Chef install on #{@server.mu_name}, if we didn't create it", MU::NOTICE
446
- begin
447
- ssh.exec!(%Q{test -f #{guardfile} || (#{remove_cmd}) ; touch #{guardfile}})
448
- rescue IOError => e
449
- # TO DO - retry this in a cleaner way
450
- MU.log "Got #{e.inspect} while trying to clean up chef, retrying", MU::NOTICE, details: %Q{test -f #{guardfile} || (#{remove_cmd}) ; touch #{guardfile}}
451
- ssh = @server.getSSHSession(15)
452
- ssh.exec!(%Q{test -f #{guardfile} || (#{remove_cmd}) ; touch #{guardfile}})
462
+ retries = 0
463
+ begin
464
+ ssh = @server.getSSHSession(15)
465
+ Timeout::timeout(60) {
466
+ if leave_ours
467
+ MU.log "Expunging pre-existing Chef install on #{@server.mu_name}, if we didn't create it", MU::NOTICE
468
+ begin
469
+ ssh.exec!(%Q{test -f #{guardfile} || (#{remove_cmd}) ; touch #{guardfile}})
470
+ rescue IOError => e
471
+ # TO DO - retry this in a cleaner way
472
+ MU.log "Got #{e.inspect} while trying to clean up chef, retrying", MU::NOTICE, details: %Q{test -f #{guardfile} || (#{remove_cmd}) ; touch #{guardfile}}
473
+ ssh = @server.getSSHSession(15)
474
+ ssh.exec!(%Q{test -f #{guardfile} || (#{remove_cmd}) ; touch #{guardfile}})
475
+ end
476
+ else
477
+ MU.log "Expunging pre-existing Chef install on #{@server.mu_name}", MU::NOTICE
478
+ ssh.exec!(remove_cmd)
479
+ end
480
+ }
481
+ rescue Timeout::Error
482
+ if retries < 5
483
+ retries += 1
484
+ sleep 5
485
+ retry
486
+ else
487
+ raise MuError, "Failed to preClean #{@server.mu_name} after repeated timeouts"
453
488
  end
454
- else
455
- MU.log "Expunging pre-existing Chef install on #{@server.mu_name}", MU::NOTICE
456
- ssh.exec!(remove_cmd)
457
489
  end
458
490
 
459
491
  ssh.close
@@ -523,6 +555,7 @@ module MU
523
555
  def bootstrap
524
556
  self.class.loadChefLib
525
557
  stashHostSSLCertSecret
558
+ splunkVaultInit
526
559
  if !@config['cleaned_chef']
527
560
  begin
528
561
  leave_ours = @config['scrub_groomer'] ? false : true
@@ -654,8 +687,8 @@ retry
654
687
  end
655
688
  }
656
689
  knifeAddToRunList("role[mu-node]")
690
+ knifeAddToRunList("mu-tools::selinux")
657
691
 
658
- splunkVaultInit
659
692
  grantSecretAccess(@server.mu_name, "windows_credentials") if @server.windows?
660
693
  grantSecretAccess(@server.mu_name, "ssl_cert")
661
694
 
@@ -669,6 +702,7 @@ retry
669
702
  run(purpose: "Base configuration", update_runlist: false, max_retries: 20)
670
703
  end
671
704
  ::Chef::Knife.run(['node', 'run_list', 'remove', @server.mu_name, "recipe[mu-tools::updates]"], {}) if !@config['skipinitialupdates']
705
+ ::Chef::Knife.run(['node', 'run_list', 'remove', @server.mu_name, "recipe[mu-tools::selinux]"], {})
672
706
 
673
707
  # This will deal with Active Directory integration.
674
708
  if !@config['active_directory'].nil?
@@ -696,6 +730,11 @@ retry
696
730
  # @return [Hash]: The data synchronized.
697
731
  def saveDeployData
698
732
  self.class.loadChefLib
733
+ if !haveBootstrapped?
734
+ MU.log "saveDeployData invoked on #{@server.to_s} before Chef has been bootstrapped!", MU::WARN, details: caller
735
+ return
736
+ end
737
+
699
738
  @server.describe(update_cache: true) # Make sure we're fresh
700
739
  saveChefMetadata
701
740
  begin
@@ -724,10 +763,12 @@ retry
724
763
  }
725
764
  end
726
765
 
727
- if chef_node.normal['deployment'] != @server.deploy.deployment
766
+ if !@server.deploy.deployment.nil? and
767
+ (chef_node.normal['deployment'].nil? or
768
+ (chef_node.normal['deployment'].to_h <=> @server.deploy.deployment) != 0
769
+ )
728
770
  MU.log "Updating node: #{@server.mu_name} deployment attributes", details: @server.deploy.deployment
729
771
  chef_node.normal['deployment'].merge!(@server.deploy.deployment)
730
- chef_node.normal['deployment']['ssh_public_key'] = @server.deploy.ssh_public_key
731
772
  chef_node.save
732
773
  end
733
774
  return chef_node['deployment']
@@ -770,6 +811,15 @@ retry
770
811
  rescue Net::HTTPServerException
771
812
  end
772
813
  end
814
+ MU.log "knife data bag delete #{node}"
815
+ if !noop
816
+ knife_cd = ::Chef::Knife::ClientDelete.new(['data', 'bag', 'delete', node])
817
+ knife_cd.config[:yes] = true
818
+ begin
819
+ knife_cd.run
820
+ rescue Net::HTTPServerException
821
+ end
822
+ end
773
823
 
774
824
  return if nodeonly
775
825
 
@@ -778,7 +828,7 @@ retry
778
828
  rescue MuNoSuchSecret
779
829
  end
780
830
  ["crt", "key", "csr"].each { |ext|
781
- if File.exists?("#{MU.mySSLDir}/#{node}.#{ext}")
831
+ if File.exist?("#{MU.mySSLDir}/#{node}.#{ext}")
782
832
  MU.log "Removing #{MU.mySSLDir}/#{node}.#{ext}"
783
833
  File.unlink("#{MU.mySSLDir}/#{node}.#{ext}") if !noop
784
834
  end
@@ -812,6 +862,7 @@ retry
812
862
  begin
813
863
  chef_node = ::Chef::Node.load(@server.mu_name)
814
864
  rescue Net::HTTPServerException
865
+ @server.deploy.sendAdminSlack("Couldn't load Chef metadata on `#{@server.mu_name}` :crying_cat_face:")
815
866
  raise MU::Groomer::RunError, "Couldn't load Chef node #{@server.mu_name}"
816
867
  end
817
868
 
@@ -821,6 +872,7 @@ retry
821
872
 
822
873
  chef_node.normal.app = @config['application_cookbook'] if !@config['application_cookbook'].nil?
823
874
  chef_node.normal["service_name"] = @config["name"]
875
+ chef_node.normal["credentials"] = @config["credentials"]
824
876
  chef_node.normal["windows_admin_username"] = @config['windows_admin_username']
825
877
  chef_node.chef_environment = MU.environment.downcase
826
878
  if @server.config['cloud'] == "AWS"
@@ -965,9 +1017,9 @@ retry
965
1017
  if multiple.size == 0
966
1018
  multiple = [rl_entry]
967
1019
  end
968
- multiple.each { |rl_entry|
969
- if !rl_entry.match(/^role|recipe\[/)
970
- rl_entry = "#{type}[#{rl_entry}]"
1020
+ multiple.each { |entry|
1021
+ if !entry.match(/^role|recipe\[/)
1022
+ entry = "#{type}[#{entry}]"
971
1023
  end
972
1024
  }
973
1025
 
@@ -975,27 +1027,27 @@ retry
975
1027
  role_list = nil
976
1028
  recipe_list = nil
977
1029
  missing = false
978
- multiple.each { |rl_entry|
979
- # Rather than argue about whether to expect a bare rl_entry name or
980
- # require rl_entry[rolename], let's just accomodate.
981
- if rl_entry.match(/^role\[(.+?)\]/)
982
- rl_entry_name = Regexp.last_match(1)
1030
+ multiple.each { |entry|
1031
+ # Rather than argue about whether to expect a bare entry name or
1032
+ # require entry[rolename], let's just accomodate.
1033
+ if entry.match(/^role\[(.+?)\]/)
1034
+ entry_name = Regexp.last_match(1)
983
1035
  if role_list.nil?
984
1036
  query=%Q{#{MU::Groomer::Chef.knife} role list};
985
1037
  role_list = %x{#{query}}
986
1038
  end
987
- if !role_list.match(/(^|\n)#{rl_entry_name}($|\n)/)
988
- MU.log "Attempting to add non-existent #{rl_entry} to #{@server.mu_name}", MU::WARN
1039
+ if !role_list.match(/(^|\n)#{entry_name}($|\n)/)
1040
+ MU.log "Attempting to add non-existent #{entry} to #{@server.mu_name}", MU::WARN
989
1041
  missing = true
990
1042
  end
991
- elsif rl_entry.match(/^recipe\[(.+?)\]/)
992
- rl_entry_name = Regexp.last_match(1)
1043
+ elsif entry.match(/^recipe\[(.+?)\]/)
1044
+ entry_name = Regexp.last_match(1)
993
1045
  if recipe_list.nil?
994
1046
  query=%Q{#{MU::Groomer::Chef.knife} recipe list};
995
1047
  recipe_list = %x{#{query}}
996
1048
  end
997
- if !recipe_list.match(/(^|\n)#{rl_entry_name}($|\n)/)
998
- MU.log "Attempting to add non-existent #{rl_entry} to #{@server.mu_name}", MU::WARN
1049
+ if !recipe_list.match(/(^|\n)#{entry_name}($|\n)/)
1050
+ MU.log "Attempting to add non-existent #{entry} to #{@server.mu_name}", MU::WARN
999
1051
  missing = true
1000
1052
  end
1001
1053
  end