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
@@ -86,7 +86,7 @@ end
86
86
  # Create a security group, or manipulate an existing one, so that we have all
87
87
  # of the appropriate network holes.
88
88
  if $opts[:sg]
89
- open_ports = [443, 2260, 7443, 8443, 9443, 8200]
89
+ open_ports = [443, MU.mommaCatPort, 7443, 8443, 9443, 8200]
90
90
  ranges = if $MU_CFG and $MU_CFG['my_networks'] and $MU_CFG['my_networks'].size > 0
91
91
  $MU_CFG['my_networks'].map { |r|
92
92
  r = r+"/32" if r.match(/^\d+\.\d+\.\d+\.\d+$/)
@@ -245,7 +245,7 @@ if $opts[:logs]
245
245
 
246
246
  resp = MU::Cloud::AWS.s3(credentials: credset).list_buckets
247
247
  resp.buckets.each { |bucket|
248
- exists = true if bucket['name'] == bucketname
248
+ exists = true if bucket.name == bucketname
249
249
  }
250
250
  if !exists
251
251
  MU.log "Creating #{bucketname} bucket"
@@ -273,7 +273,7 @@ if $opts[:logs]
273
273
  body: "#{key}"
274
274
  )
275
275
  end
276
- if File.exists?("#{MU.mySSLDir}/Mu_CA.pem")
276
+ if File.exist?("#{MU.mySSLDir}/Mu_CA.pem")
277
277
  MU.log "Putting the Mu Master's public SSL certificate into #{bucketname}/Mu_CA.pem"
