cloud-mu 1.9.0.pre.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (618) hide show
  1. checksums.yaml +7 -0
  2. data/Berksfile +56 -0
  3. data/Berksfile.lock +250 -0
  4. data/Jenkinsfile +184 -0
  5. data/LICENSE.md +37 -0
  6. data/README.md +26 -0
  7. data/bin/mu-aws-setup +376 -0
  8. data/bin/mu-cleanup +68 -0
  9. data/bin/mu-configure +1133 -0
  10. data/bin/mu-deploy +166 -0
  11. data/bin/mu-firewall-allow-clients +30 -0
  12. data/bin/mu-gcp-setup +200 -0
  13. data/bin/mu-gen-docs +34 -0
  14. data/bin/mu-gen-env +42 -0
  15. data/bin/mu-load-config.rb +158 -0
  16. data/bin/mu-node-manage +683 -0
  17. data/bin/mu-self-update +228 -0
  18. data/bin/mu-ssh +23 -0
  19. data/bin/mu-tunnel-nagios +144 -0
  20. data/bin/mu-upload-chef-artifacts +757 -0
  21. data/bin/mu-user-manage +275 -0
  22. data/cookbooks/awscli/LICENSE +37 -0
  23. data/cookbooks/awscli/README.md +58 -0
  24. data/cookbooks/awscli/attributes/default.rb +1 -0
  25. data/cookbooks/awscli/libraries/instance_metadata.rb +21 -0
  26. data/cookbooks/awscli/metadata.rb +20 -0
  27. data/cookbooks/awscli/recipes/default.rb +56 -0
  28. data/cookbooks/awscli/templates/default/config.erb +18 -0
  29. data/cookbooks/mu-activedirectory/CHANGELOG.md +13 -0
  30. data/cookbooks/mu-activedirectory/LICENSE +37 -0
  31. data/cookbooks/mu-activedirectory/README.md +6 -0
  32. data/cookbooks/mu-activedirectory/attributes/default.rb +98 -0
  33. data/cookbooks/mu-activedirectory/files/default/password-auth +32 -0
  34. data/cookbooks/mu-activedirectory/files/default/sshd_pol.pp +0 -0
  35. data/cookbooks/mu-activedirectory/files/default/sshd_pol.te +32 -0
  36. data/cookbooks/mu-activedirectory/files/default/syslogd_oddjobd.pp +0 -0
  37. data/cookbooks/mu-activedirectory/files/default/syslogd_oddjobd.te +10 -0
  38. data/cookbooks/mu-activedirectory/files/default/system-auth +34 -0
  39. data/cookbooks/mu-activedirectory/files/default/winbindpol.pp +0 -0
  40. data/cookbooks/mu-activedirectory/files/default/winbindpol.te +37 -0
  41. data/cookbooks/mu-activedirectory/libraries/config.rb +106 -0
  42. data/cookbooks/mu-activedirectory/libraries/helper.rb +86 -0
  43. data/cookbooks/mu-activedirectory/metadata.rb +17 -0
  44. data/cookbooks/mu-activedirectory/providers/domain.rb +152 -0
  45. data/cookbooks/mu-activedirectory/providers/domain_controller.rb +89 -0
  46. data/cookbooks/mu-activedirectory/providers/domain_node.rb +275 -0
  47. data/cookbooks/mu-activedirectory/recipes/default.rb +8 -0
  48. data/cookbooks/mu-activedirectory/recipes/domain-controller.rb +44 -0
  49. data/cookbooks/mu-activedirectory/recipes/domain-node.rb +50 -0
  50. data/cookbooks/mu-activedirectory/recipes/domain.rb +43 -0
  51. data/cookbooks/mu-activedirectory/recipes/sssd.rb +185 -0
  52. data/cookbooks/mu-activedirectory/resources/domain.rb +25 -0
  53. data/cookbooks/mu-activedirectory/resources/domain_controller.rb +25 -0
  54. data/cookbooks/mu-activedirectory/resources/domain_node.rb +20 -0
  55. data/cookbooks/mu-activedirectory/templates/default/dhclient-eth0.conf.erb +4 -0
  56. data/cookbooks/mu-activedirectory/templates/default/interface +0 -0
  57. data/cookbooks/mu-activedirectory/templates/default/krb5.conf.erb +23 -0
  58. data/cookbooks/mu-activedirectory/templates/default/ntp.conf.erb +56 -0
  59. data/cookbooks/mu-activedirectory/templates/default/smb.conf.erb +33 -0
  60. data/cookbooks/mu-activedirectory/templates/default/sssd.conf.erb +60 -0
  61. data/cookbooks/mu-activedirectory/templates/windows/Backup.xml.erb +20 -0
  62. data/cookbooks/mu-activedirectory/templates/windows/bkupInfo.xml.erb +1 -0
  63. data/cookbooks/mu-activedirectory/templates/windows/gpreprt.xml.erb +198 -0
  64. data/cookbooks/mu-activedirectory/templates/windows/gptmpl.inf.erb +12 -0
  65. data/cookbooks/mu-activedirectory/templates/windows/manifest.xml.erb +1 -0
  66. data/cookbooks/mu-firewall/CHANGELOG.md +11 -0
  67. data/cookbooks/mu-firewall/LICENSE +37 -0
  68. data/cookbooks/mu-firewall/README.md +5 -0
  69. data/cookbooks/mu-firewall/attributes/default.rb +3 -0
  70. data/cookbooks/mu-firewall/metadata.rb +16 -0
  71. data/cookbooks/mu-firewall/recipes/default.rb +10 -0
  72. data/cookbooks/mu-glusterfs/CHANGELOG.md +13 -0
  73. data/cookbooks/mu-glusterfs/LICENSE +37 -0
  74. data/cookbooks/mu-glusterfs/README.md +5 -0
  75. data/cookbooks/mu-glusterfs/attributes/default.rb +34 -0
  76. data/cookbooks/mu-glusterfs/metadata.rb +17 -0
  77. data/cookbooks/mu-glusterfs/recipes/client.rb +62 -0
  78. data/cookbooks/mu-glusterfs/recipes/default.rb +16 -0
  79. data/cookbooks/mu-glusterfs/recipes/samba.rb +57 -0
  80. data/cookbooks/mu-glusterfs/recipes/server.rb +200 -0
  81. data/cookbooks/mu-glusterfs/templates/default/mu-gluster-client.erb +71 -0
  82. data/cookbooks/mu-glusterfs/templates/default/smb.conf.erb +14 -0
  83. data/cookbooks/mu-jenkins/CHANGELOG.md +13 -0
  84. data/cookbooks/mu-jenkins/LICENSE +37 -0
  85. data/cookbooks/mu-jenkins/README.md +105 -0
  86. data/cookbooks/mu-jenkins/attributes/default.rb +42 -0
  87. data/cookbooks/mu-jenkins/files/default/cleanup_deploy_config.xml +73 -0
  88. data/cookbooks/mu-jenkins/files/default/deploy_config.xml +44 -0
  89. data/cookbooks/mu-jenkins/metadata.rb +21 -0
  90. data/cookbooks/mu-jenkins/recipes/default.rb +195 -0
  91. data/cookbooks/mu-jenkins/recipes/node-ssh-config.rb +54 -0
  92. data/cookbooks/mu-jenkins/recipes/public_key.rb +24 -0
  93. data/cookbooks/mu-jenkins/templates/default/example_job.config.xml.erb +24 -0
  94. data/cookbooks/mu-jenkins/templates/default/org.jvnet.hudson.plugins.SSHBuildWrapper.xml.erb +14 -0
  95. data/cookbooks/mu-jenkins/templates/default/ssh_config.erb +6 -0
  96. data/cookbooks/mu-master/CHANGELOG.md +13 -0
  97. data/cookbooks/mu-master/LICENSE +37 -0
  98. data/cookbooks/mu-master/README.md +6 -0
  99. data/cookbooks/mu-master/attributes/default.rb +95 -0
  100. data/cookbooks/mu-master/files/default/0-mu-log-server.conf +19 -0
  101. data/cookbooks/mu-master/files/default/addRSA.ldif +8 -0
  102. data/cookbooks/mu-master/files/default/check_mem.pl +197 -0
  103. data/cookbooks/mu-master/files/default/cloudamatic.png +0 -0
  104. data/cookbooks/mu-master/files/default/dirsrv_admin.pp +0 -0
  105. data/cookbooks/mu-master/files/default/dirsrv_admin.te +13 -0
  106. data/cookbooks/mu-master/files/default/nagios_selinux.pp +0 -0
  107. data/cookbooks/mu-master/files/default/nagios_selinux.te +51 -0
  108. data/cookbooks/mu-master/files/default/nagios_selinux_7.pp +0 -0
  109. data/cookbooks/mu-master/files/default/nagios_selinux_7.te +17 -0
  110. data/cookbooks/mu-master/files/default/pam_sshd +18 -0
  111. data/cookbooks/mu-master/files/default/ssl_enable.ldif +18 -0
  112. data/cookbooks/mu-master/files/default/syslogd_oddjobd.pp +0 -0
  113. data/cookbooks/mu-master/files/default/syslogd_oddjobd.te +10 -0
  114. data/cookbooks/mu-master/files/default/vimrc +19 -0
  115. data/cookbooks/mu-master/libraries/mu.rb +29 -0
  116. data/cookbooks/mu-master/metadata.rb +30 -0
  117. data/cookbooks/mu-master/providers/user.rb +41 -0
  118. data/cookbooks/mu-master/recipes/389ds.rb +164 -0
  119. data/cookbooks/mu-master/recipes/basepackages.rb +58 -0
  120. data/cookbooks/mu-master/recipes/caching_nameserver.rb +37 -0
  121. data/cookbooks/mu-master/recipes/default.rb +451 -0
  122. data/cookbooks/mu-master/recipes/eks-kubectl.rb +41 -0
  123. data/cookbooks/mu-master/recipes/firewall-holes.rb +70 -0
  124. data/cookbooks/mu-master/recipes/init.rb +542 -0
  125. data/cookbooks/mu-master/recipes/ssl-certs.rb +109 -0
  126. data/cookbooks/mu-master/recipes/sssd.rb +89 -0
  127. data/cookbooks/mu-master/recipes/update_nagios_only.rb +242 -0
  128. data/cookbooks/mu-master/recipes/vault.rb +111 -0
  129. data/cookbooks/mu-master/resources/user.rb +19 -0
  130. data/cookbooks/mu-master/templates/default/389-directory-setup.inf.erb +28 -0
  131. data/cookbooks/mu-master/templates/default/chef-server.rb.erb +18 -0
  132. data/cookbooks/mu-master/templates/default/dhclient-eth0.conf.erb +9 -0
  133. data/cookbooks/mu-master/templates/default/mu-momma-cat.erb +149 -0
  134. data/cookbooks/mu-master/templates/default/mu.rc.erb +9 -0
  135. data/cookbooks/mu-master/templates/default/openssl.cnf.erb +354 -0
  136. data/cookbooks/mu-master/templates/default/sssd.conf.erb +44 -0
  137. data/cookbooks/mu-master/templates/default/web_app.conf.erb +90 -0
  138. data/cookbooks/mu-mongo/CHANGELOG.md +13 -0
  139. data/cookbooks/mu-mongo/LICENSE +37 -0
  140. data/cookbooks/mu-mongo/README.md +5 -0
  141. data/cookbooks/mu-mongo/attributes/default.rb +22 -0
  142. data/cookbooks/mu-mongo/files/default/keyfile +16 -0
  143. data/cookbooks/mu-mongo/files/default/remove_nodes.js +5 -0
  144. data/cookbooks/mu-mongo/metadata.rb +17 -0
  145. data/cookbooks/mu-mongo/recipes/default.rb +149 -0
  146. data/cookbooks/mu-mongo/recipes/yum-update-rule.rb +18 -0
  147. data/cookbooks/mu-mongo/templates/default/mongo_create_openfema_db.js.erb +2 -0
  148. data/cookbooks/mu-mongo/templates/default/mongo_init.js.erb +1 -0
  149. data/cookbooks/mu-mongo/templates/default/mongo_logrotate.erb +14 -0
  150. data/cookbooks/mu-mongo/templates/default/mongo_replset_addnodes.js.erb +6 -0
  151. data/cookbooks/mu-mongo/templates/default/replset_init.js.erb +2 -0
  152. data/cookbooks/mu-openvpn/CHANGELOG.md +13 -0
  153. data/cookbooks/mu-openvpn/LICENSE +37 -0
  154. data/cookbooks/mu-openvpn/README.md +6 -0
  155. data/cookbooks/mu-openvpn/attributes/default.rb +119 -0
  156. data/cookbooks/mu-openvpn/metadata.rb +18 -0
  157. data/cookbooks/mu-openvpn/recipes/default.rb +108 -0
  158. data/cookbooks/mu-openvpn/templates/default/users.json.erb +42 -0
  159. data/cookbooks/mu-php54/CHANGELOG.md +12 -0
  160. data/cookbooks/mu-php54/LICENSE +37 -0
  161. data/cookbooks/mu-php54/README.md +0 -0
  162. data/cookbooks/mu-php54/files/centos/php.ini +1802 -0
  163. data/cookbooks/mu-php54/files/ubuntu/php.ini +1870 -0
  164. data/cookbooks/mu-php54/metadata.rb +21 -0
  165. data/cookbooks/mu-php54/recipes/default.rb +97 -0
  166. data/cookbooks/mu-splunk/CHANGELOG.md +37 -0
  167. data/cookbooks/mu-splunk/LICENSE +37 -0
  168. data/cookbooks/mu-splunk/README.md +451 -0
  169. data/cookbooks/mu-splunk/attributes/default.rb +95 -0
  170. data/cookbooks/mu-splunk/attributes/upgrade.rb +49 -0
  171. data/cookbooks/mu-splunk/definitions/splunk_installer.rb +103 -0
  172. data/cookbooks/mu-splunk/files/default/splunk-nocheck +10 -0
  173. data/cookbooks/mu-splunk/libraries/helpers.rb +72 -0
  174. data/cookbooks/mu-splunk/libraries/splunk_app_provider.rb +156 -0
  175. data/cookbooks/mu-splunk/libraries/splunk_app_resource.rb +43 -0
  176. data/cookbooks/mu-splunk/metadata.json +30 -0
  177. data/cookbooks/mu-splunk/metadata.rb +17 -0
  178. data/cookbooks/mu-splunk/recipes/client.rb +143 -0
  179. data/cookbooks/mu-splunk/recipes/default.rb +31 -0
  180. data/cookbooks/mu-splunk/recipes/disabled.rb +41 -0
  181. data/cookbooks/mu-splunk/recipes/install_forwarder.rb +23 -0
  182. data/cookbooks/mu-splunk/recipes/install_server.rb +23 -0
  183. data/cookbooks/mu-splunk/recipes/server.rb +53 -0
  184. data/cookbooks/mu-splunk/recipes/service.rb +95 -0
  185. data/cookbooks/mu-splunk/recipes/setup_auth.rb +49 -0
  186. data/cookbooks/mu-splunk/recipes/setup_ssl.rb +63 -0
  187. data/cookbooks/mu-splunk/recipes/upgrade.rb +94 -0
  188. data/cookbooks/mu-splunk/recipes/user.rb +34 -0
  189. data/cookbooks/mu-splunk/templates/default/base_logs_unix_inputs.conf.erb +26 -0
  190. data/cookbooks/mu-splunk/templates/default/inputs.conf.erb +13 -0
  191. data/cookbooks/mu-splunk/templates/default/outputs.conf.erb +9 -0
  192. data/cookbooks/mu-splunk/templates/default/splunk-init.erb +74 -0
  193. data/cookbooks/mu-splunk/templates/default/system-web.conf.erb +7 -0
  194. data/cookbooks/mu-tools/CHANGELOG.md +12 -0
  195. data/cookbooks/mu-tools/LICENSE +37 -0
  196. data/cookbooks/mu-tools/README.md +188 -0
  197. data/cookbooks/mu-tools/attributes/default.rb +142 -0
  198. data/cookbooks/mu-tools/attributes/ebs_rolling_snapshots.rb +3 -0
  199. data/cookbooks/mu-tools/files/amazon/etc/freshclam.conf +235 -0
  200. data/cookbooks/mu-tools/files/centos/CentOS-Base.repo +52 -0
  201. data/cookbooks/mu-tools/files/centos/etc/bashrc +93 -0
  202. data/cookbooks/mu-tools/files/centos/etc/freshclam.conf +235 -0
  203. data/cookbooks/mu-tools/files/centos/etc/login.defs +72 -0
  204. data/cookbooks/mu-tools/files/centos/etc/profile +77 -0
  205. data/cookbooks/mu-tools/files/centos/etc/security/limits.conf +57 -0
  206. data/cookbooks/mu-tools/files/centos/etc/sysconfig/init +19 -0
  207. data/cookbooks/mu-tools/files/centos/etc/sysctl.conf +82 -0
  208. data/cookbooks/mu-tools/files/centos-6/README_MU +0 -0
  209. data/cookbooks/mu-tools/files/centos-6/etc/audit/stig.rules +173 -0
  210. data/cookbooks/mu-tools/files/centos-6/etc/bashrc +90 -0
  211. data/cookbooks/mu-tools/files/centos-6/etc/login.defs +70 -0
  212. data/cookbooks/mu-tools/files/centos-6/etc/pam.d/su +12 -0
  213. data/cookbooks/mu-tools/files/centos-6/etc/profile +83 -0
  214. data/cookbooks/mu-tools/files/centos-6/etc/securetty +12 -0
  215. data/cookbooks/mu-tools/files/centos-6/etc/sysconfig/init +30 -0
  216. data/cookbooks/mu-tools/files/centos-6/etc/sysctl.conf +40 -0
  217. data/cookbooks/mu-tools/files/default/Mu_CA.pem +34 -0
  218. data/cookbooks/mu-tools/files/default/PSWindowsUpdate.zip +0 -0
  219. data/cookbooks/mu-tools/files/default/ebs_snapshots.py +123 -0
  220. data/cookbooks/mu-tools/files/default/etc/BANNER +0 -0
  221. data/cookbooks/mu-tools/files/default/etc/BANNER-FEDERAL +19 -0
  222. data/cookbooks/mu-tools/files/default/gpo_no_uac.zip +0 -0
  223. data/cookbooks/mu-tools/files/default/mypol.pp +0 -0
  224. data/cookbooks/mu-tools/files/default/mypol.te +37 -0
  225. data/cookbooks/mu-tools/files/default/nrpe_c7.pp +0 -0
  226. data/cookbooks/mu-tools/files/default/nrpe_c7.te +31 -0
  227. data/cookbooks/mu-tools/files/default/nrpe_check_disk.pp +0 -0
  228. data/cookbooks/mu-tools/files/default/nrpe_check_disk.te +11 -0
  229. data/cookbooks/mu-tools/files/default/nrpe_disk.pp +0 -0
  230. data/cookbooks/mu-tools/files/default/nrpe_disk.te +10 -0
  231. data/cookbooks/mu-tools/files/default/nrpe_file.pp +0 -0
  232. data/cookbooks/mu-tools/files/default/nrpe_file.te +31 -0
  233. data/cookbooks/mu-tools/files/default/ntrights +0 -0
  234. data/cookbooks/mu-tools/files/default/serverclass.conf +18 -0
  235. data/cookbooks/mu-tools/files/default/splunk-apps/base_logs_unix/local/app.conf +1 -0
  236. data/cookbooks/mu-tools/files/default/splunk-apps/base_logs_unix/local/inputs.conf +13 -0
  237. data/cookbooks/mu-tools/files/default/splunk-apps/base_logs_windows/local/app.conf +1 -0
  238. data/cookbooks/mu-tools/files/default/splunk-apps/base_logs_windows/local/inputs.conf +8 -0
  239. data/cookbooks/mu-tools/files/default/sshd_pol.pp +0 -0
  240. data/cookbooks/mu-tools/files/default/sshd_pol.te +32 -0
  241. data/cookbooks/mu-tools/files/redhat/etc/bashrc +93 -0
  242. data/cookbooks/mu-tools/files/redhat/etc/freshclam.conf +235 -0
  243. data/cookbooks/mu-tools/files/redhat/etc/login.defs +72 -0
  244. data/cookbooks/mu-tools/files/redhat/etc/profile +77 -0
  245. data/cookbooks/mu-tools/files/redhat/etc/security/limits.conf +57 -0
  246. data/cookbooks/mu-tools/files/redhat/etc/sysconfig/init +19 -0
  247. data/cookbooks/mu-tools/files/redhat/etc/sysctl.conf +82 -0
  248. data/cookbooks/mu-tools/files/redhat-6/README_MU +0 -0
  249. data/cookbooks/mu-tools/files/redhat-6/etc/audit/stig.rules +173 -0
  250. data/cookbooks/mu-tools/files/redhat-6/etc/bashrc +90 -0
  251. data/cookbooks/mu-tools/files/redhat-6/etc/login.defs +70 -0
  252. data/cookbooks/mu-tools/files/redhat-6/etc/pam.d/su +12 -0
  253. data/cookbooks/mu-tools/files/redhat-6/etc/profile +83 -0
  254. data/cookbooks/mu-tools/files/redhat-6/etc/securetty +12 -0
  255. data/cookbooks/mu-tools/files/redhat-6/etc/sysconfig/init +30 -0
  256. data/cookbooks/mu-tools/files/redhat-6/etc/sysctl.conf +40 -0
  257. data/cookbooks/mu-tools/files/redhat-7.1/etc/freshclam.conf +235 -0
  258. data/cookbooks/mu-tools/files/ubuntu-12.04/etc/bash.bashrc +64 -0
  259. data/cookbooks/mu-tools/files/ubuntu-12.04/etc/common-session +30 -0
  260. data/cookbooks/mu-tools/files/ubuntu-12.04/etc/login.defs +338 -0
  261. data/cookbooks/mu-tools/files/ubuntu-12.04/etc/profile +30 -0
  262. data/cookbooks/mu-tools/files/ubuntu-12.04/etc/security/limits.conf +56 -0
  263. data/cookbooks/mu-tools/files/ubuntu-12.04/etc/sysctl.conf +60 -0
  264. data/cookbooks/mu-tools/libraries/helper.rb +292 -0
  265. data/cookbooks/mu-tools/metadata.rb +28 -0
  266. data/cookbooks/mu-tools/recipes/add_admin_ssh_keys.rb +35 -0
  267. data/cookbooks/mu-tools/recipes/apply_security.rb +440 -0
  268. data/cookbooks/mu-tools/recipes/aws_api.rb +23 -0
  269. data/cookbooks/mu-tools/recipes/base_repositories.rb +31 -0
  270. data/cookbooks/mu-tools/recipes/cisbenchmark.rb +59 -0
  271. data/cookbooks/mu-tools/recipes/clamav.rb +53 -0
  272. data/cookbooks/mu-tools/recipes/cloudinit.rb +58 -0
  273. data/cookbooks/mu-tools/recipes/configure_oracle_tools.rb +81 -0
  274. data/cookbooks/mu-tools/recipes/disable-requiretty.rb +22 -0
  275. data/cookbooks/mu-tools/recipes/ebs_rolling_snapshots.rb +75 -0
  276. data/cookbooks/mu-tools/recipes/efs.rb +70 -0
  277. data/cookbooks/mu-tools/recipes/eks.rb +160 -0
  278. data/cookbooks/mu-tools/recipes/gcloud.rb +98 -0
  279. data/cookbooks/mu-tools/recipes/google_api.rb +25 -0
  280. data/cookbooks/mu-tools/recipes/maldet.rb +67 -0
  281. data/cookbooks/mu-tools/recipes/nagios.rb +19 -0
  282. data/cookbooks/mu-tools/recipes/newclient.rb +23 -0
  283. data/cookbooks/mu-tools/recipes/nrpe.rb +115 -0
  284. data/cookbooks/mu-tools/recipes/python_pip.rb +35 -0
  285. data/cookbooks/mu-tools/recipes/retrieve_application.rb +51 -0
  286. data/cookbooks/mu-tools/recipes/rsyslog.rb +65 -0
  287. data/cookbooks/mu-tools/recipes/set_local_fw.rb +57 -0
  288. data/cookbooks/mu-tools/recipes/set_mu_hostname.rb +81 -0
  289. data/cookbooks/mu-tools/recipes/split_var_partitions.rb +86 -0
  290. data/cookbooks/mu-tools/recipes/splunk-client.rb +69 -0
  291. data/cookbooks/mu-tools/recipes/splunk-server.rb +104 -0
  292. data/cookbooks/mu-tools/recipes/store_inspec_attr.rb +8 -0
  293. data/cookbooks/mu-tools/recipes/updates.rb +96 -0
  294. data/cookbooks/mu-tools/recipes/windows-client.rb +202 -0
  295. data/cookbooks/mu-tools/resources/aws_windows.rb +33 -0
  296. data/cookbooks/mu-tools/resources/disk.rb +88 -0
  297. data/cookbooks/mu-tools/resources/mommacat_request.rb +11 -0
  298. data/cookbooks/mu-tools/resources/scheduled_tasks.rb +29 -0
  299. data/cookbooks/mu-tools/resources/sshd_service.rb +45 -0
  300. data/cookbooks/mu-tools/resources/windows_users.rb +242 -0
  301. data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +168 -0
  302. data/cookbooks/mu-tools/templates/centos-6/sshd_config.erb +212 -0
  303. data/cookbooks/mu-tools/templates/centos-7/sshd_config.erb +215 -0
  304. data/cookbooks/mu-tools/templates/default/0-mu-log-client.conf.erb +13 -0
  305. data/cookbooks/mu-tools/templates/default/conf.maldet.erb +137 -0
  306. data/cookbooks/mu-tools/templates/default/etc_hosts.erb +30 -0
  307. data/cookbooks/mu-tools/templates/default/etc_pamd_password-auth.erb +14 -0
  308. data/cookbooks/mu-tools/templates/default/etc_pamd_system-auth.erb +14 -0
  309. data/cookbooks/mu-tools/templates/default/etc_sysconfig_network.erb +12 -0
  310. data/cookbooks/mu-tools/templates/default/kubeconfig.erb +29 -0
  311. data/cookbooks/mu-tools/templates/default/kubelet.service.erb +35 -0
  312. data/cookbooks/mu-tools/templates/default/maldet_scanall.sh.erb +15 -0
  313. data/cookbooks/mu-tools/templates/default/nrpe.cfg.erb +233 -0
  314. data/cookbooks/mu-tools/templates/redhat-6/sshd_config.erb +213 -0
  315. data/cookbooks/mu-tools/templates/redhat-7/sshd_config.erb +215 -0
  316. data/cookbooks/mu-tools/templates/ubuntu-12.04/sshd_config.erb +146 -0
  317. data/cookbooks/mu-tools/templates/ubuntu-14.04/sshd_config.erb +145 -0
  318. data/cookbooks/mu-tools/templates/windows/Backup.xml.erb +20 -0
  319. data/cookbooks/mu-tools/templates/windows/bkupInfo.xml.erb +1 -0
  320. data/cookbooks/mu-tools/templates/windows/gpreprt.xml.erb +214 -0
  321. data/cookbooks/mu-tools/templates/windows/gptmpl.inf.erb +12 -0
  322. data/cookbooks/mu-tools/templates/windows/manifest.xml.erb +1 -0
  323. data/cookbooks/mu-tools/templates/windows/set_ad_dns_scheduled_task.ps1.erb +6 -0
  324. data/cookbooks/mu-tools/templates/windows/sshd_config.erb +136 -0
  325. data/cookbooks/mu-utility/CHANGELOG.md +12 -0
  326. data/cookbooks/mu-utility/LICENSE +37 -0
  327. data/cookbooks/mu-utility/README.md +6 -0
  328. data/cookbooks/mu-utility/attributes/default.rb +1 -0
  329. data/cookbooks/mu-utility/libraries/matchers.rb +21 -0
  330. data/cookbooks/mu-utility/metadata.rb +16 -0
  331. data/cookbooks/mu-utility/recipes/apt.rb +23 -0
  332. data/cookbooks/mu-utility/recipes/cleanup_image_helper.rb +118 -0
  333. data/cookbooks/mu-utility/recipes/iptables.rb +26 -0
  334. data/cookbooks/mu-utility/recipes/luks.rb +18 -0
  335. data/cookbooks/mu-utility/recipes/nat.rb +104 -0
  336. data/cookbooks/mu-utility/recipes/php.rb +33 -0
  337. data/cookbooks/mu-utility/recipes/rdp_gateway.rb +83 -0
  338. data/cookbooks/mu-utility/recipes/remi.rb +44 -0
  339. data/cookbooks/mu-utility/recipes/vim.rb +26 -0
  340. data/cookbooks/mu-utility/recipes/windows_basics.rb +37 -0
  341. data/cookbooks/mu-utility/recipes/zip.rb +26 -0
  342. data/cookbooks/mu-utility/templates/default/BundleConfig.xml.erb +34 -0
  343. data/cookbooks/mu-utility/templates/default/config.xml.erb +60 -0
  344. data/cookbooks/nagios/Berksfile +8 -0
  345. data/cookbooks/nagios/CHANGELOG.md +589 -0
  346. data/cookbooks/nagios/CONTRIBUTING.md +11 -0
  347. data/cookbooks/nagios/LICENSE +37 -0
  348. data/cookbooks/nagios/README.md +328 -0
  349. data/cookbooks/nagios/TESTING.md +2 -0
  350. data/cookbooks/nagios/attributes/config.rb +171 -0
  351. data/cookbooks/nagios/attributes/default.rb +228 -0
  352. data/cookbooks/nagios/chefignore +102 -0
  353. data/cookbooks/nagios/definitions/command.rb +33 -0
  354. data/cookbooks/nagios/definitions/contact.rb +33 -0
  355. data/cookbooks/nagios/definitions/contactgroup.rb +33 -0
  356. data/cookbooks/nagios/definitions/host.rb +33 -0
  357. data/cookbooks/nagios/definitions/hostdependency.rb +33 -0
  358. data/cookbooks/nagios/definitions/hostescalation.rb +34 -0
  359. data/cookbooks/nagios/definitions/hostgroup.rb +33 -0
  360. data/cookbooks/nagios/definitions/nagios_conf.rb +38 -0
  361. data/cookbooks/nagios/definitions/resource.rb +33 -0
  362. data/cookbooks/nagios/definitions/service.rb +33 -0
  363. data/cookbooks/nagios/definitions/servicedependency.rb +33 -0
  364. data/cookbooks/nagios/definitions/serviceescalation.rb +34 -0
  365. data/cookbooks/nagios/definitions/servicegroup.rb +33 -0
  366. data/cookbooks/nagios/definitions/timeperiod.rb +33 -0
  367. data/cookbooks/nagios/libraries/base.rb +314 -0
  368. data/cookbooks/nagios/libraries/command.rb +91 -0
  369. data/cookbooks/nagios/libraries/contact.rb +230 -0
  370. data/cookbooks/nagios/libraries/contactgroup.rb +112 -0
  371. data/cookbooks/nagios/libraries/custom_option.rb +36 -0
  372. data/cookbooks/nagios/libraries/data_bag_helper.rb +23 -0
  373. data/cookbooks/nagios/libraries/default.rb +90 -0
  374. data/cookbooks/nagios/libraries/host.rb +412 -0
  375. data/cookbooks/nagios/libraries/hostdependency.rb +181 -0
  376. data/cookbooks/nagios/libraries/hostescalation.rb +173 -0
  377. data/cookbooks/nagios/libraries/hostgroup.rb +119 -0
  378. data/cookbooks/nagios/libraries/nagios.rb +282 -0
  379. data/cookbooks/nagios/libraries/resource.rb +59 -0
  380. data/cookbooks/nagios/libraries/service.rb +455 -0
  381. data/cookbooks/nagios/libraries/servicedependency.rb +215 -0
  382. data/cookbooks/nagios/libraries/serviceescalation.rb +195 -0
  383. data/cookbooks/nagios/libraries/servicegroup.rb +144 -0
  384. data/cookbooks/nagios/libraries/timeperiod.rb +160 -0
  385. data/cookbooks/nagios/libraries/users_helper.rb +54 -0
  386. data/cookbooks/nagios/metadata.rb +25 -0
  387. data/cookbooks/nagios/recipes/_load_databag_config.rb +153 -0
  388. data/cookbooks/nagios/recipes/_load_default_config.rb +241 -0
  389. data/cookbooks/nagios/recipes/apache.rb +48 -0
  390. data/cookbooks/nagios/recipes/default.rb +204 -0
  391. data/cookbooks/nagios/recipes/nginx.rb +82 -0
  392. data/cookbooks/nagios/recipes/pagerduty.rb +143 -0
  393. data/cookbooks/nagios/recipes/server_package.rb +40 -0
  394. data/cookbooks/nagios/recipes/server_source.rb +164 -0
  395. data/cookbooks/nagios/templates/default/apache2.conf.erb +96 -0
  396. data/cookbooks/nagios/templates/default/cgi.cfg.erb +266 -0
  397. data/cookbooks/nagios/templates/default/commands.cfg.erb +13 -0
  398. data/cookbooks/nagios/templates/default/contacts.cfg.erb +37 -0
  399. data/cookbooks/nagios/templates/default/hostgroups.cfg.erb +25 -0
  400. data/cookbooks/nagios/templates/default/hosts.cfg.erb +15 -0
  401. data/cookbooks/nagios/templates/default/htpasswd.users.erb +6 -0
  402. data/cookbooks/nagios/templates/default/nagios.cfg.erb +22 -0
  403. data/cookbooks/nagios/templates/default/nginx.conf.erb +62 -0
  404. data/cookbooks/nagios/templates/default/pagerduty.cgi.erb +185 -0
  405. data/cookbooks/nagios/templates/default/resource.cfg.erb +27 -0
  406. data/cookbooks/nagios/templates/default/servicedependencies.cfg.erb +15 -0
  407. data/cookbooks/nagios/templates/default/servicegroups.cfg.erb +14 -0
  408. data/cookbooks/nagios/templates/default/services.cfg.erb +14 -0
  409. data/cookbooks/nagios/templates/default/templates.cfg.erb +31 -0
  410. data/cookbooks/nagios/templates/default/timeperiods.cfg.erb +13 -0
  411. data/cookbooks/s3fs/CHANGELOG.md +13 -0
  412. data/cookbooks/s3fs/LICENSE +37 -0
  413. data/cookbooks/s3fs/README.md +6 -0
  414. data/cookbooks/s3fs/attributes/default.rb +15 -0
  415. data/cookbooks/s3fs/files/default/fuse-2.9.3.zip +0 -0
  416. data/cookbooks/s3fs/metadata.rb +16 -0
  417. data/cookbooks/s3fs/recipes/default.rb +91 -0
  418. data/data_bags/demo/app.json +7 -0
  419. data/data_bags/nagios_services/chef.json +6 -0
  420. data/data_bags/nagios_services/linux_diskspace.json +5 -0
  421. data/data_bags/nagios_services/momma_cat.json +6 -0
  422. data/data_bags/nagios_services/mu-master-memory.json +5 -0
  423. data/data_bags/nagios_services/nagios_ui.json +6 -0
  424. data/data_bags/nagios_services/node_ssh.json +6 -0
  425. data/data_bags/nagios_services/ssh.json +6 -0
  426. data/demo/lambda_test.yaml +29 -0
  427. data/environments/DEV.json +8 -0
  428. data/environments/PROD.json +8 -0
  429. data/environments/dev.json +8 -0
  430. data/environments/development.json +8 -0
  431. data/environments/prod.json +8 -0
  432. data/extras/README.md +1 -0
  433. data/extras/admin-role-binding.yaml +16 -0
  434. data/extras/admin-user.yaml +6 -0
  435. data/extras/aws-auth-cm.yaml.erb +12 -0
  436. data/extras/clean-stock-amis +48 -0
  437. data/extras/git-fix-permissions-hook +12 -0
  438. data/extras/gitlab-eks-helper.sh.erb +20 -0
  439. data/extras/image-generators/README.md +2 -0
  440. data/extras/image-generators/aws/centos6.yaml +18 -0
  441. data/extras/image-generators/aws/centos7-govcloud.yaml +24 -0
  442. data/extras/image-generators/aws/centos7.yaml +17 -0
  443. data/extras/image-generators/aws/rhel7.yaml +17 -0
  444. data/extras/image-generators/aws/win2k12.yaml +16 -0
  445. data/extras/image-generators/aws/win2k16.yaml +16 -0
  446. data/extras/image-generators/aws/windows.yaml +18 -0
  447. data/extras/image-generators/gcp/centos6.yaml +17 -0
  448. data/extras/lambda_waf_domain_blacklist.py +103 -0
  449. data/extras/platform_berksfile_base +50 -0
  450. data/extras/ruby_rpm/build.sh +17 -0
  451. data/extras/ruby_rpm/muby.spec +44 -0
  452. data/extras/vault_tools/README.md +6 -0
  453. data/extras/vault_tools/export_vaults.sh +3 -0
  454. data/extras/vault_tools/recreate_vaults.sh +5 -0
  455. data/extras/vault_tools/test_vaults.sh +5 -0
  456. data/install/README.md +8 -0
  457. data/install/cfn_create_mu_master.json +1034 -0
  458. data/install/chef-server.rb.erb +19 -0
  459. data/install/deprecated-bash-library.sh +1891 -0
  460. data/install/images/Usage.png +0 -0
  461. data/install/installer +71 -0
  462. data/install/jenkinskeys.rb +8 -0
  463. data/install/user-dot-murc.erb +14 -0
  464. data/modules/html.erb +19 -0
  465. data/modules/mommacat.ru +426 -0
  466. data/modules/mu/cleanup.rb +339 -0
  467. data/modules/mu/cloud.rb +1446 -0
  468. data/modules/mu/clouds/README.md +201 -0
  469. data/modules/mu/clouds/aws/alarm.rb +319 -0
  470. data/modules/mu/clouds/aws/cache_cluster.rb +1010 -0
  471. data/modules/mu/clouds/aws/collection.rb +373 -0
  472. data/modules/mu/clouds/aws/container_cluster.rb +667 -0
  473. data/modules/mu/clouds/aws/database.rb +1836 -0
  474. data/modules/mu/clouds/aws/dnszone.rb +911 -0
  475. data/modules/mu/clouds/aws/firewall_rule.rb +641 -0
  476. data/modules/mu/clouds/aws/folder.rb +92 -0
  477. data/modules/mu/clouds/aws/function.rb +349 -0
  478. data/modules/mu/clouds/aws/group.rb +251 -0
  479. data/modules/mu/clouds/aws/loadbalancer.rb +888 -0
  480. data/modules/mu/clouds/aws/log.rb +363 -0
  481. data/modules/mu/clouds/aws/msg_queue.rb +480 -0
  482. data/modules/mu/clouds/aws/notification.rb +139 -0
  483. data/modules/mu/clouds/aws/role.rb +656 -0
  484. data/modules/mu/clouds/aws/search_domain.rb +646 -0
  485. data/modules/mu/clouds/aws/server.rb +2294 -0
  486. data/modules/mu/clouds/aws/server_pool.rb +1388 -0
  487. data/modules/mu/clouds/aws/storage_pool.rb +495 -0
  488. data/modules/mu/clouds/aws/user.rb +382 -0
  489. data/modules/mu/clouds/aws/userdata/README.md +4 -0
  490. data/modules/mu/clouds/aws/userdata/linux.erb +179 -0
  491. data/modules/mu/clouds/aws/userdata/windows.erb +278 -0
  492. data/modules/mu/clouds/aws/vpc.rb +1943 -0
  493. data/modules/mu/clouds/aws.rb +1009 -0
  494. data/modules/mu/clouds/cloudformation/alarm.rb +146 -0
  495. data/modules/mu/clouds/cloudformation/cache_cluster.rb +167 -0
  496. data/modules/mu/clouds/cloudformation/collection.rb +117 -0
  497. data/modules/mu/clouds/cloudformation/database.rb +278 -0
  498. data/modules/mu/clouds/cloudformation/dnszone.rb +274 -0
  499. data/modules/mu/clouds/cloudformation/firewall_rule.rb +308 -0
  500. data/modules/mu/clouds/cloudformation/loadbalancer.rb +193 -0
  501. data/modules/mu/clouds/cloudformation/log.rb +170 -0
  502. data/modules/mu/clouds/cloudformation/server.rb +370 -0
  503. data/modules/mu/clouds/cloudformation/server_pool.rb +279 -0
  504. data/modules/mu/clouds/cloudformation/vpc.rb +322 -0
  505. data/modules/mu/clouds/cloudformation.rb +733 -0
  506. data/modules/mu/clouds/docker.rb +30 -0
  507. data/modules/mu/clouds/google/container_cluster.rb +290 -0
  508. data/modules/mu/clouds/google/database.rb +152 -0
  509. data/modules/mu/clouds/google/firewall_rule.rb +267 -0
  510. data/modules/mu/clouds/google/group.rb +164 -0
  511. data/modules/mu/clouds/google/loadbalancer.rb +479 -0
  512. data/modules/mu/clouds/google/server.rb +1510 -0
  513. data/modules/mu/clouds/google/server_pool.rb +274 -0
  514. data/modules/mu/clouds/google/user.rb +266 -0
  515. data/modules/mu/clouds/google/userdata/README.md +4 -0
  516. data/modules/mu/clouds/google/userdata/linux.erb +137 -0
  517. data/modules/mu/clouds/google/userdata/windows.erb +275 -0
  518. data/modules/mu/clouds/google/vpc.rb +890 -0
  519. data/modules/mu/clouds/google.rb +811 -0
  520. data/modules/mu/config/README.md +11 -0
  521. data/modules/mu/config/alarm.rb +271 -0
  522. data/modules/mu/config/cache_cluster.rb +172 -0
  523. data/modules/mu/config/collection.rb +87 -0
  524. data/modules/mu/config/container_cluster.rb +103 -0
  525. data/modules/mu/config/container_cluster.yml +36 -0
  526. data/modules/mu/config/database.rb +458 -0
  527. data/modules/mu/config/database.yml +26 -0
  528. data/modules/mu/config/dnszone.rb +327 -0
  529. data/modules/mu/config/firewall_rule.rb +118 -0
  530. data/modules/mu/config/folder.rb +70 -0
  531. data/modules/mu/config/function.rb +140 -0
  532. data/modules/mu/config/group.rb +64 -0
  533. data/modules/mu/config/loadbalancer.rb +482 -0
  534. data/modules/mu/config/log.rb +47 -0
  535. data/modules/mu/config/log.yml +6 -0
  536. data/modules/mu/config/msg_queue.rb +47 -0
  537. data/modules/mu/config/msg_queue.yml +9 -0
  538. data/modules/mu/config/notification.rb +44 -0
  539. data/modules/mu/config/project.rb +71 -0
  540. data/modules/mu/config/role.rb +102 -0
  541. data/modules/mu/config/search_domain.rb +61 -0
  542. data/modules/mu/config/search_domain.yml +25 -0
  543. data/modules/mu/config/server.rb +587 -0
  544. data/modules/mu/config/server.yml +8 -0
  545. data/modules/mu/config/server_pool.rb +216 -0
  546. data/modules/mu/config/server_pool.yml +71 -0
  547. data/modules/mu/config/storage_pool.rb +145 -0
  548. data/modules/mu/config/user.rb +78 -0
  549. data/modules/mu/config/vpc.rb +743 -0
  550. data/modules/mu/config/vpc.yml +6 -0
  551. data/modules/mu/config.rb +2000 -0
  552. data/modules/mu/defaults/README.md +2 -0
  553. data/modules/mu/defaults/amazon_images.yaml +121 -0
  554. data/modules/mu/defaults/google_images.yaml +16 -0
  555. data/modules/mu/deploy.rb +686 -0
  556. data/modules/mu/groomer.rb +123 -0
  557. data/modules/mu/groomers/README.md +58 -0
  558. data/modules/mu/groomers/chef.rb +1024 -0
  559. data/modules/mu/kittens.rb +11319 -0
  560. data/modules/mu/logger.rb +208 -0
  561. data/modules/mu/master/README.md +27 -0
  562. data/modules/mu/master/chef.rb +471 -0
  563. data/modules/mu/master/ldap.rb +1005 -0
  564. data/modules/mu/master.rb +415 -0
  565. data/modules/mu/mommacat.rb +2703 -0
  566. data/modules/mu-load-config.rb +1 -0
  567. data/modules/mu.rb +724 -0
  568. data/modules/scratchpad.erb +1 -0
  569. data/modules/tests/super_complex_bok.yml +41 -0
  570. data/modules/tests/super_simple_bok.yml +40 -0
  571. data/mu.gemspec +62 -0
  572. data/roles/demo-dbservice-configure.json +19 -0
  573. data/roles/demo-portal-configure.json +19 -0
  574. data/roles/mu-master-jenkins.json +24 -0
  575. data/roles/mu-master-nagios-only.json +13 -0
  576. data/roles/mu-master.json +12 -0
  577. data/roles/mu-node.json +19 -0
  578. data/roles/mu-splunk-server.json +13 -0
  579. data/roles/mu-splunk.json +13 -0
  580. data/test/clean_up.py +25 -0
  581. data/test/demo-test-profile/README.md +3 -0
  582. data/test/demo-test-profile/controls/flask.rb +84 -0
  583. data/test/demo-test-profile/inspec.lock +7 -0
  584. data/test/demo-test-profile/inspec.yml +11 -0
  585. data/test/etco-test-profile/README.md +3 -0
  586. data/test/etco-test-profile/controls/all-in-one.rb +182 -0
  587. data/test/etco-test-profile/inspec.lock +7 -0
  588. data/test/etco-test-profile/inspec.yml +11 -0
  589. data/test/exec_inspec.py +246 -0
  590. data/test/exec_mu_install.py +241 -0
  591. data/test/exec_retry.py +44 -0
  592. data/test/mu-master-test/README.md +3 -0
  593. data/test/mu-master-test/controls/all_in_one.rb +557 -0
  594. data/test/mu-master-test/inspec.lock +3 -0
  595. data/test/mu-master-test/inspec.yml +11 -0
  596. data/test/mu-tools-test/README.md +3 -0
  597. data/test/mu-tools-test/controls/base.rb +265 -0
  598. data/test/mu-tools-test/inspec.lock +3 -0
  599. data/test/mu-tools-test/inspec.yml +8 -0
  600. data/test/simple-server-php-test/README.md +3 -0
  601. data/test/simple-server-php-test/controls/apachephp.rb +25 -0
  602. data/test/simple-server-php-test/controls/example.rb +19 -0
  603. data/test/simple-server-php-test/inspec.lock +7 -0
  604. data/test/simple-server-php-test/inspec.yml +12 -0
  605. data/test/simple-server-rails-test/README.md +3 -0
  606. data/test/simple-server-rails-test/controls/rails.rb +188 -0
  607. data/test/simple-server-rails-test/inspec.lock +7 -0
  608. data/test/simple-server-rails-test/inspec.yml +11 -0
  609. data/test/simple-windows-test/README.md +3 -0
  610. data/test/simple-windows-test/controls/windows.rb +20 -0
  611. data/test/simple-windows-test/inspec.lock +7 -0
  612. data/test/simple-windows-test/inspec.yml +11 -0
  613. data/test/smoke_test.rb +75 -0
  614. data/test/wordpress-test/README.md +3 -0
  615. data/test/wordpress-test/controls/wordpress.rb +97 -0
  616. data/test/wordpress-test/inspec.lock +7 -0
  617. data/test/wordpress-test/inspec.yml +11 -0
  618. metadata +979 -0
data/bin/mu-configure ADDED
@@ -0,0 +1,1133 @@
1
+ #!/usr/local/ruby-current/bin/ruby
2
+ # Copyright:: Copyright (c) 2017 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 'optimist'
17
+ require 'simple-password-gen'
18
+ require 'socket'
19
+ require 'open-uri'
20
+ require 'colorize'
21
+ require 'timeout'
22
+ require 'etc'
23
+ require 'aws-sdk-core'
24
+ require 'json'
25
+ require 'pp'
26
+ require 'readline'
27
+ require 'fileutils'
28
+ require 'erb'
29
+ require 'tmpdir'
30
+
31
+ GIT_PATTERN = /(((git|ssh|http(s)?)|(git@[\w\.]+))(:(\/\/)?))?([\w\.@\:\/\-~]+)(\.git)?(\/)?/
32
+
33
+ # Top-level keys in $MU_CFG for which we'll provide interactive, menu-driven
34
+ # configuration.
35
+ $CONFIGURABLES = {
36
+ "public_address" => {
37
+ "title" => "Public Address",
38
+ "desc" => "IP address or hostname",
39
+ "required" => true,
40
+ "rootonly" => true,
41
+ "pattern" => /^(localhost|127\.0\.0\.1|#{Socket.gethostname})$/,
42
+ "negate_pattern" => true,
43
+ "changes" => ["389ds", "chef-server", "chefrun", "chefcerts"]
44
+ },
45
+ "mu_admin_email" => {
46
+ "title" => "Admin Email",
47
+ "desc" => "Administative contact email",
48
+ "pattern" => /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i,
49
+ "required" => true,
50
+ "rootonly" => true,
51
+ "changes" => ["mu-user", "chefrun"]
52
+ },
53
+ "mu_admin_name" => {
54
+ "title" => "Admin Name",
55
+ "desc" => "Administative contact's full name",
56
+ "default" => "Mu Administrator",
57
+ "rootonly" => true,
58
+ "changes" => ["mu-user", "chefrun"]
59
+ },
60
+ "hostname" => {
61
+ "title" => "Local Hostname",
62
+ "pattern" => /^[a-z0-9\-_]+$/i,
63
+ "required" => true,
64
+ "rootonly" => true,
65
+ "desc" => "The local system's value for HOSTNAME",
66
+ "changes" => ["chefrun", "hostname"]
67
+ },
68
+ "banner" => {
69
+ "title" => "Banner",
70
+ "desc" => "Login banner, displayed in various locations",
71
+ "rootonly" => true,
72
+ "changes" => ["chefrun"]
73
+ },
74
+ "mu_repository" => {
75
+ "title" => "Mu Tools Repository",
76
+ "desc" => "Source repository for Mu tools",
77
+ "pattern" => GIT_PATTERN,
78
+ "callback" => :cloneGitRepo,
79
+ "changes" => ["chefartifacts", "chefrun"],
80
+ "default" => "git://github.com/cloudamatic/mu.git"
81
+ },
82
+ "repos" => {
83
+ "title" => "Additional Repositories",
84
+ "desc" => "Optional platform repositories, as a Git URL or Github repo name (ex: eGT-Labs/fema_platform.git)",
85
+ "pattern" => GIT_PATTERN,
86
+ "callback" => :cloneGitRepo,
87
+ "changes" => ["chefartifacts", "chefrun"],
88
+ "array" => true,
89
+ "default" => ['https://github.com/cloudamatic/mu_demo_platform']
90
+ },
91
+ "master_runlist_extras" => {
92
+ "title" => "Mu Master Runlist Extras",
93
+ "desc" => "Optional extra Chef roles or recipes to invoke when running chef-client on this Master (ex: recipe[mycookbook::mumaster])",
94
+ "array" => true,
95
+ "rootonly" => true,
96
+ "changes" => ["chefrun"]
97
+ },
98
+ "allow_invade_foreign_vpcs" => {
99
+ "title" => "Invade Foreign VPCs?",
100
+ "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.",
101
+ "boolean" => true
102
+ },
103
+ "jenkins" => {
104
+ "title" => "Jenkins Continuous Integration",
105
+ "rootonly" => true,
106
+ "subtree" => {
107
+ "enable" => {
108
+ "title" => "Enable Jenkins",
109
+ "desc" => "Enable Jenkins, with UI web-accessible at /jenkins.",
110
+ "default" => false,
111
+ "boolean" => true,
112
+ "changes" => ["chefrun"]
113
+ },
114
+ "admin_email" => {
115
+ "title" => "Jenkins Admin Email",
116
+ "desc" => "Administative contact email for Jenkins",
117
+ "pattern" => /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i,
118
+ "changes" => ["chefrun"]
119
+ },
120
+ "admin_user" => {
121
+ "title" => "Jenkins admin username",
122
+ "desc" => "The name of a Mu user who will serve as the Jenkins admin.",
123
+ "default" => "jenkins",
124
+ "changes" => ["chefrun"]
125
+ }
126
+ }
127
+ },
128
+ "aws" => {
129
+ "title" => "Amazon Web Services",
130
+ "subtree" => {
131
+ "account_number" => {
132
+ "title" => "Account Number",
133
+ "desc" => "Account number for the Amazon Web Services account which we administer",
134
+ "pattern" => /^\d+$/
135
+ },
136
+ "region" => {
137
+ "title" => "Default Region",
138
+ "desc" => "Default Amazon Web Services region in which we operate"
139
+ },
140
+ "access_key" => {
141
+ "title" => "Access Key",
142
+ "desc" => "Credentials used for accessing the AWS API (looks like: AKIAINWLOOAA24PBRBZA)",
143
+ "pattern" => /^[a-z0-9]+$/i
144
+ },
145
+ "access_secret" => {
146
+ "title" => "Access Secret",
147
+ "desc" => "Credentials used for accessing the AWS API (looks like: +Z16iRP9QAq7EcjHINyEMs3oR7A76QpfaSgCBogp)"
148
+ },
149
+ "log_bucket_name" => {
150
+ "title" => "Log and Secret Bucket Name",
151
+ "desc" => "S3 bucket into which we'll synchronize deploy secrets, and if we're hosted in AWS, collected system logs",
152
+ "changes" => ["chefrun"]
153
+ }
154
+ }
155
+ },
156
+ "google" => {
157
+ "title" => "Google Cloud Platform",
158
+ "subtree" => {
159
+ "project" => {
160
+ "title" => "Default Project",
161
+ "desc" => "Default Google Cloud Platform project in which we operate and deploy. 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"
162
+ },
163
+ "credentials" => {
164
+ "title" => "Credentials Vault:Item",
165
+ "desc" => "A vault and item from which to retrieve the JSON-formatted Service Account credentials for our GCP 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 "
166
+ },
167
+ "region" => {
168
+ "title" => "Default Region",
169
+ "desc" => "Default Google Cloud Platform region in which we operate and deploy",
170
+ "default" => "us-east4"
171
+ },
172
+ "log_bucket_name" => {
173
+ "title" => "Log and Secret Bucket Name",
174
+ "desc" => "Cloud Storage bucket into which we'll synchronize deploy secrets, and if we're hosted in GCP, collected system logs",
175
+ "changes" => ["chefrun"]
176
+ }
177
+ }
178
+ }
179
+ }
180
+
181
+ AMROOT = Process.uid == 0
182
+ HOMEDIR = Etc.getpwuid(Process.uid).dir
183
+
184
+ $opts = Optimist::options do
185
+ banner <<-EOS
186
+ EOS
187
+ required = []
188
+ opt :noninteractive, "Skip menu-based configuration prompts. If there is no existing configuration, the following flags are required: #{required.map{|x|"--"+x}.join(", ")}", :require => false, :default => false, :type => :boolean
189
+ $CONFIGURABLES.each_pair { |key, data|
190
+ next if !AMROOT and data['rootonly']
191
+ if data.has_key?("subtree")
192
+ data["subtree"].each_pair { |subkey, subdata|
193
+ next if !AMROOT and subdata['rootonly']
194
+ subdata['cli-opt'] = (key+"-"+subkey).gsub(/_/, "-")
195
+ opt (key+"-"+subkey).to_sym, subdata["desc"], :require => false, :type => (subdata["boolean"] ? :boolean : :string)
196
+ required << subdata['cli-opt'] if subdata['required']
197
+ }
198
+ elsif data["array"]
199
+ data['cli-opt'] = key.gsub(/_/, "-")
200
+ opt key.to_sym, data["desc"], :require => false, :type => (data["boolean"] ? :booleans : :strings)
201
+ required << data['cli-opt'] if data['required']
202
+ else
203
+ data['cli-opt'] = key.gsub(/_/, "-")
204
+ opt key.to_sym, data["desc"], :require => false, :type => (data["boolean"] ? :boolean : :string)
205
+ required << data['cli-opt'] if data['required']
206
+ end
207
+ }
208
+
209
+ opt :force, "Run all rebuild actions, whether or not our configuration is changed.", :require => false, :default => false, :type => :boolean if AMROOT
210
+ opt :ssh_keys, "One or more paths to SSH private keys, which we can try to use for SSH-based Git clone operations", :require => false, :type => :strings
211
+ end
212
+
213
+ if ENV.has_key?("MU_INSTALLDIR")
214
+ MU_BASE = ENV["MU_INSTALLDIR"]
215
+ else
216
+ MU_BASE = "/opt/mu"
217
+ end
218
+
219
+ $INITIALIZE = (!File.size?("#{MU_BASE}/etc/mu.yaml") or $opts[:force])
220
+ $HAVE_GLOBAL_CONFIG = File.size?("#{MU_BASE}/etc/mu.yaml")
221
+ if !AMROOT and ($INITIALIZE or !$HAVE_GLOBAL_CONFIG)
222
+ puts "Global configuration has not been initialized or is missing. Must run as root to correct."
223
+ exit 1
224
+ end
225
+ if !$HAVE_GLOBAL_CONFIG and $opts[:noninteractive] and (!$opts[:public_address] or !$opts[:mu_admin_email])
226
+ puts "Specify --public-address and --mu-admin-email on new non-interactive configs"
227
+ exit 1
228
+ end
229
+
230
+ $IN_AWS = false
231
+ begin
232
+ Timeout.timeout(2) do
233
+ instance_id = open("http://169.254.169.254/latest/meta-data/instance-id").read
234
+ $IN_AWS = true if !instance_id.nil? and instance_id.size > 0
235
+ end
236
+ rescue OpenURI::HTTPError, Timeout::Error, SocketError, Errno::ENETUNREACH
237
+ end
238
+ $IN_GOOGLE = false
239
+ begin
240
+ Timeout.timeout(2) do
241
+ instance_id = open(
242
+ "http://metadata.google.internal/computeMetadata/v1/instance/name",
243
+ "Metadata-Flavor" => "Google"
244
+ ).read
245
+ $IN_GOOGLE = true if !instance_id.nil? and instance_id.size > 0
246
+ end
247
+ rescue OpenURI::HTTPError, Timeout::Error, SocketError, Errno::ENETUNREACH
248
+ end
249
+
250
+
251
+ KNIFE_TEMPLATE = "log_level :info
252
+ log_location STDOUT
253
+ node_name '<%= chefuser %>'
254
+ client_key '<%= MU_BASE %>/var/users/<%= user %>/<%= chefuser %>.user.key'
255
+ validation_client_name 'mu-validator'
256
+ validation_key '<%= MU_BASE %>/var/orgs/<%= user %>/<%= chefuser %>.org.key'
257
+ chef_server_url 'https://<%= MU.mu_public_addr %>:7443/organizations/<%= chefuser %>'
258
+ chef_server_root 'https://<%= MU.mu_public_addr %>:7443/organizations/<%= chefuser %>'
259
+ syntax_check_cache_path '<%= HOMEDIR %>/.chef/syntax_check_cache'
260
+ cookbook_path [ '<%= HOMEDIR %>/.chef/cookbooks', '<%= HOMEDIR %>/.chef/site_cookbooks' ]
261
+ <% if $MU_CFG.has_key?('ssl') and $MU_CFG['ssl'].has_key?('chain') %>
262
+ ssl_ca_path '<%= File.dirname($MU_CFG['ssl']['chain']) %>'
263
+ ssl_ca_file '<%= File.basename($MU_CFG['ssl']['chain']) %>'
264
+ <% end %>
265
+ knife[:vault_mode] = 'client'
266
+ knife[:vault_admins] = ['<%= chefuser %>']"
267
+
268
+ CLIENT_TEMPLATE = "chef_server_url 'https://<%= MU.mu_public_addr %>:7443/organizations/<%= user %>'
269
+ validation_client_name 'mu-validator'
270
+ log_location STDOUT
271
+ node_name 'MU-MASTER'
272
+ verify_api_cert false
273
+ ssl_verify_mode :verify_none
274
+ "
275
+
276
+ PIVOTAL_TEMPLATE = "node_name 'pivotal'
277
+ chef_server_url 'https://<%= MU.mu_public_addr %>:7443'
278
+ chef_server_root 'https://<%= MU.mu_public_addr %>:7443'
279
+ no_proxy '<%= MU.mu_public_addr %>'
280
+ client_key '/etc/opscode/pivotal.pem'
281
+ ssl_verify_mode :verify_none
282
+ "
283
+
284
+ $CHANGES = []
285
+
286
+
287
+ $MENU_MAP = {}
288
+ def assignMenuEntries
289
+ count = 1
290
+ $CONFIGURABLES.each_pair { |key, data|
291
+ next if !AMROOT and data['rootonly']
292
+ if data.has_key?("subtree")
293
+ letters = ("a".."z").to_a
294
+ lettercount = 0
295
+ data["subtree"].each_pair { |subkey, subdata|
296
+ next if !AMROOT and subdata['rootonly']
297
+ $CONFIGURABLES[key]["subtree"][subkey]["menu"] = count.to_s+letters[lettercount]
298
+ $MENU_MAP[count.to_s+letters[lettercount]] = $CONFIGURABLES[key]["subtree"][subkey]
299
+ lettercount = lettercount + 1
300
+ }
301
+ end
302
+ $MENU_MAP[count.to_s] = $CONFIGURABLES[key]
303
+ $CONFIGURABLES[key]["menu"] = count.to_s
304
+ count = count + 1
305
+ }
306
+ $MENU_MAP.freeze
307
+ end
308
+
309
+ def trySSHKeyWithGit(repo, keypath = nil)
310
+ cfgbackup = nil
311
+ deletekey = false
312
+ repo.match(/^([^@]+?)@([^:]+?):/)
313
+ ssh_user = Regexp.last_match(1)
314
+ ssh_host = Regexp.last_match(2)
315
+ if keypath.nil?
316
+ response = nil
317
+ puts "Would you like to provide a private ssh key for #{repo} and try again?"
318
+ begin
319
+ response = Readline.readline("Y/N> ".bold, false)
320
+ end while !response and !response.match(/^(y|n)$/i)
321
+ if response == "y" or response == "Y"
322
+ Dir.mkdir("#{HOMEDIR}/.ssh", 0700) if !Dir.exists?("#{HOMEDIR}/.ssh")
323
+ keynamestr = repo.gsub(/[^a-z0-9\-]/i, "-") + Process.pid.to_s
324
+ keypath = "#{HOMEDIR}/.ssh/#{keynamestr}"
325
+ puts "Paste a complete SSH private key for #{ssh_user.bold}@#{ssh_host.bold} below, then ^D"
326
+ system("cat > #{keypath}")
327
+ File.chmod(0600, keypath)
328
+ puts "Key saved to "+keypath.bold
329
+ deletekey = true
330
+ else
331
+ return false
332
+ end
333
+ end
334
+
335
+ if File.exists?("#{HOMEDIR}/.ssh/config")
336
+ FileUtils.cp("#{HOMEDIR}/.ssh/config", "#{HOMEDIR}/.ssh/config.bak.#{Process.pid.to_s}")
337
+ cfgbackup = "#{HOMEDIR}/.ssh/config.bak.#{Process.pid.to_s}"
338
+ end
339
+ File.open("#{HOMEDIR}/.ssh/config", "a", 0600){ |f|
340
+ f.puts "Host "+ssh_host
341
+ f.puts " User "+ssh_user
342
+ f.puts " IdentityFile "+keypath
343
+ f.puts " StrictHostKeyChecking no"
344
+ }
345
+
346
+ puts "/usr/bin/git clone #{repo}"
347
+ output = %x{/usr/bin/git clone #{repo} 2>&1}
348
+ if $?.exitstatus == 0
349
+ puts "Successfully cloned #{repo}".green.on_black
350
+ return true
351
+ else
352
+ puts output.red.on_black
353
+ if cfgbackup
354
+ puts "Restoring #{HOMEDIR}/.ssh/config"
355
+ File.rename(cfgbackup, "#{HOMEDIR}/.ssh/config")
356
+ end
357
+ if deletekey
358
+ puts "Removing #{keypath}"
359
+ File.unlink(keypath)
360
+ end
361
+ end
362
+ return false
363
+ end
364
+
365
+ def cloneGitRepo(repo)
366
+ puts "Testing ability to check out Git repository #{repo.bold}"
367
+ fullrepo = repo
368
+ if !repo.match(/@|:\/\//) # we try ssh first
369
+ fullrepo = "git@github.com:"+repo
370
+ puts "Doesn't look like a full URL, trying SSH to #{fullrepo}"
371
+ end
372
+ cwd = Dir.pwd
373
+ Dir.mktmpdir("mu-git-test-") { |dir|
374
+ Dir.chdir(dir)
375
+ puts "/usr/bin/git clone #{fullrepo}"
376
+ output = %x{/usr/bin/git clone #{fullrepo} 2>&1}
377
+ if $?.exitstatus == 0
378
+ puts "Successfully cloned #{fullrepo}".green.on_black
379
+ Dir.chdir(cwd)
380
+ return fullrepo
381
+ elsif $?.exitstatus != 0 and output.match(/permission denied/i)
382
+ puts ""
383
+ puts output.red.on_black
384
+ if $opts[:ssh_keys_given]
385
+ $opts[:ssh_keys].each { |keypath|
386
+ if trySSHKeyWithGit(fullrepo, keypath)
387
+ Dir.chdir(cwd)
388
+ return fullrepo
389
+ end
390
+ }
391
+ end
392
+ if !$opts[:noninteractive]
393
+ if trySSHKeyWithGit(fullrepo)
394
+ Dir.chdir(cwd)
395
+ return fullrepo
396
+ end
397
+ end
398
+ end
399
+ if !repo.match(/@|:\/\//)
400
+ fullrepo = "git://github.com/"+repo
401
+ puts ""
402
+ puts "No luck there, trying #{fullrepo}".bold
403
+ puts "/usr/bin/git clone #{fullrepo}"
404
+ output = %x{/usr/bin/git clone #{fullrepo} 2>&1}
405
+ if $?.exitstatus == 0
406
+ puts "Successfully cloned #{fullrepo}".green.on_black
407
+ Dir.chdir(cwd)
408
+ return fullrepo
409
+ else
410
+ puts output.red.on_black
411
+ fullrepo = "https://github.com/"+repo
412
+ puts "Final attempt, trying #{fullrepo}"
413
+ puts "/usr/bin/git clone #{fullrepo}"
414
+ output = %x{/usr/bin/git clone #{fullrepo} 2>&1}
415
+ if $?.exitstatus == 0
416
+ puts "Successfully cloned #{fullrepo}".green.on_black
417
+ Dir.chdir(cwd)
418
+ return fullrepo
419
+ else
420
+ puts output.red.on_black
421
+ end
422
+ end
423
+ else
424
+ puts "No other methods I can think to try, giving up on #{repo.bold}".red.on_black
425
+ end
426
+ }
427
+ Dir.chdir(cwd)
428
+ nil
429
+ end
430
+
431
+ # Rustle up some sensible default values, if this is our first time
432
+ def setDefaults
433
+ ips = []
434
+ if $IN_AWS
435
+ ["public-ipv4", "local-ipv4"].each { |addr|
436
+ begin
437
+ Timeout.timeout(2) do
438
+ ip = open("http://169.254.169.254/latest/meta-data/#{addr}").read
439
+ ips << ip if !ip.nil? and ip.size > 0
440
+ end
441
+ rescue OpenURI::HTTPError, Timeout::Error, SocketError
442
+ # these are ok to ignore
443
+ end
444
+ }
445
+ elsif $IN_GOOGLE
446
+ base_url = "http://metadata.google.internal/computeMetadata/v1"
447
+ begin
448
+ Timeout.timeout(2) do
449
+ # TODO iterate across multiple interfaces/access-configs
450
+ ip = open("#{base_url}/instance/network-interfaces/0/ip", "Metadata-Flavor" => "Google").read
451
+ ips << ip if !ip.nil? and ip.size > 0
452
+ ip = open("#{base_url}/instance/network-interfaces/0/access-configs/0/external-ip", "Metadata-Flavor" => "Google").read
453
+ ips << ip if !ip.nil? and ip.size > 0
454
+ end
455
+ rescue OpenURI::HTTPError, Timeout::Error, SocketError => e
456
+ # This is fairly normal, just handle it gracefully
457
+ end
458
+ end
459
+
460
+ 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 })
461
+
462
+ $CONFIGURABLES["allow_invade_foreign_vpcs"]["default"] = false
463
+ $CONFIGURABLES["public_address"]["default"] = ips.first
464
+ $CONFIGURABLES["hostname"]["default"] = Socket.gethostname
465
+ $CONFIGURABLES["banner"]["default"] = "Mu Master at #{$CONFIGURABLES["public_address"]["default"]}"
466
+ if $CONFIGURABLES["mu_admin_email"]["value"]
467
+ $CONFIGURABLES["jenkins"]["subtree"]["admin_email"]["default"] = $CONFIGURABLES["mu_admin_email"]["value"]
468
+ end
469
+ if $IN_AWS
470
+ aws = JSON.parse(open("http://169.254.169.254/latest/dynamic/instance-identity/document").read)
471
+ iam = nil
472
+ begin
473
+ iam = open("http://169.254.169.254/latest/meta-data/iam/security-credentials").read
474
+ rescue OpenURI::HTTPError, SocketError
475
+ end
476
+ $CONFIGURABLES["aws"]["subtree"]["account_number"]["default"] = aws["accountId"]
477
+ $CONFIGURABLES["aws"]["subtree"]["region"]["default"] = aws["region"]
478
+ if iam and iam.size > 0
479
+ # XXX can we think of a good way to test our permission set?
480
+ $CONFIGURABLES["aws"]["subtree"]["access_key"]["desc"] = $CONFIGURABLES["aws"]["subtree"]["access_key"]["desc"] + ". Not necessary if IAM Profile #{iam.bold} has sufficient API access."
481
+ $CONFIGURABLES["aws"]["subtree"]["access_secret"]["desc"] = $CONFIGURABLES["aws"]["subtree"]["access_key"]["desc"] + ". Not necessary if IAM Profile #{iam.bold} has sufficient API access."
482
+ end
483
+ end
484
+ $CONFIGURABLES["aws"]["subtree"]["log_bucket_name"]["default"] = $CONFIGURABLES["hostname"]["default"]
485
+ $CONFIGURABLES["google"]["subtree"]["log_bucket_name"]["default"] = $CONFIGURABLES["hostname"]["default"]
486
+ end
487
+
488
+
489
+ def runValueCallback(desc, val)
490
+ if desc['array']
491
+ if desc["callback"]
492
+ newval = []
493
+ val.each { |v|
494
+ v = send(desc["callback"].to_sym, v)
495
+ newval << v if !v.nil?
496
+ }
497
+ val = newval
498
+ end
499
+ elsif desc["callback"]
500
+ val = send(desc["callback"].to_sym, val)
501
+ end
502
+ val
503
+ end
504
+
505
+ def importCLIValues
506
+ $CONFIGURABLES.each_pair { |key, data|
507
+ next if !AMROOT and data['rootonly']
508
+ if data.has_key?("subtree")
509
+ data["subtree"].each_pair { |subkey, subdata|
510
+ next if !AMROOT and subdata['rootonly']
511
+ if $opts[(subdata['cli-opt'].gsub(/-/, "_")+"_given").to_sym]
512
+ newval = runValueCallback(subdata, $opts[subdata['cli-opt'].gsub(/-/, "_").to_sym])
513
+ subdata["value"] = newval if !newval.nil?
514
+ $CHANGES.concat(subdata['changes']) if subdata['changes']
515
+ end
516
+ }
517
+ else
518
+ if $opts[(data['cli-opt'].gsub(/-/, "_")+"_given").to_sym]
519
+ newval = runValueCallback(data, $opts[data['cli-opt'].gsub(/-/, "_").to_sym])
520
+ data["value"] = newval if !newval.nil?
521
+ $CHANGES.concat(data['changes']) if data['changes']
522
+ end
523
+ end
524
+ }
525
+ end
526
+
527
+ # Load values from our existing configuration into the $CONFIGURABLES hash
528
+ def importCurrentValues
529
+ require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
530
+ $CONFIGURABLES.each_key { |key|
531
+ next if !$MU_CFG.has_key?(key)
532
+ if $CONFIGURABLES[key].has_key?("subtree")
533
+ # It's a sub-tree. I'm too lazy to write a recursive thing for this, just
534
+ # cover the simple case that we actually care about for now.
535
+ $CONFIGURABLES[key]["subtree"].keys.each { |subkey|
536
+ next if !$MU_CFG[key].has_key?(subkey)
537
+ $CONFIGURABLES[key]["subtree"][subkey]["value"] = $MU_CFG[key][subkey]
538
+ }
539
+ else
540
+ $CONFIGURABLES[key]["value"] = $MU_CFG[key]
541
+ end
542
+ }
543
+ end
544
+
545
+ def printVal(data)
546
+ valid = true
547
+ valid = validate(data["value"], data, false) if data["value"]
548
+ if !valid
549
+ print " "+data["value"].to_s.red.on_black
550
+ print " (consider default of #{data["default"].to_s.bold})" if data["default"]
551
+ elsif !data["value"].nil?
552
+ print " - "+data["value"].to_s.green.on_black
553
+ elsif data["required"]
554
+ print " - "+"REQUIRED".red.on_black
555
+ elsif !data["default"].nil?
556
+ print " - "+data["default"].to_s.yellow.on_black+" (DEFAULT)"
557
+ end
558
+ end
559
+
560
+ # Converts the current $CONFIGURABLES object to a Hash suitable for merging
561
+ # with $MU_CFG.
562
+ def setConfigTree
563
+ cfg = {}
564
+ $CONFIGURABLES.each_pair { |key, data|
565
+ next if !AMROOT and data['rootonly']
566
+ if data.has_key?("subtree")
567
+ data["subtree"].each_pair { |subkey, subdata|
568
+ next if !AMROOT and subdata['rootonly']
569
+ if !subdata["value"].nil?
570
+ cfg[key] ||= {}
571
+ cfg[key][subkey] = subdata["value"]
572
+ elsif !subdata["default"].nil? and !$HAVE_GLOBAL_CONFIG or ($MU_CFG and (!$MU_CFG[key] or !$MU_CFG[key][subkey]))
573
+ cfg[key] ||= {}
574
+ cfg[key][subkey] = subdata["default"]
575
+ end
576
+ }
577
+ elsif !data["value"].nil?
578
+ cfg[key] = data["value"]
579
+ elsif !data["default"].nil? and !$HAVE_GLOBAL_CONFIG or ($MU_CFG and !$MU_CFG[key])
580
+ cfg[key] = data["default"]
581
+ end
582
+ }
583
+ cfg
584
+ end
585
+
586
+ def displayCurrentOpts
587
+ count = 1
588
+ optlist = []
589
+ $CONFIGURABLES.each_pair { |key, data|
590
+ next if !AMROOT and data['rootonly']
591
+ print data["menu"].bold+") "+data["title"]
592
+ if data.has_key?("subtree")
593
+ puts ""
594
+ data["subtree"].each_pair { |subkey, subdata|
595
+ next if !AMROOT and subdata['rootonly']
596
+ print " "+subdata["menu"].bold+". "+subdata["title"]
597
+ printVal(subdata)
598
+ puts ""
599
+ }
600
+ else
601
+ printVal(data)
602
+ puts ""
603
+ end
604
+ count = count + 1
605
+ }
606
+ optlist
607
+ end
608
+
609
+ ###############################################################################
610
+
611
+ trap("INT"){ puts "" ; exit }
612
+ importCurrentValues if !$INITIALIZE or $HAVE_GLOBAL_CONFIG
613
+ importCLIValues
614
+ setDefaults
615
+ assignMenuEntries # populates and freezes $MENU_MAP
616
+
617
+ def ask(desc)
618
+ puts ""
619
+ puts (desc['required'] ? "REQUIRED".red.on_black : "OPTIONAL".yellow.on_black)+" - "+desc["desc"]
620
+ puts "Enter one or more values, separated by commas".yellow.on_black if desc['array']
621
+ puts "Enter 0 or false, 1 or true".yellow.on_black if desc['boolean']
622
+ prompt = desc["title"].bold + "> "
623
+ current = desc['value'] || desc['default']
624
+ if current
625
+ current = current.join(", ") if desc['array'] and current.is_a?(Array)
626
+ Readline.pre_input_hook = -> do
627
+ Readline.insert_text current.to_s
628
+ Readline.redisplay
629
+ Readline.pre_input_hook = nil
630
+ end
631
+ end
632
+ val = Readline.readline(prompt, false)
633
+ if desc['array'] and !val.nil?
634
+ val = val.strip.split(/\s*,\s*/)
635
+ end
636
+ if desc['boolean']
637
+ val = false if ["0", "false", "FALSE"].include?(val)
638
+ val = true if ["1", "true", "TRUE"].include?(val)
639
+ end
640
+ val = runValueCallback(desc, val)
641
+ val = current if val.nil? and desc['value']
642
+ val
643
+ end
644
+
645
+ def validate(newval, reqs, addnewline = true)
646
+ ok = true
647
+ def validate_individual_value(newval, reqs, addnewline)
648
+ ok = true
649
+ if reqs['boolean'] and newval != true and newval != false and newval != nil
650
+ puts "\nInvalid value '#{newval.bold}' for #{reqs['title'].bold} (must be true or false)".light_red.on_black
651
+ puts "\n\n" if addnewline
652
+ ok = false
653
+ elsif reqs['pattern']
654
+ if newval.nil?
655
+ puts "\nSupplied value for #{reqs['title'].bold} did not pass validation".light_red.on_black
656
+ puts "\n\n" if addnewline
657
+ ok = false
658
+ elsif reqs['negate_pattern']
659
+ if newval.to_s.match(reqs['pattern'])
660
+ puts "\nInvalid value '#{newval.bold}' for #{reqs['title'].bold} (must NOT match #{reqs['pattern']})".light_red.on_black
661
+ puts "\n\n" if addnewline
662
+ ok = false
663
+ end
664
+ elsif !newval.to_s.match(reqs['pattern'])
665
+ puts "\nInvalid value '#{newval.bold}' #{reqs['title'].bold} (must match #{reqs['pattern']})".light_red.on_black
666
+ puts "\n\n" if addnewline
667
+ ok = false
668
+ end
669
+ end
670
+ ok
671
+ end
672
+
673
+ if reqs['array']
674
+ if !newval.is_a?(Array)
675
+ puts "\nInvalid value '#{newval.bold}' for #{reqs['title'].bold} (should be an array)".light_red.on_black
676
+ puts "\n\n" if addnewline
677
+ ok = false
678
+ else
679
+ newval.each { |v|
680
+ ok = false if !validate_individual_value(v, reqs, addnewline)
681
+ }
682
+ end
683
+ else
684
+ ok = false if !validate_individual_value(newval, reqs, addnewline)
685
+ end
686
+ ok
687
+ end
688
+
689
+ answer = nil
690
+ changed = false
691
+
692
+ def entireConfigValid?
693
+ ok = true
694
+ $CONFIGURABLES.each_pair { |key, data|
695
+ next if !AMROOT and data['rootonly']
696
+ if data.has_key?("subtree")
697
+ data["subtree"].each_pair { |subkey, subdata|
698
+ next if !AMROOT and subdata['rootonly']
699
+ next if !data["value"]
700
+ ok = false if !validate(data["value"], data, false)
701
+ }
702
+ else
703
+ next if !data["value"]
704
+ ok = false if !validate(data["value"], data, false)
705
+ end
706
+ }
707
+ ok
708
+ end
709
+
710
+ def menu
711
+ begin
712
+ optlist = displayCurrentOpts
713
+ begin
714
+ print "Enter an option to change, "+"O".bold+" to save this config, or "+"^D".bold+" to quit.\n> "
715
+ answer = gets
716
+ if answer.nil?
717
+ puts ""
718
+ exit 0
719
+ end
720
+ answer.strip!
721
+ rescue EOFError
722
+ puts ""
723
+ exit 0
724
+ end
725
+ if $MENU_MAP.has_key?(answer) and !$MENU_MAP[answer].has_key?("subtree")
726
+ newval = ask($MENU_MAP[answer])
727
+ if !validate(newval, $MENU_MAP[answer])
728
+ sleep 1
729
+ next
730
+ end
731
+ $MENU_MAP[answer]['value'] = newval == "" ? nil : newval
732
+ $CHANGES.concat($MENU_MAP[answer]['changes']) if $MENU_MAP[answer].include?("changes")
733
+ if $MENU_MAP[answer]['title'] == "Local Hostname"
734
+ $CONFIGURABLES["aws"]["subtree"]["log_bucket_name"]["default"] = newval
735
+ elsif $MENU_MAP[answer]['title'] == "Public Address"
736
+ $CONFIGURABLES["banner"]["default"] = "Mu Master at #{newval}"
737
+ elsif $MENU_MAP[answer]['title'] == "Mu Admin Email"
738
+ $CONFIGURABLES["jenkins"]["subtree"]["admin_email"]["default"] = newval
739
+ end
740
+ changed = true
741
+ puts ""
742
+ elsif !["", "0", "O", "o"].include?(answer)
743
+ puts "\nInvalid option '#{answer.bold}'".light_red.on_black+"\n\n"
744
+ sleep 1
745
+ else
746
+ answer = nil if !entireConfigValid?
747
+ end
748
+ end while answer != "0" and answer != "O" and answer != "o"
749
+ end
750
+
751
+ if !$opts[:noninteractive]
752
+ menu
753
+ else
754
+ if !entireConfigValid?
755
+ puts "Configuration had validation errors, exiting.\nRe-invoke #{$0} to correct."
756
+ exit 1
757
+ end
758
+ end
759
+
760
+ if AMROOT
761
+ $MU_CFG['multiuser'] = true
762
+ saveMuConfig($MU_CFG)
763
+ end
764
+
765
+ def set389DSCreds
766
+ require 'mu'
767
+ credlist = {
768
+ "bind_creds" => {
769
+ "user" => "CN=mu_bind_creds,#{$MU_CFG["ldap"]['user_ou']}"
770
+ },
771
+ "join_creds" => {
772
+ "user" => "CN=mu_join_creds,#{$MU_CFG["ldap"]['user_ou']}"
773
+ },
774
+ "cfg_directory_adm" => {
775
+ "user" => "admin"
776
+ },
777
+ "root_dn_user" => {
778
+ "user" => "CN=root_dn_user"
779
+ }
780
+ }
781
+ credlist.each_pair { |creds, cfg|
782
+ begin
783
+ data = nil
784
+ if $MU_CFG["ldap"].has_key?(creds)
785
+ data = MU::Groomer::Chef.getSecret(
786
+ vault: $MU_CFG["ldap"][creds]["vault"],
787
+ item: $MU_CFG["ldap"][creds]["item"]
788
+ )
789
+ MU::Groomer::Chef.grantSecretAccess("MU-MASTER", $MU_CFG["ldap"][creds]["vault"], $MU_CFG["ldap"][creds]["item"])
790
+ else
791
+ data = MU::Groomer::Chef.getSecret(vault: "mu_ldap", item: creds)
792
+ MU::Groomer::Chef.grantSecretAccess("MU-MASTER", "mu_ldap", creds)
793
+ end
794
+ rescue MU::Groomer::Chef::MuNoSuchSecret
795
+ user = cfg["user"]
796
+ pw = Password.pronounceable(14..16)
797
+ if $MU_CFG["ldap"].has_key?(creds)
798
+ data = {
799
+ $MU_CFG["ldap"][creds]["username_field"] => user,
800
+ $MU_CFG["ldap"][creds]["password_field"] => pw
801
+ }
802
+ MU::Groomer::Chef.saveSecret(
803
+ vault: $MU_CFG["ldap"][creds]["vault"],
804
+ item: $MU_CFG["ldap"][creds]["item"],
805
+ data: data,
806
+ permissions: "name:MU-MASTER"
807
+ )
808
+ else
809
+ MU::Groomer::Chef.saveSecret(
810
+ vault: "mu_ldap",
811
+ item: creds,
812
+ data: { "username" => user, "password" => pw },
813
+ permissions: "name:MU-MASTER"
814
+ )
815
+ end
816
+ end
817
+ }
818
+ end
819
+
820
+ if AMROOT
821
+ cur_chef_version = `/bin/rpm -q chef`.sub(/^chef-(\d+\.\d+\.\d+-\d+)\..*/, '\1').chomp
822
+ pref_chef_version = File.read("#{MU_BASE}/var/mu-chef-client-version").chomp
823
+ if cur_chef_version != pref_chef_version
824
+ puts "Updating MU-MASTER's Chef Client to '#{pref_chef_version}'"
825
+ chef_installer = open("https://omnitruck.chef.io/install.sh").read
826
+ File.open("#{HOMEDIR}/chef-install.sh", File::CREAT|File::TRUNC|File::RDWR, 0644){ |f|
827
+ f.puts chef_installer
828
+ }
829
+ system("/bin/rm -rf /opt/chef ; sh #{HOMEDIR}/chef-install.sh -v #{pref_chef_version}");
830
+ # This will go fix gems, permissions, etc
831
+ system("/opt/chef/bin/chef-apply #{MU_BASE}/lib/cookbooks/mu-master/recipes/init.rb");
832
+ end
833
+ end
834
+
835
+ if $INITIALIZE
836
+ %x{/sbin/service iptables stop} # Chef run will set up correct rules later
837
+ $MU_SET_DEFAULTS = setConfigTree
838
+ require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
839
+ else
840
+ if AMROOT
841
+ $NEW_CFG = $MU_CFG.merge(setConfigTree)
842
+ else
843
+ $NEW_CFG = setConfigTree
844
+ end
845
+ saveMuConfig($NEW_CFG)
846
+ $MU_CFG = $MU_CFG.merge(setConfigTree)
847
+ require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
848
+ end
849
+ begin
850
+ require 'mu'
851
+ rescue MU::MuError => e
852
+ puts "Correct the above error before proceeding. To retry, run:\n\n#{$0.bold} #{ARGV.join(" ").bold}"
853
+ exit 1
854
+ rescue LoadError
855
+ system("cd #{MU_BASE}/lib/modules && umask 0022 && /usr/local/ruby-current/bin/bundle install")
856
+ require 'mu'
857
+ end
858
+
859
+ if AMROOT and ($INITIALIZE or $CHANGES.include?("hostname"))
860
+ system("/bin/hostname #{$MU_CFG['hostname']}")
861
+ end
862
+
863
+ # Do some more basic-but-Chef-dependent configuration *before* we meddle with
864
+ # the Chef Server configuration, which depends on some of this (SSL certs and
865
+ # local firewall ports).
866
+ if AMROOT and ($INITIALIZE or $CHANGES.include?("chefartifacts"))
867
+ MU.log "Purging and re-uploading all Chef artifacts", MU::NOTICE
868
+ %x{/sbin/service iptables stop} if $INITIALIZE
869
+ output = %x{MU_INSTALLDIR=#{MU_BASE} MU_LIBDIR=#{MU_BASE}/lib MU_DATADIR=#{MU_BASE}/var #{MU_BASE}/lib/bin/mu-upload-chef-artifacts}
870
+ if $?.exitstatus != 0
871
+ puts output
872
+ MU.log "mu-upload-chef-artifacts failed, can't proceed", MU::ERR
873
+ %x{/sbin/service iptables start} if $INITIALIZE
874
+ exit 1
875
+ end
876
+ %x{/sbin/service iptables start} if $INITIALIZE
877
+ end
878
+
879
+ if $INITIALIZE and AMROOT
880
+ MU.log "Force open key firewall holes", MU::NOTICE
881
+ system("chef-client -o 'recipe[mu-master::firewall-holes]'")
882
+ end
883
+
884
+ if AMROOT
885
+ MU.log "Checking internal SSL signing authority and certificates", MU::NOTICE
886
+ if !system("chef-client -o 'recipe[mu-master::ssl-certs]'") and $INITIALIZE
887
+ MU.log "Got bad exit code trying to run recipe[mu-master::ssl-certs]', aborting", MU::ERR
888
+ exit 1
889
+ end
890
+ end
891
+
892
+ def updateChefRbs
893
+ user = AMROOT ? "mu" : Etc.getpwuid(Process.uid).name
894
+ chefuser = user.gsub(/\./, "")
895
+ templates = { HOMEDIR+"/.chef/knife.rb" => KNIFE_TEMPLATE }
896
+ if AMROOT
897
+ templates["/etc/chef/client.rb"] = CLIENT_TEMPLATE
898
+ templates["/etc/opscode/pivotal.rb"] = PIVOTAL_TEMPLATE
899
+ end
900
+ templates.each_pair { |file, template|
901
+ erb = ERB.new(template)
902
+ processed = erb.result(binding)
903
+ tmpfile = file+".tmp."+Process.pid.to_s
904
+ File.open(tmpfile, File::CREAT|File::TRUNC|File::RDWR, 0644){ |f|
905
+ f.puts processed
906
+ }
907
+ if !File.size?(file) or File.read(tmpfile) != File.read(file)
908
+ File.rename(tmpfile, file)
909
+ MU.log "Updated #{file}", MU::NOTICE
910
+ $CHANGES << "chefcerts"
911
+ else
912
+ File.unlink(tmpfile)
913
+ end
914
+ }
915
+ end
916
+
917
+
918
+ if AMROOT
919
+ erb = ERB.new(File.read("#{MU_BASE}/lib/cookbooks/mu-master/templates/default/chef-server.rb.erb"))
920
+ updated_server_cfg = erb.result(binding)
921
+ cfgpath = "/etc/opscode/chef-server.rb"
922
+ tmpfile = "/etc/opscode/chef-server.rb.#{Process.pid}"
923
+ File.open(tmpfile, File::CREAT|File::TRUNC|File::RDWR, 0644){ |f|
924
+ f.puts updated_server_cfg
925
+ }
926
+ if !File.size?(cfgpath) or File.read(tmpfile) != File.read(cfgpath)
927
+ File.rename(tmpfile, cfgpath)
928
+ # Opscode can't seem to get things right with their postgres socket
929
+ Dir.mkdir("/var/run/postgresql", 0755) if !Dir.exists?("/var/run/postgresql")
930
+ if File.exists?("/tmp/.s.PGSQL.5432") and !File.exists?("/var/run/postgresql/.s.PGSQL.5432")
931
+ File.symlink("/tmp/.s.PGSQL.5432", "/var/run/postgresql/.s.PGSQL.5432")
932
+ elsif !File.exists?("/tmp/.s.PGSQL.5432") and File.exists?("/var/run/postgresql/.s.PGSQL.5432")
933
+ File.symlink("/var/run/postgresql/.s.PGSQL.5432", "/tmp/.s.PGSQL.5432")
934
+ end
935
+ MU.log "Chef Server config was modified, reconfiguring...", MU::NOTICE
936
+ # XXX Some undocumented port Chef needs only on startup is being blocked by
937
+ # iptables. Something rabbitmq-related. Dopey workaround.
938
+ %x{/sbin/service iptables stop}
939
+ system("/opt/opscode/bin/chef-server-ctl reconfigure")
940
+ system("/opt/opscode/bin/chef-server-ctl restart")
941
+ %x{/sbin/service iptables start}
942
+ updateChefRbs
943
+ $CHANGES << "chefcerts"
944
+ else
945
+ File.unlink(tmpfile)
946
+ updateChefRbs
947
+ end
948
+ else
949
+ updateChefRbs
950
+ end
951
+
952
+ if $IN_AWS and AMROOT
953
+ system("#{MU_BASE}/lib/bin/mu-aws-setup --dns --sg --logs --ephemeral")
954
+ # XXX --ip? Do we really care?
955
+ end
956
+ if $IN_GOOGLE and AMROOT
957
+ system("#{MU_BASE}/lib/bin/mu-gcp-setup --sg --logs")
958
+ end
959
+
960
+ if $INITIALIZE or $CHANGES.include?("chefcerts")
961
+ system("rm -f #{HOMEDIR}/.chef/trusted_certs/* ; knife ssl fetch -c #{HOMEDIR}/.chef/knife.rb")
962
+ if AMROOT
963
+ system("rm -f /etc/chef/trusted_certs/* ; knife ssl fetch -c /etc/chef/client.rb")
964
+ end
965
+ end
966
+
967
+ # knife ssl fetch isn't bright enough to nab our intermediate certs, which
968
+ # ironically becomes a problem when we use one from the real world. Jam it
969
+ # into knife and chef-client's faces thusly:
970
+ if $MU_CFG['ssl'] and $MU_CFG['ssl']['chain'] and File.size?($MU_CFG['ssl']['chain'])
971
+ cert = File.basename($MU_CFG['ssl']['chain'])
972
+ FileUtils.cp($MU_CFG['ssl']['chain'], HOMEDIR+"/.chef/trusted_certs/#{cert}")
973
+ File.chmod(0600, HOMEDIR+"/.chef/trusted_certs/#{cert}")
974
+ if AMROOT
975
+ File.chmod(0644, $MU_CFG['ssl']['chain'])
976
+ FileUtils.cp($MU_CFG['ssl']['chain'], "/etc/chef/trusted_certs/#{cert}")
977
+ end
978
+ end
979
+
980
+ if $MU_CFG['repos'] and $MU_CFG['repos'].size > 0
981
+ $MU_CFG['repos'].each { |repo|
982
+ repo.match(/\/([^\/]+?)(\.git)?$/)
983
+ shortname = Regexp.last_match(1)
984
+ repodir = MU.dataDir + "/" + shortname
985
+ if !Dir.exists?(repodir)
986
+ MU.log "Cloning #{repo} into #{repodir}", MU::NOTICE
987
+ Dir.chdir(MU.dataDir)
988
+ system("/usr/bin/git clone #{repo}")
989
+ $CHANGES << "chefartifacts"
990
+ end
991
+ }
992
+ end
993
+
994
+ if !AMROOT
995
+ exit
996
+ end
997
+
998
+ begin
999
+ MU::Groomer::Chef.getSecret(vault: "secrets", item: "consul")
1000
+ rescue MU::Groomer::Chef::MuNoSuchSecret
1001
+ data = {
1002
+ "private_key" => File.read("#{MU_BASE}/var/ssl/consul.key"),
1003
+ "certificate" => File.read("#{MU_BASE}/var/ssl/consul.crt"),
1004
+ "ca_certificate" => File.read("#{MU_BASE}/var/ssl/Mu_CA.pem")
1005
+ }
1006
+ MU::Groomer::Chef.saveSecret(
1007
+ vault: "secrets",
1008
+ item: "consul",
1009
+ data: data,
1010
+ permissions: "name:MU-MASTER"
1011
+ )
1012
+ end
1013
+ if $INITIALIZE or $CHANGES.include?("vault")
1014
+ MU.log "Setting up Hashicorp Vault", MU::NOTICE
1015
+ system("chef-client -o 'recipe[mu-master::vault]'")
1016
+ end
1017
+
1018
+ if $MU_CFG['ldap']['type'] == "389 Directory Services"
1019
+ begin
1020
+ MU::Master::LDAP.listUsers
1021
+ rescue Exception => e # XXX lazy exception handling is lazy
1022
+ $CHANGES << "389ds"
1023
+ end
1024
+ if $INITIALIZE or $CHANGES.include?("389ds")
1025
+ File.unlink("/root/389ds.tmp/389-directory-setup.inf") if File.exists?("/root/389ds.tmp/389-directory-setup.inf")
1026
+ MU.log "Configuring 389 Directory Services", MU::NOTICE
1027
+ set389DSCreds
1028
+ system("chef-client -o 'recipe[mu-master::389ds]'")
1029
+ exit 1 if $? != 0
1030
+ MU::Master::LDAP.initLocalLDAP
1031
+ system("chef-client -o 'recipe[mu-master::sssd]'")
1032
+ exit 1 if $? != 0
1033
+ end
1034
+ end
1035
+
1036
+ if $MU_CFG['jenkins'] and $MU_CFG['jenkins']['enable']
1037
+ MU::Groomer::Chef.loadChefLib
1038
+ chef_node = ::Chef::Node.load("MU-MASTER")
1039
+ begin
1040
+ data = MU::Groomer::Chef.getSecret(vault: "jenkins", item: "admin")
1041
+ MU::Groomer::Chef.grantSecretAccess("MU-MASTER", "jenkins", "admin")
1042
+ rescue MU::Groomer::Chef::MuNoSuchSecret
1043
+ MU.log "Saving keys for Jenkins admin user '#{$MU_CFG['jenkins']['admin_user']}' into Vault jenkins:admin", MU::NOTICE
1044
+ if !File.exists?("#{HOMEDIR}/.ssh/mu-jenkins-admin.pub") and !File.exists?("#{HOMEDIR}/.ssh/mu-jenkins-admin.pub")
1045
+ system("/usr/bin/ssh-keygen -N '' -f #{HOMEDIR}/.ssh/mu-jenkins-admin")
1046
+ end
1047
+ public_key = File.read("#{HOMEDIR}/.ssh/mu-jenkins-admin.pub").chomp
1048
+ private_key = File.read("#{HOMEDIR}/.ssh/mu-jenkins-admin").chomp
1049
+ MU::Groomer::Chef.saveSecret(
1050
+ vault: "jenkins",
1051
+ item: "admin",
1052
+ data: {
1053
+ "username": $MU_CFG['jenkins']['admin_user'],
1054
+ "private_key": private_key,
1055
+ "public_key": public_key
1056
+ }
1057
+ )
1058
+ end
1059
+ end
1060
+
1061
+ # Figure out if our run list is dumb
1062
+ MU.log "Verifying MU-MASTER's Chef run list", MU::NOTICE
1063
+ MU::Groomer::Chef.loadChefLib
1064
+ chef_node = ::Chef::Node.load("MU-MASTER")
1065
+ run_list = ["role[mu-master]"]
1066
+ run_list << "role[mu-master-jenkins]" if $MU_CFG['jenkins']['enable']
1067
+ run_list.concat($MU_CFG['master_runlist_extras']) if $MU_CFG['master_runlist_extras'].is_a?(Array)
1068
+ set_runlist = false
1069
+ run_list.each { |rl|
1070
+ set_runlist = true if !chef_node.run_list?(rl)
1071
+ }
1072
+ if set_runlist
1073
+ MU.log "Updating MU-MASTER run_list", MU::NOTICE, details: run_list
1074
+ chef_node.run_list(run_list)
1075
+ chef_node.save
1076
+ $CHANGES << "chefrun"
1077
+ else
1078
+ MU.log "Chef run list looks correct", MU::NOTICE, details: run_list
1079
+ end
1080
+
1081
+ # TODO here are some things we don't do yet but should
1082
+ # accommodate running as a non-root user
1083
+
1084
+ if $INITIALIZE
1085
+ MU::Config.emitSchemaAsRuby
1086
+ MU.log "Generating YARD documentation in /var/www/html/docs (see http://#{$MU_CFG['public_address']}/docs/frames.html)"
1087
+ File.umask(0022)
1088
+ system("cd #{MU.myRoot} && umask 0022 && env -i PATH=#{ENV['PATH']} HOME=#{HOMEDIR} /usr/local/ruby-current/bin/yard doc modules -m markdown -o /var/www/html/docs && chcon -R -h -t httpd_sys_script_exec_t /var/www/html/")
1089
+ end
1090
+
1091
+
1092
+ MU.log "Running chef-client on MU-MASTER", MU::NOTICE
1093
+ system("chef-client -o '#{run_list.join(",")}'")
1094
+
1095
+
1096
+ if !File.exists?("#{MU_BASE}/var/users/mu/email") or !File.exists?("#{MU_BASE}/var/users/mu/realname")
1097
+ MU.log "Finalizing the 'mu' Chef/LDAP account", MU::NOTICE
1098
+ MU.setLogging(MU::Logger::SILENT)
1099
+ MU::Master.manageUser(
1100
+ "mu",
1101
+ name: $MU_CFG['mu_admin_name'],
1102
+ email: $MU_CFG['mu_admin_email'],
1103
+ admin: true,
1104
+ password: MU.generateWindowsPassword # we'll just overwrite this and do it with mu-user-manage below, which can do smart things with Scratchpad
1105
+ )
1106
+ MU.setLogging(MU::Logger::NORMAL)
1107
+ sleep 3 # avoid LDAP lag for mu-user-manage
1108
+ end
1109
+
1110
+ output = %x{/opt/chef/bin/knife vault show scratchpad 2>&1}
1111
+ if $?.exitstatus != 0 or output.match(/is not a chef-vault/)
1112
+ MU::Groomer::Chef.saveSecret(
1113
+ vault: "scratchpad",
1114
+ item: "placeholder",
1115
+ data: { "secret" => "DO NOT DELETE", "timestamp" => "9999999999" },
1116
+ permissions: "name:MU-MASTER"
1117
+ )
1118
+ end
1119
+
1120
+ MU.log "Regenerating documentation in /var/www/html/docs"
1121
+ %x{#{MU_BASE}/lib/bin/mu-gen-docs}
1122
+
1123
+ if $INITIALIZE
1124
+ MU.log "Setting initial password for admin user 'mu', for logging into Nagios and other built-in services.", MU::NOTICE
1125
+ puts %x{#{MU_BASE}/lib/bin/mu-user-manage -g mu}
1126
+ MU.log "If Scratchpad web interface is not accessible, try the following:", MU::NOTICE
1127
+ puts "#{MU_BASE}/lib/bin/mu-user-manage -g --no-scratchpad mu".bold
1128
+ end
1129
+
1130
+ if !ENV['PATH'].match(/(^|:)#{Regexp.quote(MU_BASE)}\/bin(:|$)/)
1131
+ MU.log "I added some entries to your $PATH, run this to import them:", MU::NOTICE
1132
+ puts "source #{HOMEDIR}/.bashrc".bold
1133
+ end