278
278
  MU::Cloud::AWS.s3(credentials: credset).put_object(
279
279
  bucket: bucketname,
@@ -438,7 +438,7 @@ end
438
438
  if $opts[:uploadlogs]
439
439
  today = Time.new.strftime("%Y%m%d").to_s
440
440
  ["master.log", "nodes.log"].each { |log|
441
- if File.exists?("/Mu_Logs/#{log}-#{today}")
441
+ if File.exist?("/Mu_Logs/#{log}-#{today}")
442
442
  MU.log "Uploading /Mu_Logs/#{log}-#{today} to bucket #{$bucketname}"
443
443
  MU::Cloud::AWS.s3.put_object(
444
444
  bucket: $bucketname,
@@ -0,0 +1,265 @@
1
+ #!/usr/local/ruby-current/bin/ruby
2
+ #
3
+ # Copyright:: Copyright (c) 2017 eGlobalTech, Inc., all rights reserved
4
+ #
5
+ # Licensed under the BSD-3 license (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License in the root of the project or at
8
+ #
9
+ # http://egt-labs.com/mu/LICENSE.html
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # Perform initial Mu setup tasks:
18
+ # 1. Set up an appropriate Security Group
19
+ # 2. Associate a specific Elastic IP address to this MU server, if required.
20
+ # 3. Create an S3 bucket for Mu logs.
21
+
22
+ require 'etc'
23
+ require 'securerandom'
24
+
25
+ require File.expand_path(File.dirname(__FILE__))+"/mu-load-config.rb"
26
+
27
+ require 'rubygems'
28
+ require 'bundler/setup'
29
+ require 'json'
30
+ require 'erb'
31
+ require 'optimist'
32
+ require 'json-schema'
33
+ require 'mu'
34
+ require 'mu/master/ssl'
35
+ Dir.chdir(MU.installDir)
36
+
37
+ $opts = Optimist::options do
38
+ banner <<-EOS
39
+ Usage:
40
+ #{$0} [-i] [-s] [-l] [-u] [-d]
41
+ EOS
42
+ # opt :ip, "Attempt to configure the IP requested in the CHEF_PUBLIC_IP environment variable, or if none is set, to associate an arbitrary Elastic IP.", :require => false, :default => false, :type => :boolean
43
+ opt :sg, "Attempt to configure a Security Group with appropriate permissions.", :require => false, :default => false, :type => :boolean
44
+ opt :logs, "Ensure the presence of an Cloud Storage bucket prefixed with 'Mu_Logs' for use with CloudTrails, syslog, etc.", :require => false, :default => false, :type => :boolean
45
+ # opt :dns, "Ensure the presence of a private DNS Zone called for internal amongst Mu resources.", :require => false, :default => false, :type => :boolean
46
+ opt :uploadlogs, "Push today's log files to the Cloud Storage bucket created by the -l option.", :require => false, :default => false, :type => :boolean
47
+ end
48
+
49
+ if MU::Cloud::Azure.hosted? and !$MU_CFG['google']
50
+ new_cfg = $MU_CFG.dup
51
+ cfg_blob = MU::Cloud::Azure.hosted_config
52
+ if cfg_blob
53
+ cfg_blob['log_bucket_name'] ||= $MU_CFG['hostname']
54
+ new_cfg["google"] = { "default" => cfg_blob }
55
+ MU.log "Adding auto-detected Azure stanza to #{cfgPath}", MU::NOTICE
56
+ if new_cfg != $MU_CFG or !cfgExists?
57
+ MU.log "Generating #{cfgPath}"
58
+ saveMuConfig(new_cfg)
59
+ $MU_CFG = new_cfg
60
+ end
61
+ end
62
+ end
63
+
64
+ sgs_to_ifaces = {}
65
+ ifaces_to_sgs = {}
66
+ sgs = []
67
+ if MU::Cloud::Azure.hosted?
68
+ instance = MU.myCloudDescriptor
69
+ # Azure VMs can have exactly one security group per network interface, so if
70
+ # there's already one, we use it.
71
+ iface_num = 0
72
+ instance.network_profile.network_interfaces.each { |iface|
73
+ iface_id = MU::Cloud::Azure::Id.new(iface.id)
74
+ ifaces_to_sgs[iface_id] = false
75
+ iface_desc = MU::Cloud::Azure.network.network_interfaces.get(MU.myInstanceId.resource_group, iface_id.to_s)
76
+ if iface_desc.network_security_group
77
+ sg_id = MU::Cloud::Azure::Id.new(iface_desc.network_security_group.id)
78
+ sgs << sg_id
79
+ sgs_to_ifaces[sg_id] = iface_id
80
+ ifaces_to_sgs[iface_id] = sg_id
81
+ else
82
+ ifaces_to_sgs[iface_id] = "mu-master-"+MU.myInstanceId.name
83
+ ifaces_to_sgs[iface_id] += "-"+iface_num.to_s if iface_num > 0
84
+ end
85
+ if iface_desc.ip_configurations
86
+ iface_desc.ip_configurations.each { |ipcfg|
87
+ ipcfg.subnet.id.match(/resourceGroups\/([^\/]+)\/providers\/Microsoft.Network\/virtualNetworks\/([^\/]+)\/subnets\/(.*)/)
88
+ rg = Regexp.last_match[1]
89
+ vpc_id = Regexp.last_match[2]
90
+ subnet_id = Regexp.last_match[3]
91
+ subnet = MU::Cloud::Azure.network.subnets.get(
92
+ rg,
93
+ vpc_id,
94
+ subnet_id
95
+ )
96
+ if subnet.network_security_group
97
+ sg_id = MU::Cloud::Azure::Id.new(subnet.network_security_group.id)
98
+ sgs << sg_id
99
+ end
100
+ }
101
+ end
102
+ iface_num += 1
103
+ }
104
+ sgs.uniq!
105
+
106
+ # if !instance.tags.items or !instance.tags.items.include?(admin_sg_name)
107
+ # newitems = instance.tags.items ? instance.tags.items.dup : []
108
+ # newitems << admin_sg_name
109
+ # MU.log "Setting my instance tags", MU::NOTICE, details: newitems
110
+ # newtags = MU::Cloud::Azure.compute(:Tags).new(
111
+ # fingerprint: instance.tags.fingerprint,
112
+ # items: newitems
113
+ # )
114
+ # MU::Cloud::Azure.compute.set_instance_tags(
115
+ # MU::Cloud::Azure.myProject,
116
+ # MU.myAZ,
117
+ # MU.myInstanceId,
118
+ # newtags
119
+ # )
120
+ # instance = MU.myCloudDescriptor
121
+ # end
122
+ preferred_ip = MU.mu_public_ip
123
+ end
124
+
125
+ # Create a security group, or manipulate an existing one, so that we have all
126
+ # of the appropriate network holes.
127
+ if $opts[:sg]
128
+ open_ports = [80, 443, MU.mommaCatPort, 7443, 8443, 9443, 8200]
129
+
130
+ sgs.each { |sg_id|
131
+ admin_sg_name = sg_id.is_a?(String) ? sg_id : sg_id.name
132
+
133
+ found = MU::MommaCat.findStray("Azure", "firewall_rule", dummy_ok: true, cloud_id: admin_sg_name, region: instance.location)
134
+ admin_sg = found.first if !found.nil? and found.size > 0
135
+
136
+ rules = []
137
+ open_ports.each { |port|
138
+ rules << {
139
+ "proto" => "tcp",
140
+ "port" => port.to_s
141
+ }
142
+ }
143
+
144
+ rules << {
145
+ "proto" => "tcp",
146
+ "port" => 22
147
+ # "hosts" => ["#{preferred_ip}/32"]
148
+ }
149
+ cfg = {
150
+ "name" => admin_sg_name,
151
+ "scrub_mu_isms" => true,
152
+ "cloud" => "Azure",
153
+ "rules" => rules,
154
+ "region" => instance.location,
155
+ "target_tags" => [admin_sg_name],
156
+ "vpc" => {
157
+ "vpc_id" => MU::Cloud::Azure::Id.new(instance.network_profile.network_interfaces.first.id)
158
+ }
159
+ }
160
+
161
+ if !admin_sg
162
+ admin_sg = MU::Cloud::FirewallRule.new(kitten_cfg: cfg, mu_name: admin_sg_name)
163
+ admin_sg.create
164
+ admin_sg.groom
165
+ else
166
+ rules.each { |rule|
167
+ admin_sg.addRule(rule["hosts"], proto: rule["proto"], port: rule["port"].to_i)
168
+ }
169
+ end
170
+ }
171
+ end
172
+
173
+ $bucketname = MU::Cloud::Azure.adminBucketName
174
+
175
+ if $opts[:logs]
176
+ MU::Cloud::Azure.listCredentials.each { |credset|
177
+ bucketname = MU::Cloud::Azure.adminBucketName(credset)
178
+ exists = false
179
+
180
+ MU.log "Configuring log and secret Azure Cloud Storage bucket '#{bucketname}'"
181
+
182
+ bucket = nil
183
+ begin
184
+ bucket = MU::Cloud::Azure.storage(credentials: credset).get_bucket(bucketname)
185
+ rescue ::Azure::Apis::ClientError => e
186
+ if e.message.match(/notFound:/)
187
+ MU.log "Creating #{bucketname} bucket"
188
+ bucketobj = MU::Cloud::Azure.storage(:Bucket).new(
189
+ name: bucketname,
190
+ location: "US", # XXX why is this needed?
191
+ versioning: MU::Cloud::Azure.storage(:Bucket)::Versioning.new(
192
+ enabled: true
193
+ ),
194
+ lifecycle: MU::Cloud::Azure.storage(:Bucket)::Lifecycle.new(
195
+ rule: [ MU::Cloud::Azure.storage(:Bucket)::Lifecycle::Rule.new(
196
+ action: MU::Cloud::Azure.storage(:Bucket)::Lifecycle::Rule::Action.new(
197
+ type: "SetStorageClass",
198
+ storage_class: "DURABLE_REDUCED_AVAILABILITY"
199
+ ),
200
+ condition: MU::Cloud::Azure.storage(:Bucket)::Lifecycle::Rule::Condition.new(
201
+ age: 180
202
+ )
203
+ )]
204
+ )
205
+ )
206
+ bucket = MU::Cloud::Azure.storage(credentials: credset).insert_bucket(
207
+ MU::Cloud::Azure.defaultProject(credset),
208
+ bucketobj
209
+ )
210
+ else
211
+ pp e.backtrace
212
+ raise MU::MuError, e.inspect
213
+ end
214
+ end
215
+
216
+ ebs_key = nil
217
+
218
+ begin
219
+ ebs_key = MU::Cloud::Azure.storage(credentials: credset).get_object(bucketname, "log_vol_ebs_key")
220
+ rescue ::Azure::Apis::ClientError => e
221
+ if e.message.match(/notFound:/)
222
+ # XXX this may not be useful outside of AWS
223
+ MU.log "Creating new key for encrypted log volume"
224
+ key = SecureRandom.random_bytes(32)
225
+ f = Tempfile.new("logvolkey") # XXX this is insecure and stupid
226
+ f.write key
227
+ f.close
228
+ objectobj = MU::Cloud::Azure.storage(:Object).new(
229
+ bucket: bucketname,
230
+ name: "log_vol_ebs_key"
231
+ )
232
+ ebs_key = MU::Cloud::Azure.storage(credentials: credset).insert_object(
233
+ bucketname,
234
+ objectobj,
235
+ upload_source: f.path
236
+ )
237
+ f.unlink
238
+ else
239
+ raise MuError, e.inspect
240
+ end
241
+ end
242
+ # XXX stop doing this per-bucket, chowderhead
243
+ MU::Master.disk("/dev/xvdl", "/Mu_Logs", 50, "log_vol_ebs_key", "ram7")
244
+ }
245
+
246
+ end
247
+
248
+ if $opts[:dns]
249
+ end
250
+
251
+ if $opts[:uploadlogs]
252
+ today = Time.new.strftime("%Y%m%d").to_s
253
+ ["master.log", "nodes.log"].each { |log|
254
+ if File.exist?("/Mu_Logs/#{log}-#{today}")
255
+ MU.log "Uploading /Mu_Logs/#{log}-#{today} to bucket #{$bucketname}"
256
+ MU::Cloud::AWS.s3.put_object(
257
+ bucket: $bucketname,
258
+ key: "#{log}/#{today}",
259
+ body: File.read("/Mu_Logs/#{log}-#{today}")
260
+ )
261
+ else
262
+ MU.log "No log /Mu_Logs/#{log}-#{today} was found", MU::WARN
263
+ end
264
+ }
265
+ end
@@ -0,0 +1,43 @@
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
+ #pp MU::Cloud::Azure.listRegions
26
+ #pp MU::Cloud::Azure::Habitat.testcalls
27
+ #pp MU::Cloud::Azure::VPC.find(cloud_id: MU::Cloud::Azure::Id.new(resource_group: "mu", name: "mu-vnet"))
28
+ #pp MU::Cloud::Azure.authorization.role_assignments.list_for_resource_group("AKS-DEV-2019062015-KA-EASTUS")
29
+ #pp MU::Cloud::Azure::Role.find(role_name: "Azure Kubernetes Service Cluster Admin Role")
30
+ #puts MU::Cloud::Azure.default_subscription
31
+ #pp MU::Cloud::Azure.fetchPublicIP("MYVPC-DEV-2019061911-XI-EASTUS", "ip-addr-thingy")
32
+ #pp MU::Cloud::Azure.ensureProvider("egtazure", "Microsoft.ContainerService", force: true)
33
+ pp MU::Cloud::Azure::Server.find(cloud_id: "mu")
34
+ exit
35
+ pp MU::Cloud::Azure::Server.fetchImage("OpenLogic/CentOS/6")
36
+ pp MU::Cloud::Azure::Server.fetchImage("OpenLogic/CentOS/7")
37
+ pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/8")
38
+ pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/7")
39
+ pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/6")
40
+ pp MU::Cloud::Azure::Server.fetchImage("Debian/debian-10/10")
41
+ pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2012-R2-Datacenter")
42
+ pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2016-Datacenter")
43
+ pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2019-Datacenter")
@@ -23,6 +23,14 @@ require 'optimist'
23
23
  require 'mu'
24
24
  Dir.chdir(MU.installDir)
25
25
 
26
+ credentials = []
27
+ MU::Cloud.supportedClouds.each { |cloud|
28
+ cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
29
+ next if cloudclass.listCredentials.nil? or cloudclass.listCredentials.size == 0
30
+ credentials.concat(cloudclass.listCredentials)
31
+ }
32
+ credentials.uniq!
33
+
26
34
  $opts = Optimist::options do
27
35
  banner <<-EOS
28
36
  Usage:
@@ -35,6 +43,8 @@ Usage:
35
43
  opt :skipcloud, "Only purge Mu master deployment metadata, and skip all cloud resources.", :require => false, :default => false, :type => :boolean
36
44
  opt :web, "Generate web-friendly (HTML) output.", :require => false, :default => false, :type => :boolean
37
45
  opt :verbose, "Display debugging output.", :require => false, :default => false, :type => :boolean
46
+ opt :credentials, "Restrict to operating on a subset of available credential sets, instead of all that we know about.", :require => false, :default => credentials, :type => :strings
47
+ opt :regions, "Restrict to operating on a subset of available regions, instead of all that we know about.", :require => false, :type => :strings
38
48
  opt :quiet, "Display minimal output.", :require => false, :default => false, :type => :boolean
39
49
  end
40
50
  verbosity = MU::Logger::NORMAL
@@ -57,12 +67,14 @@ end
57
67
 
58
68
 
59
69
  MU::Cleanup.run(
60
- $opts[:deploy],
61
- noop: $opts[:noop],
62
- skipsnapshots: $opts[:skipsnapshots],
63
- onlycloud: $opts[:onlycloud],
64
- verbosity: verbosity,
65
- web: $opts[:web],
66
- skipcloud: $opts[:skipcloud],
67
- ignoremaster: $opts[:ignoremaster]
70
+ $opts[:deploy],
71
+ noop: $opts[:noop],
72
+ skipsnapshots: $opts[:skipsnapshots],
73
+ onlycloud: $opts[:onlycloud],
74
+ verbosity: verbosity,
75
+ web: $opts[:web],
76
+ skipcloud: $opts[:skipcloud],
77
+ ignoremaster: $opts[:ignoremaster],
78
+ credsets: $opts[:credentials],
79
+ regions: $opts[:regions]
68
80
  )
@@ -29,12 +29,52 @@ require 'erb'
29
29
  require 'tmpdir'
30
30
 
31
31
  $IN_GEM = false
32
- if Gem.paths and Gem.paths.home and File.dirname(__FILE__).match(/^#{Gem.paths.home}/)
33
- $IN_GEM = true
32
+ gemwhich = %x{gem which mu 2>&1}.chomp
33
+ gemwhich = nil if $?.exitstatus != 0
34
+ mypath = File.realpath(File.expand_path(File.dirname(__FILE__)))
35
+ if !mypath.match(/^\/opt\/mu/)
36
+ if Gem.paths and Gem.paths.home and
37
+ (mypath.match(/^#{Gem.paths.home}/) or gemwhich.match(/^#{Gem.paths.home}/))
38
+ $IN_GEM = true
39
+ elsif $?.exitstatus == 0 and gemwhich and !gemwhich.empty?
40
+ $LOAD_PATH.each { |path|
41
+ if path.match(/\/cloud-mu-[^\/]+\/modules/) or
42
+ path.match(/#{Regexp.quote(gemwhich)}/)
43
+ $IN_GEM = true
44
+ end
45
+ }
46
+ end
47
+ end
48
+
49
+ $possible_addresses = []
50
+ $impossible_addresses = ['127.0.0.1', 'localhost']
51
+ begin
52
+ sys_name = Socket.gethostname
53
+ official, aliases = Socket.gethostbyname(sys_name)
54
+ $possible_addresses << sys_name
55
+ $possible_addresses << official
56
+ $possible_addresses.concat(aliases)
57
+ rescue SocketError
58
+ # don't let them use the default hostname if it doesn't resolve
59
+ $impossible_addresses << sys_name
34
60
  end
61
+ Socket.getifaddrs.each { |iface|
62
+ if iface.addr and iface.addr.ipv4?
63
+ $possible_addresses << iface.addr.ip_address
64
+ begin
65
+ addrinfo = Socket.gethostbyaddr(iface.addr.ip_address)
66
+ $possible_addresses << addrinfo.first if !addrinfo.first.nil?
67
+ rescue SocketError
68
+ # usually no name to look up; that's ok
69
+ end
70
+ end
71
+ }
72
+ $possible_addresses.uniq!
73
+ $possible_addresses.reject! { |i| i.match(/^(0\.0\.0\.0$|169\.254\.|127\.0\.)/)}
35
74
 
36
75
  GIT_PATTERN = /(((git|ssh|http(s)?)|(git@[\w\.]+))(:(\/\/)?))?([\w\.@\:\/\-~]+)(\.git)?(\/)?/
37
76
 
77
+
38
78
  # Top-level keys in $MU_CFG for which we'll provide interactive, menu-driven
39
79
  # configuration.
40
80
  $CONFIGURABLES = {
@@ -42,8 +82,7 @@ $CONFIGURABLES = {
42
82
  "title" => "Public Address",
43
83
  "desc" => "IP address or hostname",
44
84
  "required" => true,
45
- "rootonly" => true,
46
- "pattern" => /^(localhost|127\.0\.0\.1|#{Socket.gethostname})$/,
85
+ "pattern" => /^(#{$impossible_addresses.map { |a| Regexp.quote(a) }.join("|") })$/,
47
86
  "negate_pattern" => true,
48
87
  "changes" => ["389ds", "chef-server", "chefrun", "chefcerts"]
49
88
  },
@@ -52,14 +91,12 @@ $CONFIGURABLES = {
52
91
  "desc" => "Administative contact email",
53
92
  "pattern" => /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i,
54
93
  "required" => true,
55
- "rootonly" => true,
56
94
  "changes" => ["mu-user", "chefrun"]
57
95
  },
58
96
  "mu_admin_name" => {
59
97
  "title" => "Admin Name",
60
98
  "desc" => "Administative contact's full name",
61
99
  "default" => "Mu Administrator",
62
- "rootonly" => true,
63
100
  "changes" => ["mu-user", "chefrun"]
64
101
  },
65
102
  "hostname" => {
@@ -70,10 +107,17 @@ $CONFIGURABLES = {
70
107
  "desc" => "The local system's value for HOSTNAME",
71
108
  "changes" => ["chefrun", "hostname"]
72
109
  },
110
+ "mommacat_port" => {
111
+ "title" => "Momma Cat Listen Port",
112
+ "pattern" => /^[0-9]+$/i,
113
+ "default" => 2260,
114
+ "required" => $IN_GEM,
115
+ "desc" => "Listen port for the Momma Cat grooming daemon",
116
+ "changes" => ["chefrun"]
117
+ },
73
118
  "banner" => {
74
119
  "title" => "Banner",
75
120
  "desc" => "Login banner, displayed in various locations",
76
- "rootonly" => true,
77
121
  "changes" => ["chefrun"]
78
122
  },
79
123
  "mu_repository" => {
@@ -105,6 +149,11 @@ $CONFIGURABLES = {
105
149
  "desc" => "If set to true, Mu will be allowed to modify routing and peering behavior of VPCs which it did not create, but for which it has permissions.",
106
150
  "boolean" => true
107
151
  },
152
+ "ansible_dir" => {
153
+ "title" => "Ansible directory",
154
+ "desc" => "Intended for use with minimal installs which use Ansible as a groomer and which do not store Ansible artifacts in a dedicated git repository. This allows simply pointing to a local directory.",
155
+ "required" => false
156
+ },
108
157
  "aws" => {
109
158
  "title" => "Amazon Web Services",
110
159
  "named_subentries" => true,
@@ -166,6 +215,10 @@ $CONFIGURABLES = {
166
215
  "title" => "Credentials File",
167
216
  "desc" => "JSON-formatted Service Account credentials for our GCP account, stored in plain text in a file. Generate a service account at: https://console.cloud.google.com/iam-admin/serviceaccounts/project, making sure the account has sufficient privileges to manage cloud resources. Download the private key as JSON and point this argument to the file. This is less secure than using 'credentials' to store in a vault."
168
217
  },
218
+ "credentials_encoded" => {
219
+ "title" => "Base64-Encoded Credentials",
220
+ "desc" => "JSON-formatted Service Account credentials for our GCP account, b64-encoded and dropped directly into mu.yaml. Generate a service account at: https://console.cloud.google.com/iam-admin/serviceaccounts/project, making sure the account has sufficient privileges to manage cloud resources. Download the private key as JSON and point this argument to the file. This is less secure than using 'credentials' to store in a vault."
221
+ },
169
222
  "region" => {
170
223
  "title" => "Default Region",
171
224
  "desc" => "Default Google Cloud Platform region in which we operate and deploy",
@@ -182,6 +235,11 @@ $CONFIGURABLES = {
182
235
  "required" => false,
183
236
  "desc" => "For Google Cloud projects which are attached to a GSuite domain. GCP service accounts cannot view or manage GSuite resources (groups, users, etc) directly, but must instead masquerade as a GSuite user which has delegated authority to the service account. See also: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority"
184
237
  },
238
+ "customer_id" => {
239
+ "title" => "GSuite Customer ID",
240
+ "required" => false,
241
+ "desc" => "For Google Cloud projects which are attached to a GSuite domain. Some API calls (groups, users, etc) require this identifier. From admin.google.com, choose Security, the Single Sign On, and look for the Entity ID field. The value after idpid= in the URL there should be the customer ID."
242
+ },
185
243
  "default" => {
186
244
  "title" => "Is Default Account",
187
245
  "default" => false,
@@ -194,28 +252,40 @@ $CONFIGURABLES = {
194
252
  "title" => "Microsoft Azure Cloud Computing Platform & Services",
195
253
  "named_subentries" => true,
196
254
  "subtree" => {
255
+ "directory_id" => {
256
+ "title" => "Directory ID",
257
+ "desc" => "AKA Tenant ID; the default Microsoft Azure Directory project in which we operate and deploy, from https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview"
258
+ },
259
+ "client_id" => {
260
+ "title" => "Client ID",
261
+ "desc" => "App client id used to authenticate to our subscription. From https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview"
262
+ },
263
+ "client_secret" => {
264
+ "title" => "Client Secret",
265
+ "desc" => "App client secret used to authenticate to our subscription. From https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview under the 'Certificates & secrets' tab, 'Client secrets.' This can only be retrieved upon initial secret creation."
266
+ },
197
267
  "subscription" => {
198
268
  "title" => "Default Subscription",
199
- "desc" => "Default Microsoft Azure Directory project in which we operate and deploy."
200
- },
201
- "credentials" => {
202
- "title" => "Credentials Vault:Item",
203
- "desc" => "A secure Chef vault and item from which to retrieve the JSON-formatted Service Account credentials for our Azure account, in the format vault:itemname (e.g. 'secrets:google'). Generate a service account at: https://console.cloud.google.com/iam-admin/serviceaccounts/project, making sure the account has sufficient privileges to manage cloud resources. Download the private key as JSON, and import that key to the vault specified here. Import example: knife vault create secrets google -J my-google-service-account.json "
269
+ "desc" => "Default Microsoft Azure Subscription we will use to deploy, from https://portal.azure.com/#blade/Microsoft_Azure_Billing/SubscriptionsBlade"
204
270
  },
271
+ # "credentials" => {
272
+ # "title" => "Credentials Vault:Item",
273
+ # "desc" => "A secure Chef vault and item from which to retrieve the JSON-formatted Service Account credentials for our Azure account, in the format vault:itemname (e.g. 'secrets:google'). Generate a service account at: https://console.cloud.google.com/iam-admin/serviceaccounts/project, making sure the account has sufficient privileges to manage cloud resources. Download the private key as JSON, and import that key to the vault specified here. Import example: knife vault create secrets google -J my-google-service-account.json "
274
+ # },
205
275
  "credentials_file" => {
206
276
  "title" => "Credentials File",
207
- "desc" => "JSON-formatted Service Account credentials for our Azure account, stored in plain text in a file."
277
+ "desc" => "JSON file which contains a hash of directory_id, client_id, client_secret, and subscription values. If found, these will be override values entered directly in mu-configure."
208
278
  },
209
279
  "region" => {
210
280
  "title" => "Default Region",
211
281
  "desc" => "Default Microsoft Azure region in which we operate and deploy",
212
282
  "default" => "eastus"
213
283
  },
214
- "log_bucket_name" => {
215
- "title" => "Log and Secret Bucket Name",
216
- "desc" => "Cloud Storage bucket into which we'll synchronize deploy secrets, and if we're hosted in Azure, collected system logs",
217
- "changes" => ["chefrun"]
218
- },
284
+ # "log_bucket_name" => {
285
+ # "title" => "Log and Secret Bucket Name",
286
+ # "desc" => "Cloud Storage bucket into which we'll synchronize deploy secrets, and if we're hosted in Azure, collected system logs",
287
+ # "changes" => ["chefrun"]
288
+ # },
219
289
  "default" => {
220
290
  "title" => "Is Default Account",
221
291
  "default" => false,
@@ -226,6 +296,55 @@ $CONFIGURABLES = {
226
296
  }
227
297
  }
228
298
 
299
+ def cloneHash(hash)
300
+ new = {}
301
+ hash.each_pair { |k,v|
302
+ if v.is_a?(Hash)
303
+ new[k] = cloneHash(v)
304
+ elsif !v.nil?
305
+ new[k] = v.dup
306
+ end
307
+ }
308
+ new
309
+ end
310
+
311
+ # Load values from our existing configuration into the $CONFIGURABLES hash
312
+ def importCurrentValues
313
+ require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
314
+ $CONFIGURABLES.each_key { |key|
315
+ next if !$MU_CFG.has_key?(key)
316
+ if $CONFIGURABLES[key].has_key?("subtree")
317
+ # It's a sub-tree. I'm too lazy to write a recursive thing for this, just
318
+ # cover the simple case that we actually care about for now.
319
+ if $CONFIGURABLES[key]["named_subentries"]
320
+ $CONFIGURABLES[key]['subtree']["#title"] = $CONFIGURABLES[key]['title']
321
+ $MU_CFG[key].each_pair { |nameentry, subtree|
322
+ $CONFIGURABLES[key]['subtree']["#entries"] ||= {}
323
+ $CONFIGURABLES[key]['subtree']["#entries"][nameentry] = cloneHash($CONFIGURABLES[key]['subtree'])
324
+ $CONFIGURABLES[key]['subtree']["#entries"][nameentry].delete("#entries")
325
+ $CONFIGURABLES[key]["subtree"]["#entries"][nameentry]["name"] = {
326
+ "title" => "Name",
327
+ "desc" => "A name/alias for this account.",
328
+ "required" => true,
329
+ "value" => nameentry
330
+ }
331
+ $CONFIGURABLES[key]["subtree"].keys.each { |subkey|
332
+ next if !subtree.has_key?(subkey)
333
+ $CONFIGURABLES[key]["subtree"]["#entries"][nameentry][subkey]["value"] = subtree[subkey]
334
+ }
335
+ }
336
+ else
337
+ $CONFIGURABLES[key]["subtree"].keys.each { |subkey|
338
+ next if !$MU_CFG[key].has_key?(subkey)
339
+ $CONFIGURABLES[key]["subtree"][subkey]["value"] = $MU_CFG[key][subkey]
340
+ }
341
+ end
342
+ else
343
+ $CONFIGURABLES[key]["value"] = $MU_CFG[key]
344
+ end
345
+ }
346
+ end
347
+
229
348
  AMROOT = Process.uid == 0
230
349
  HOMEDIR = Etc.getpwuid(Process.uid).dir
231
350
 
@@ -240,16 +359,16 @@ $opts = Optimist::options do
240
359
  data["subtree"].each_pair { |subkey, subdata|
241
360
  next if !AMROOT and subdata['rootonly']
242
361
  subdata['cli-opt'] = (key+"-"+subkey).gsub(/_/, "-")
243
- opt (key+"-"+subkey).to_sym, subdata["desc"], :require => false, :type => (subdata["boolean"] ? :boolean : :string)
362
+ opt subdata['cli-opt'].to_sym, subdata["desc"], :require => false, :type => (subdata["boolean"] ? :boolean : :string)
244
363
  required << subdata['cli-opt'] if subdata['required']
245
364
  }
246
365
  elsif data["array"]
247
366
  data['cli-opt'] = key.gsub(/_/, "-")
248
- opt key.to_sym, data["desc"], :require => false, :type => (data["boolean"] ? :booleans : :strings)
367
+ opt data['cli-opt'].to_sym, data["desc"], :require => false, :type => (data["boolean"] ? :booleans : :strings)
249
368
  required << data['cli-opt'] if data['required']
250
369
  else
251
370
  data['cli-opt'] = key.gsub(/_/, "-")
252
- opt key.to_sym, data["desc"], :require => false, :type => (data["boolean"] ? :boolean : :string)
371
+ opt data['cli-opt'].to_sym, data["desc"], :require => false, :type => (data["boolean"] ? :boolean : :string)
253
372
  required << data['cli-opt'] if data['required']
254
373
  end
255
374
  }
@@ -264,16 +383,38 @@ else
264
383
  MU_BASE = "/opt/mu"
265
384
  end
266
385
 
267
- $INITIALIZE = (!File.size?("#{MU_BASE}/etc/mu.yaml") or $opts[:force])
386
+ def cfgPath
387
+ home = Etc.getpwuid(Process.uid).dir
388
+ username = Etc.getpwuid(Process.uid).name
389
+ if Process.uid == 0
390
+ if ENV.include?('MU_INSTALLDIR')
391
+ ENV['MU_INSTALLDIR']+"/etc/mu.yaml"
392
+ elsif Dir.exist?("/opt/mu")
393
+ "/opt/mu/etc/mu.yaml"
394
+ else
395
+ "#{home}/.mu.yaml"
396
+ end
397
+ else
398
+ "#{home}/.mu.yaml"
399
+ end
400
+ end
401
+
402
+ $INITIALIZE = (!File.size?(cfgPath) or $opts[:force])
403
+
268
404
  $HAVE_GLOBAL_CONFIG = File.size?("#{MU_BASE}/etc/mu.yaml")
269
- if !AMROOT and ($INITIALIZE or !$HAVE_GLOBAL_CONFIG) and !$IN_GEM
405
+ if !AMROOT and !$HAVE_GLOBAL_CONFIG and !$IN_GEM and Dir.exist?("/opt/mu/lib")
270
406
  puts "Global configuration has not been initialized or is missing. Must run as root to correct."
271
407
  exit 1
272
408
  end
273
409
 
274
- if !$HAVE_GLOBAL_CONFIG and $opts[:noninteractive] and (!$opts[:public_address] or !$opts[:mu_admin_email])
275
- puts "Specify --public-address and --mu-admin-email on new non-interactive configs"
276
- exit 1
410
+ if !$HAVE_GLOBAL_CONFIG and $opts[:noninteractive] and (!$opts[:"public-address"] or !$opts[:"mu-admin-email"])
411
+ if $IN_GEM
412
+ importCurrentValues # maybe we're in local-only mode
413
+ end
414
+ if !$MU_CFG or !$MU_CFG['mu_admin_email'] or !$MU_CFG['mu_admin_name']
415
+ puts "Specify --public-address and --mu-admin-email on new non-interactive configs"
416
+ exit 1
417
+ end
277
418
  end
278
419
 
279
420
  $IN_AWS = false
@@ -298,13 +439,12 @@ end
298
439
  $IN_AZURE = false
299
440
  begin
300
441
  Timeout.timeout(2) do
301
- instance_id = open("http://169.254.169.254/metadata/instance/compute").read
302
- $IN_AWS = true if !instance_id.nil? and instance_id.size > 0
442
+ instance = open("http://169.254.169.254/metadata/instance/compute?api-version=2017-08-01","Metadata"=>"true").read
443
+ $IN_AZURE = true if !instance.nil? and instance.size > 0
303
444
  end
304
445
  rescue OpenURI::HTTPError, Timeout::Error, SocketError, Errno::ENETUNREACH, Errno::EHOSTUNREACH
305
446
  end
306
447
 
307
-
308
448
  KNIFE_TEMPLATE = "log_level :info
309
449
  log_location STDOUT
310
450
  node_name '<%= chefuser %>'
@@ -340,17 +480,6 @@ ssl_verify_mode :verify_none
340
480
 
341
481
  $CHANGES = []
342
482
 
343
- def cloneHash(hash)
344
- new = {}
345
- hash.each_pair { |k,v|
346
- if v.is_a?(Hash)
347
- new[k] = cloneHash(v)
348
- elsif !v.nil?
349
- new[k] = v.dup
350
- end
351
- }
352
- new
353
- end
354
483
 
355
484
  $MENU_MAP = {}
356
485
  def assignMenuEntries(tree = $CONFIGURABLES, map = $MENU_MAP)
@@ -420,7 +549,7 @@ def trySSHKeyWithGit(repo, keypath = nil)
420
549
  response = Readline.readline("Y/N> ".bold, false)
421
550
  end while !response and !response.match(/^(y|n)$/i)
422
551
  if response == "y" or response == "Y"
423
- Dir.mkdir("#{HOMEDIR}/.ssh", 0700) if !Dir.exists?("#{HOMEDIR}/.ssh")
552
+ Dir.mkdir("#{HOMEDIR}/.ssh", 0700) if !Dir.exist?("#{HOMEDIR}/.ssh")
424
553
  keynamestr = repo.gsub(/[^a-z0-9\-]/i, "-") + Process.pid.to_s
425
554
  keypath = "#{HOMEDIR}/.ssh/#{keynamestr}"
426
555
  puts "Paste a complete SSH private key for #{ssh_user.bold}@#{ssh_host.bold} below, then ^D"
@@ -433,7 +562,7 @@ def trySSHKeyWithGit(repo, keypath = nil)
433
562
  end
434
563
  end
435
564
 
436
- if File.exists?("#{HOMEDIR}/.ssh/config")
565
+ if File.exist?("#{HOMEDIR}/.ssh/config")
437
566
  FileUtils.cp("#{HOMEDIR}/.ssh/config", "#{HOMEDIR}/.ssh/config.bak.#{Process.pid.to_s}")
438
567
  cfgbackup = "#{HOMEDIR}/.ssh/config.bak.#{Process.pid.to_s}"
439
568
  end
@@ -482,8 +611,8 @@ def cloneGitRepo(repo)
482
611
  elsif $?.exitstatus != 0 and output.match(/permission denied/i)
483
612
  puts ""
484
613
  puts output.red.on_black
485
- if $opts[:ssh_keys_given]
486
- $opts[:ssh_keys].each { |keypath|
614
+ if $opts[:"ssh-keys-given"]
615
+ $opts[:"ssh-keys"].each { |keypath|
487
616
  if trySSHKeyWithGit(fullrepo, keypath)
488
617
  Dir.chdir(cwd)
489
618
  return fullrepo
@@ -558,10 +687,9 @@ def setDefaults
558
687
  end
559
688
  end
560
689
 
561
- ips.concat(Socket.ip_address_list.delete_if { |i| !i.ipv4? or i.ip_address.match(/^(0\.0\.0\.0$|169\.254\.|127\.0\.)/) }.map { |a| a.ip_address })
562
690
 
563
691
  $CONFIGURABLES["allow_invade_foreign_vpcs"]["default"] = false
564
- $CONFIGURABLES["public_address"]["default"] = ips.first
692
+ $CONFIGURABLES["public_address"]["default"] = $possible_addresses.first
565
693
  $CONFIGURABLES["hostname"]["default"] = Socket.gethostname
566
694
  $CONFIGURABLES["banner"]["default"] = "Mu Master at #{$CONFIGURABLES["public_address"]["default"]}"
567
695
  if $IN_AWS
@@ -605,19 +733,42 @@ def importCLIValues
605
733
  $CONFIGURABLES.each_pair { |key, data|
606
734
  next if !AMROOT and data['rootonly']
607
735
  if data.has_key?("subtree")
736
+
608
737
  if !data['named_subentries']
609
738
  data["subtree"].each_pair { |subkey, subdata|
610
739
  next if !AMROOT and subdata['rootonly']
611
- if $opts[(subdata['cli-opt'].gsub(/-/, "_")+"_given").to_sym]
612
- newval = runValueCallback(subdata, $opts[subdata['cli-opt'].gsub(/-/, "_").to_sym])
740
+ if $opts[(subdata['cli-opt'].+"_given").to_sym]
741
+ newval = runValueCallback(subdata, $opts[subdata['cli-opt'].to_sym])
613
742
  subdata["value"] = newval if !newval.nil?
614
743
  $CHANGES.concat(subdata['changes']) if subdata['changes']
615
744
  end
616
745
  }
746
+ # Honor CLI adds for named trees (credentials, etc) if there are no
747
+ # entries in them yet.
748
+ elsif data["#entries"].nil? or data["#entries"].empty?
749
+ newvals = false
750
+ data["subtree"].each_pair { |subkey, subdata|
751
+ next if !AMROOT and subdata['rootonly']
752
+ next if !subdata['cli-opt']
753
+ if $opts[(subdata['cli-opt']+"_given").to_sym]
754
+ newval = runValueCallback(subdata, $opts[subdata['cli-opt'].to_sym])
755
+ if !newval.nil?
756
+ subdata["value"] = newval
757
+ newvals = true
758
+ end
759
+ end
760
+ }
761
+ if newvals
762
+ newtree = data["subtree"].dup
763
+ newtree['default']['value'] = true if newtree['default']
764
+ data['subtree']['#entries'] = {
765
+ "default" => newtree
766
+ }
767
+ end
617
768
  end
618
769
  else
619
- if $opts[(data['cli-opt'].gsub(/-/, "_")+"_given").to_sym]
620
- newval = runValueCallback(data, $opts[data['cli-opt'].gsub(/-/, "_").to_sym])
770
+ if $opts[(data['cli-opt']+"_given").to_sym]
771
+ newval = runValueCallback(data, $opts[data['cli-opt'].to_sym])
621
772
  data["value"] = newval if !newval.nil?
622
773
  $CHANGES.concat(data['changes']) if data['changes']
623
774
  end
@@ -625,42 +776,6 @@ def importCLIValues
625
776
  }
626
777
  end
627
778
 
628
- # Load values from our existing configuration into the $CONFIGURABLES hash
629
- def importCurrentValues
630
- require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
631
- $CONFIGURABLES.each_key { |key|
632
- next if !$MU_CFG.has_key?(key)
633
- if $CONFIGURABLES[key].has_key?("subtree")
634
- # It's a sub-tree. I'm too lazy to write a recursive thing for this, just
635
- # cover the simple case that we actually care about for now.
636
- if $CONFIGURABLES[key]["named_subentries"]
637
- $CONFIGURABLES[key]['subtree']["#title"] = $CONFIGURABLES[key]['title']
638
- $MU_CFG[key].each_pair { |nameentry, subtree|
639
- $CONFIGURABLES[key]['subtree']["#entries"] ||= {}
640
- $CONFIGURABLES[key]['subtree']["#entries"][nameentry] = cloneHash($CONFIGURABLES[key]['subtree'])
641
- $CONFIGURABLES[key]['subtree']["#entries"][nameentry].delete("#entries")
642
- $CONFIGURABLES[key]["subtree"]["#entries"][nameentry]["name"] = {
643
- "title" => "Name",
644
- "desc" => "A name/alias for this account.",
645
- "required" => true,
646
- "value" => nameentry
647
- }
648
- $CONFIGURABLES[key]["subtree"].keys.each { |subkey|
649
- next if !subtree.has_key?(subkey)
650
- $CONFIGURABLES[key]["subtree"]["#entries"][nameentry][subkey]["value"] = subtree[subkey]
651
- }
652
- }
653
- else
654
- $CONFIGURABLES[key]["subtree"].keys.each { |subkey|
655
- next if !$MU_CFG[key].has_key?(subkey)
656
- $CONFIGURABLES[key]["subtree"][subkey]["value"] = $MU_CFG[key][subkey]
657
- }
658
- end
659
- else
660
- $CONFIGURABLES[key]["value"] = $MU_CFG[key]
661
- end
662
- }
663
- end
664
779
 
665
780
  def printVal(data)
666
781
  valid = true
@@ -969,6 +1084,7 @@ if !$opts[:noninteractive]
969
1084
  $CONFIGURABLES, $MENU_MAP = menu
970
1085
  $MU_CFG = setConfigTree
971
1086
  else
1087
+ $MU_CFG = setConfigTree
972
1088
  if !entireConfigValid?
973
1089
  puts "Configuration had validation errors, exiting.\nRe-invoke #{$0} to correct."
974
1090
  exit 1
@@ -1012,7 +1128,7 @@ def set389DSCreds
1012
1128
  data = MU::Groomer::Chef.getSecret(vault: "mu_ldap", item: creds)
1013
1129
  MU::Groomer::Chef.grantSecretAccess("MU-MASTER", "mu_ldap", creds)
1014
1130
  end
1015
- rescue MU::Groomer::Chef::MuNoSuchSecret
1131
+ rescue MU::Groomer::MuNoSuchSecret
1016
1132
  user = cfg["user"]
1017
1133
  pw = Password.pronounceable(14..16)
1018
1134
  if $MU_CFG["ldap"].has_key?(creds)
@@ -1038,7 +1154,7 @@ def set389DSCreds
1038
1154
  }
1039
1155
  end
1040
1156
 
1041
- if AMROOT
1157
+ if AMROOT and !$IN_GEM
1042
1158
  cur_chef_version = `/bin/rpm -q chef`.sub(/^chef-(\d+\.\d+\.\d+-\d+)\..*/, '\1').chomp
1043
1159
  pref_chef_version = File.read("#{MU_BASE}/var/mu-chef-client-version").chomp
1044
1160
  if (cur_chef_version != pref_chef_version and cur_chef_version.sub(/\-\d+$/, "") != pref_chef_version) or cur_chef_version.match(/is not installed/)
@@ -1054,11 +1170,12 @@ if AMROOT
1054
1170
  end
1055
1171
 
1056
1172
  if $INITIALIZE
1057
- if AMROOT
1173
+ if AMROOT and !$IN_GEM
1058
1174
  %x{/sbin/service iptables stop} # Chef run will set up correct rules later
1059
1175
  end
1060
1176
  $MU_SET_DEFAULTS = setConfigTree
1061
1177
  require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
1178
+ saveMuConfig($MU_SET_DEFAULTS)
1062
1179
  else
1063
1180
  if AMROOT
1064
1181
  $NEW_CFG = $MU_CFG.merge(setConfigTree)
@@ -1078,10 +1195,16 @@ rescue LoadError
1078
1195
  system("cd #{MU_BASE}/lib/modules && umask 0022 && /usr/local/ruby-current/bin/bundle install")
1079
1196
  require 'mu'
1080
1197
  end
1081
-
1198
+ exit
1082
1199
  if $IN_GEM
1200
+ if $INITIALIZE
1201
+ $MU_CFG = MU.detectCloudProviders
1202
+ end
1203
+ require 'mu/master/ssl'
1204
+ MU::Master::SSL.bootstrap
1083
1205
  puts $MU_CFG.to_yaml
1084
1206
  saveMuConfig($MU_CFG)
1207
+ MU::MommaCat.restart
1085
1208
  exit
1086
1209
  end
1087
1210
 
@@ -1122,7 +1245,7 @@ def updateChefRbs
1122
1245
  user = AMROOT ? "mu" : Etc.getpwuid(Process.uid).name
1123
1246
  chefuser = user.gsub(/\./, "")
1124
1247
  templates = { HOMEDIR+"/.chef/knife.rb" => KNIFE_TEMPLATE }
1125
- Dir.mkdir(HOMEDIR+"/.chef") if !Dir.exists?(HOMEDIR+"/.chef")
1248
+ Dir.mkdir(HOMEDIR+"/.chef") if !Dir.exist?(HOMEDIR+"/.chef")
1126
1249
  if AMROOT
1127
1250
  templates["/etc/chef/client.rb"] = CLIENT_TEMPLATE
1128
1251
  templates["/etc/opscode/pivotal.rb"] = PIVOTAL_TEMPLATE
@@ -1156,10 +1279,10 @@ if AMROOT
1156
1279
  if !File.size?(cfgpath) or File.read(tmpfile) != File.read(cfgpath)
1157
1280
  File.rename(tmpfile, cfgpath)
1158
1281
  # Opscode can't seem to get things right with their postgres socket
1159
- Dir.mkdir("/var/run/postgresql", 0755) if !Dir.exists?("/var/run/postgresql")
1160
- if File.exists?("/tmp/.s.PGSQL.5432") and !File.exists?("/var/run/postgresql/.s.PGSQL.5432")
1282
+ Dir.mkdir("/var/run/postgresql", 0755) if !Dir.exist?("/var/run/postgresql")
1283
+ if File.exist?("/tmp/.s.PGSQL.5432") and !File.exist?("/var/run/postgresql/.s.PGSQL.5432")
1161
1284
  File.symlink("/tmp/.s.PGSQL.5432", "/var/run/postgresql/.s.PGSQL.5432")
1162
- elsif !File.exists?("/tmp/.s.PGSQL.5432") and File.exists?("/var/run/postgresql/.s.PGSQL.5432")
1285
+ elsif !File.exist?("/tmp/.s.PGSQL.5432") and File.exist?("/var/run/postgresql/.s.PGSQL.5432")
1163
1286
  File.symlink("/var/run/postgresql/.s.PGSQL.5432", "/tmp/.s.PGSQL.5432")
1164
1287
  end
1165
1288
  MU.log "Chef Server config was modified, reconfiguring...", MU::NOTICE
@@ -1186,6 +1309,9 @@ end
1186
1309
  if $IN_GOOGLE and AMROOT
1187
1310
  system("#{MU_BASE}/lib/bin/mu-gcp-setup --sg --logs")
1188
1311
  end
1312
+ if $IN_AZURE and AMROOT
1313
+ system("#{MU_BASE}/lib/bin/mu-azure-setup --sg")
1314
+ end
1189
1315
 
1190
1316
  if $INITIALIZE or $CHANGES.include?("chefcerts")
1191
1317
  system("rm -f #{HOMEDIR}/.chef/trusted_certs/* ; knife ssl fetch -c #{HOMEDIR}/.chef/knife.rb")
@@ -1212,7 +1338,7 @@ if $MU_CFG['repos'] and $MU_CFG['repos'].size > 0
1212
1338
  repo.match(/\/([^\/]+?)(\.git)?$/)
1213
1339
  shortname = Regexp.last_match(1)
1214
1340
  repodir = MU.dataDir + "/" + shortname
1215
- if !Dir.exists?(repodir)
1341
+ if !Dir.exist?(repodir)
1216
1342
  MU.log "Cloning #{repo} into #{repodir}", MU::NOTICE
1217
1343
  Dir.chdir(MU.dataDir)
1218
1344
  system("/usr/bin/git clone #{repo}")
@@ -1227,7 +1353,7 @@ end
1227
1353
 
1228
1354
  begin
1229
1355
  MU::Groomer::Chef.getSecret(vault: "secrets", item: "consul")
1230
- rescue MU::Groomer::Chef::MuNoSuchSecret
1356
+ rescue MU::Groomer::MuNoSuchSecret
1231
1357
  data = {
1232
1358
  "private_key" => File.read("#{MU_BASE}/var/ssl/consul.key"),
1233
1359
  "certificate" => File.read("#{MU_BASE}/var/ssl/consul.crt"),
@@ -1252,7 +1378,7 @@ if $MU_CFG['ldap']['type'] == "389 Directory Services"
1252
1378
  $CHANGES << "389ds"
1253
1379
  end
1254
1380
  if $INITIALIZE or $CHANGES.include?("389ds")
1255
- File.unlink("/root/389ds.tmp/389-directory-setup.inf") if File.exists?("/root/389ds.tmp/389-directory-setup.inf")
1381
+ File.unlink("/root/389ds.tmp/389-directory-setup.inf") if File.exist?("/root/389ds.tmp/389-directory-setup.inf")
1256
1382
  MU.log "Configuring 389 Directory Services", MU::NOTICE
1257
1383
  set389DSCreds
1258
1384
  system("chef-client -o 'recipe[mu-master::389ds]'")
@@ -1297,7 +1423,7 @@ MU.log "Running chef-client on MU-MASTER", MU::NOTICE
1297
1423
  system("chef-client -o '#{run_list.join(",")}'")
1298
1424
 
1299
1425
 
1300
- if !File.exists?("#{MU_BASE}/var/users/mu/email") or !File.exists?("#{MU_BASE}/var/users/mu/realname")
1426
+ if !File.exist?("#{MU_BASE}/var/users/mu/email") or !File.exist?("#{MU_BASE}/var/users/mu/realname")
1301
1427
  MU.log "Finalizing the 'mu' Chef/LDAP account", MU::NOTICE
1302
1428
  MU.setLogging(MU::Logger::SILENT)
1303
1429
  MU::Master.manageUser(