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
@@ -0,0 +1,1009 @@
1
+ # Copyright:: Copyright (c) 2014 eGlobalTech, Inc., all rights reserved
2
+ #
3
+ # Licensed under the BSD-3 license (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License in the root of the project or at
6
+ #
7
+ # http://egt-labs.com/mu/LICENSE.html
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "net/http"
16
+ require 'open-uri'
17
+ require 'timeout'
18
+ require 'inifile'
19
+ gem 'aws-sdk-core'
20
+ autoload :Aws, "aws-sdk-core"
21
+
22
+
23
+ module MU
24
+ class Cloud
25
+ # Support for Amazon Web Services as a provisioning layer.
26
+ class AWS
27
+ @@myRegion_var = nil
28
+
29
+ @@creds_loaded = false
30
+
31
+ # Load some credentials for using the AWS API
32
+ def self.loadCredentials
33
+ return if @@creds_loaded
34
+ if $MU_CFG and $MU_CFG['aws']
35
+ loaded = false
36
+ if $MU_CFG['aws']['access_key'] and $MU_CFG['aws']['access_secret'] and
37
+ # access key and secret just sitting in mu.yaml
38
+ !$MU_CFG['aws']['access_key'].empty? and
39
+ !$MU_CFG['aws']['access_secret'].empty?
40
+ Aws.config = {
41
+ access_key_id: $MU_CFG['aws']['access_key'],
42
+ secret_access_key: $MU_CFG['aws']['access_secret'],
43
+ region: $MU_CFG['aws']['region']
44
+ }
45
+ loaded = true
46
+ elsif $MU_CFG['aws']['credentials_file'] and
47
+ !$MU_CFG['aws']['credentials_file'].empty?
48
+ # pull access key and secret from an awscli-style credentials file
49
+ begin
50
+ File.read($MU_CFG["aws"]["credentials_file"]) # make sure it's there
51
+ credfile = IniFile.load($MU_CFG["aws"]["credentials_file"])
52
+
53
+ if !credfile.sections or credfile.sections.size == 0
54
+ raise ::IniFile::Error, "No AWS profiles found in #{$MU_CFG["aws"]["credentials_file"]}"
55
+ end
56
+ data = credfile.has_section?("default") ? credfile["default"] : credfile[credfile.sections.first]
57
+ if data["aws_access_key_id"] and data["aws_secret_access_key"]
58
+ Aws.config = {
59
+ access_key_id: data['aws_access_key_id'],
60
+ secret_access_key: data['aws_secret_access_key'],
61
+ region: $MU_CFG['aws']['region']
62
+ }
63
+ loaded = true
64
+ else
65
+ MU.log "AWS credentials in #{$MU_CFG["aws"]["credentials_file"]} specified, but is missing aws_access_key_id or aws_secret_access_key elements", MU::WARN
66
+ end
67
+ rescue IniFile::Error, Errno::ENOENT, Errno::EACCES => e
68
+ MU.log "AWS credentials file #{$MU_CFG["aws"]["credentials_file"]} is missing or invalid", MU::WARN, details: e.message
69
+ end
70
+ elsif $MU_CFG['aws']['credentials'] and
71
+ !$MU_CFG['aws']['credentials'].empty?
72
+ # pull access key and secret from a vault
73
+ begin
74
+ vault, item = $MU_CFG["aws"]["credentials"].split(/:/)
75
+ data = MU::Groomer::Chef.getSecret(vault: vault, item: item).to_h
76
+ if data["access_key"] and data["access_secret"]
77
+ Aws.config = {
78
+ access_key_id: data['access_key'],
79
+ secret_access_key: data['access_secret'],
80
+ region: $MU_CFG['aws']['region']
81
+ }
82
+ loaded = true
83
+ else
84
+ MU.log "AWS credentials vault:item #{$MU_CFG["aws"]["credentials"]} specified, but is missing access_key or access_secret elements", MU::WARN
85
+ end
86
+ rescue MU::Groomer::Chef::MuNoSuchSecret
87
+ MU.log "AWS credentials vault:item #{$MU_CFG["aws"]["credentials"]} specified, but does not exist", MU::WARN
88
+ end
89
+ end
90
+
91
+ if !loaded and hosted?
92
+ # assume we've got an IAM profile and hope for the best
93
+ ENV.delete('AWS_ACCESS_KEY_ID')
94
+ ENV.delete('AWS_SECRET_ACCESS_KEY')
95
+ Aws.config = {region: ENV['EC2_REGION']}
96
+ loaded = true
97
+ end
98
+
99
+ @@creds_loaded = loaded
100
+ if !@@creds_loaded
101
+ raise MuError, "AWS layer is enabled in mu.yaml, but I couldn't find working API credentials anywhere"
102
+ end
103
+ end
104
+ end
105
+
106
+ # Any cloud-specific instance methods we require our resource
107
+ # implementations to have, above and beyond the ones specified by
108
+ # {MU::Cloud}
109
+ # @return [Array<Symbol>]
110
+ def self.required_instance_methods
111
+ [:arn]
112
+ end
113
+
114
+ # If we've configured AWS as a provider, or are simply hosted in AWS,
115
+ # decide what our default region is.
116
+ def self.myRegion
117
+ if $MU_CFG and (!$MU_CFG['aws'] or !account_number) and !hosted?
118
+ return nil
119
+ end
120
+ if $MU_CFG and $MU_CFG['aws'] and $MU_CFG['aws']['region']
121
+ @@myRegion_var ||= MU::Cloud::AWS.ec2($MU_CFG['aws']['region']).describe_availability_zones.availability_zones.first.region_name
122
+ elsif ENV.has_key?("EC2_REGION") and !ENV['EC2_REGION'].empty?
123
+ @@myRegion_var ||= MU::Cloud::AWS.ec2(ENV['EC2_REGION']).describe_availability_zones.availability_zones.first.region_name
124
+ else
125
+ # hacky, but useful in a pinch
126
+ az_str = MU::Cloud::AWS.getAWSMetaData("placement/availability-zone")
127
+ @@myRegion_var = az_str.sub(/[a-z]$/i, "") if az_str
128
+ end
129
+ end
130
+
131
+ # Is the region we're dealing with a GovCloud region?
132
+ # @param region [String]: The region in question, defaults to the Mu Master's local region
133
+ def self.isGovCloud?(region = myRegion)
134
+ return false if !region
135
+ region.match(/^us-gov-/)
136
+ end
137
+
138
+ # @param resources [Array<String>]: The cloud provider identifier of the resource to untag
139
+ # @param key [String]: The name of the tag to remove
140
+ # @param value [String]: The value of the tag to remove
141
+ # @param region [String]: The cloud provider region
142
+ def self.removeTag(key, value, resources = [], region: myRegion)
143
+ MU::Cloud::AWS.ec2(region).delete_tags(
144
+ resources: resources,
145
+ tags: [
146
+ {
147
+ key: key,
148
+ value: value
149
+ }
150
+ ]
151
+ )
152
+ end
153
+
154
+ # Tag EC2 resources.
155
+ #
156
+ # @param resources [Array<String>]: The cloud provider identifier of the resource to tag
157
+ # @param key [String]: The name of the tag to create
158
+ # @param value [String]: The value of the tag
159
+ # @param region [String]: The cloud provider region
160
+ # @return [void,<Hash>]
161
+ def self.createTag(key, value, resources = [], region: myRegion)
162
+
163
+ if !MU::Cloud::CloudFormation.emitCloudFormation
164
+ begin
165
+ MU::Cloud::AWS.ec2(region).create_tags(
166
+ resources: resources,
167
+ tags: [
168
+ {
169
+ key: key,
170
+ value: value
171
+ }
172
+ ]
173
+ )
174
+ rescue Aws::EC2::Errors::ServiceError => e
175
+ MU.log "Got #{e.inspect} tagging #{resources.size.to_s} resources with #{key}=#{value}", MU::WARN, details: resources if attempts > 1
176
+ if attempts < 5
177
+ attempts = attempts + 1
178
+ sleep 15
179
+ retry
180
+ else
181
+ raise e
182
+ end
183
+ end
184
+ MU.log "Created tag #{key} with value #{value}", MU::DEBUG, details: resources
185
+ else
186
+ return {
187
+ "Key" => key,
188
+ "Value" => value
189
+ }
190
+ end
191
+ end
192
+
193
+ @@azs = {}
194
+ # List the Availability Zones associated with a given Amazon Web Services
195
+ # region. If no region is given, search the one in which this MU master
196
+ # server resides.
197
+ # @param region [String]: The region to search.
198
+ # @return [Array<String>]: The Availability Zones in this region.
199
+ def self.listAZs(region = MU.curRegion)
200
+ if $MU_CFG and (!$MU_CFG['aws'] or !account_number)
201
+ return []
202
+ end
203
+ if !region.nil? and @@azs[region]
204
+ return @@azs[region]
205
+ end
206
+ if region
207
+ azs = MU::Cloud::AWS.ec2(region).describe_availability_zones(
208
+ filters: [name: "region-name", values: [region]]
209
+ )
210
+ end
211
+ @@azs[region] ||= []
212
+ azs.data.availability_zones.each { |az|
213
+ @@azs[region] << az.zone_name if az.state == "available"
214
+ }
215
+ return @@azs[region]
216
+ end
217
+
218
+ # Plant a Mu deploy secret into a storage bucket somewhere for so our kittens can consume it
219
+ # @param deploy_id [String]: The deploy for which we're writing the secret
220
+ # @param value [String]: The contents of the secret
221
+ def self.writeDeploySecret(deploy_id, value, name = nil)
222
+ name ||= deploy_id+"-secret"
223
+ begin
224
+ MU.log "Writing #{name} to S3 bucket #{MU.adminBucketName}"
225
+ MU::Cloud::AWS.s3(myRegion).put_object(
226
+ acl: "private",
227
+ bucket: MU.adminBucketName,
228
+ key: name,
229
+ body: value
230
+ )
231
+ rescue Aws::S3::Errors => e
232
+ raise MU::MommaCat::DeployInitializeError, "Got #{e.inspect} trying to write #{name} to #{MU.adminBucketName}"
233
+ end
234
+ end
235
+
236
+ @@is_in_aws = nil
237
+
238
+ # Alias for #{MU::Cloud::AWS.hosted?}
239
+ def self.hosted
240
+ MU::Cloud::AWS.hosted?
241
+ end
242
+
243
+ # Determine whether we (the Mu master, presumably) are hosted in this
244
+ # cloud.
245
+ # @return [Boolean]
246
+ def self.hosted?
247
+ require 'open-uri'
248
+
249
+ if !@@is_in_aws.nil?
250
+ return @@is_in_aws
251
+ end
252
+
253
+ begin
254
+ Timeout.timeout(2) do
255
+ instance_id = open("http://169.254.169.254/latest/meta-data/instance-id").read
256
+ if !instance_id.nil? and instance_id.size > 0
257
+ @@is_in_aws = true
258
+ return true
259
+ end
260
+ end
261
+ rescue OpenURI::HTTPError, Timeout::Error, SocketError, Errno::EHOSTUNREACH
262
+ end
263
+
264
+ @@is_in_aws = false
265
+ false
266
+ end
267
+
268
+ # If we're running this cloud, return the $MU_CFG blob we'd use to
269
+ # describe this environment as our target one.
270
+ def self.hosted_config
271
+ return nil if !hosted?
272
+ region = getAWSMetaData("placement/availability-zone").sub(/[a-z]$/i, "")
273
+ mac = getAWSMetaData("network/interfaces/macs/").split(/\n/)[0]
274
+ acct_num = getAWSMetaData("network/interfaces/macs/#{mac}owner-id")
275
+ acct_num.chomp!
276
+ {
277
+ "region" => region,
278
+ "account_number" => acct_num
279
+ }
280
+ end
281
+
282
+ # A non-working example configuration
283
+ def self.config_example
284
+ sample = hosted_config
285
+ sample ||= {
286
+ "region" => "us-east-1",
287
+ "account_number" => "123456789012",
288
+ }
289
+ # sample["access_key"] = "AKIAIXKNI3JY6JVVJIHA"
290
+ # sample["access_secret"] = "oWjHT+2N3veyswy7+UA5i+H14KpvrOIZlnRlxpkw"
291
+ sample["credentials_file"] = "#{Etc.getpwuid(Process.uid).dir}/.aws/credentials"
292
+ sample["log_bucket_name"] = "my-mu-s3-bucket"
293
+ sample
294
+ end
295
+
296
+ @my_acct_num = nil
297
+
298
+ # Fetch the AWS account number where this Mu master resides. If it's not in
299
+ # AWS at all, or otherwise cannot be determined, return nil.
300
+ # here.
301
+ # XXX account for Google and non-cloud situations
302
+ # XXX but what about multi-account uuuugh
303
+ def self.account_number
304
+ return nil if !$MU_CFG['aws']
305
+ return @my_acct_num if @my_acct_num
306
+
307
+ begin
308
+ user_list = MU::Cloud::AWS.iam($MU_CFG['aws']['region']).list_users.users
309
+ # rescue ::Aws::IAM::Errors => e # XXX why does this NameError here?
310
+ rescue Exception => e
311
+ MU.log "Got #{e.inspect} while trying to figure out our account number", MU::WARN, details: caller
312
+ end
313
+ if user_list.nil? or user_list.size == 0
314
+ mac = MU::Cloud::AWS.getAWSMetaData("network/interfaces/macs/").split(/\n/)[0]
315
+ acct_num = MU::Cloud::AWS.getAWSMetaData("network/interfaces/macs/#{mac}owner-id")
316
+ acct_num.chomp!
317
+ else
318
+ acct_num = MU::Cloud::AWS.iam($MU_CFG['aws']['region']).list_users.users.first.arn.split(/:/)[4]
319
+ end
320
+ MU.setVar("acct_num", acct_num)
321
+ @my_acct_num ||= acct_num
322
+ acct_num
323
+ end
324
+
325
+ @@regions = {}
326
+ # List the Amazon Web Services region names available to this account. The
327
+ # region that is local to this Mu server will be listed first.
328
+ # @param us_only [Boolean]: Restrict results to United States only
329
+ # @return [Array<String>]
330
+ def self.listRegions(us_only = false)
331
+ if $MU_CFG and (!$MU_CFG['aws'] or !account_number)
332
+ return []
333
+ end
334
+ if @@regions.size == 0
335
+ result = MU::Cloud::AWS.ec2(myRegion).describe_regions.regions
336
+ regions = []
337
+ result.each { |r|
338
+ @@regions[r.region_name] = Proc.new { listAZs(r.region_name) }
339
+ }
340
+ end
341
+ regions = if us_only
342
+ @@regions.keys.delete_if { |r| !r.match(/^us\-/) }.uniq
343
+ else
344
+ @@regions.keys.uniq
345
+ end
346
+
347
+ # XXX GovCloud doesn't show up if you query a commercial endpoint... that's
348
+ # *probably* ok for most purposes? We can't call listAZs on it from out here
349
+ # apparently, so getting around it is nontrivial
350
+ # if !@@regions.has_key?("us-gov-west-1")
351
+ # @@regions["us-gov-west-1"] = Proc.new { listAZs("us-gov-west-1") }
352
+ # end
353
+
354
+ regions.sort! { |a, b|
355
+ val = a <=> b
356
+ if a == myRegion
357
+ val = -1
358
+ elsif b == myRegion
359
+ val = 1
360
+ end
361
+ val
362
+ }
363
+ regions
364
+ end
365
+
366
+ # Generate an EC2 keypair unique to this deployment, given a regular
367
+ # OpenSSH-style public key and a name.
368
+ # @param keyname [String]: The name of the key to create.
369
+ # @param public_key [String]: The public key
370
+ # @return [Array<String>]: keypairname, ssh_private_key, ssh_public_key
371
+ def self.createEc2SSHKey(keyname, public_key)
372
+ # We replicate this key in all regions
373
+ if !MU::Cloud::CloudFormation.emitCloudFormation
374
+ MU::Cloud::AWS.listRegions.each { |region|
375
+ MU.log "Replicating #{keyname} to EC2 in #{region}", MU::DEBUG, details: @ssh_public_key
376
+ MU::Cloud::AWS.ec2(region).import_key_pair(
377
+ key_name: keyname,
378
+ public_key_material: public_key
379
+ )
380
+ }
381
+ end
382
+ end
383
+
384
+ @@instance_types = nil
385
+ # Query the AWS API for the list of valid EC2 instance types and some of
386
+ # their attributes. We can use this in config validation and to help
387
+ # "translate" machine types across cloud providers.
388
+ # @param region [String]: Supported machine types can vary from region to region, so we look for the set we're interested in specifically
389
+ # @return [Hash]
390
+ def self.listInstanceTypes(region = myRegion)
391
+ return @@instance_types if @@instance_types and @@instance_types[region]
392
+ if $MU_CFG and (!$MU_CFG['aws'] or !account_number)
393
+ return {}
394
+ end
395
+
396
+ human_region = @@regionLookup[region]
397
+
398
+ @@instance_types ||= {}
399
+ @@instance_types[region] ||= {}
400
+ next_token = nil
401
+
402
+ begin
403
+ # Pricing API isn't widely available, so ask a region we know supports
404
+ # it
405
+ resp = MU::Cloud::AWS.pricing("us-east-1").get_products(
406
+ service_code: "AmazonEC2",
407
+ filters: [
408
+ {
409
+ field: "productFamily",
410
+ value: "Compute Instance",
411
+ type: "TERM_MATCH"
412
+ },
413
+ {
414
+ field: "tenancy",
415
+ value: "Shared",
416
+ type: "TERM_MATCH"
417
+ },
418
+ {
419
+ field: "location",
420
+ value: human_region,
421
+ type: "TERM_MATCH"
422
+ }
423
+ ],
424
+ next_token: next_token
425
+ )
426
+ resp.price_list.each { |pricing|
427
+ data = JSON.parse(pricing)
428
+ type = data["product"]["attributes"]["instanceType"]
429
+ next if @@instance_types[region].has_key?(type)
430
+ @@instance_types[region][type] = {}
431
+ ["ecu", "vcpu", "memory", "storage"].each { |a|
432
+ @@instance_types[region][type][a] = data["product"]["attributes"][a]
433
+ }
434
+ @@instance_types[region][type]["memory"].sub!(/ GiB/, "")
435
+ @@instance_types[region][type]["memory"] = @@instance_types[region][type]["memory"].to_f
436
+ @@instance_types[region][type]["vcpu"] = @@instance_types[region][type]["vcpu"].to_f
437
+ }
438
+ next_token = resp.next_token
439
+ end while resp and next_token
440
+
441
+ @@instance_types
442
+ end
443
+
444
+ # AWS can stash API-available certificates in Amazon Certificate Manager
445
+ # or in IAM. Rather than make people crazy trying to get the syntax
446
+ # correct in our Baskets of Kittens, let's have a helper that tries to do
447
+ # the right thing, and only raise an exception if we need help to
448
+ # disambiguate.
449
+ # @param name [String]: The name of the cert. For IAM certs this can be any IAM name; for ACM, it's usually the domain name. If multiple matches are found, or no matches, an exception is raised.
450
+ # @param id [String]: The ARN of a known certificate. We just validate that it exists. This is ignored if a name parameter is supplied.
451
+ # @return [String]: The ARN of a matching certificate that is known to exist. If it is an ACM certificate, we also know that it is not expired.
452
+ def self.findSSLCertificate(name: nil, id: nil, region: myRegion)
453
+ if name.nil? and name.empty? and id.nil? and id.empty?
454
+ raise MuError, "Can't call findSSLCertificate without specifying either a name or an id"
455
+ end
456
+
457
+ if !name.nil? and !name.empty?
458
+ matches = []
459
+ acmcerts = MU::Cloud::AWS.acm(region).list_certificates(
460
+ certificate_statuses: ["ISSUED"]
461
+ )
462
+ acmcerts.certificate_summary_list.each { |cert|
463
+ matches << cert.certificate_arn if cert.domain_name == name
464
+ }
465
+ begin
466
+ iamcert = MU::Cloud::AWS.iam.get_server_certificate(
467
+ server_certificate_name: name
468
+ )
469
+ rescue Aws::IAM::Errors::ValidationError, Aws::IAM::Errors::NoSuchEntity
470
+ # valid names for ACM certs can break here, and that's ok to ignore
471
+ end
472
+ if !iamcert.nil?
473
+ matches << iamcert.server_certificate.server_certificate_metadata.arn
474
+ end
475
+ if matches.size == 1
476
+ return matches.first
477
+ elsif matches.size == 0
478
+ raise MuError, "No IAM or ACM certificate named #{name} was found"
479
+ elsif matches.size > 1
480
+ raise MuError, "Multiple certificates named #{name} were found. Remove extras or use ssl_certificate_id to supply the exact ARN of the one you want to use."
481
+ end
482
+ end
483
+
484
+ if id.match(/^arn:aws(?:-us-gov)?:acm/)
485
+ resp = MU::Cloud::AWS.acm(region).get_certificate(
486
+ certificate_arn: id
487
+ )
488
+ if resp.nil?
489
+ raise MuError, "No such ACM certificate '#{id}'"
490
+ end
491
+ elsif id.match(/^arn:aws(?:-us-gov)?:iam/)
492
+ resp = MU::Cloud::AWS.iam.list_server_certificates
493
+ if resp.nil?
494
+ raise MuError, "No such IAM certificate '#{id}'"
495
+ end
496
+ resp.server_certificate_metadata_list.each { |cert|
497
+ if cert.arn == id
498
+ if cert.expiration < Time.now
499
+ MU.log "IAM SSL certificate #{cert.server_certificate_name} (#{id}) is EXPIRED", MU::WARN
500
+ end
501
+ return id
502
+ end
503
+ }
504
+ raise MuError, "No such IAM certificate '#{id}'"
505
+ else
506
+ raise MuError, "The format of '#{id}' doesn't look like an ARN for either Amazon Certificate Manager or IAM"
507
+ end
508
+
509
+ id
510
+ end
511
+
512
+ # Amazon Certificate Manager API
513
+ def self.acm(region = MU.curRegion)
514
+ region ||= myRegion
515
+ @@acm_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "ACM", region: region)
516
+ @@acm_api[region]
517
+ end
518
+
519
+ # Amazon's IAM API
520
+ def self.iam(region = MU.curRegion)
521
+ region ||= myRegion
522
+ @@iam_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "IAM", region: region)
523
+ @@iam_api[region]
524
+ end
525
+
526
+ # Amazon's EC2 API
527
+ def self.ec2(region = MU.curRegion)
528
+ region ||= myRegion
529
+ @@ec2_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "EC2", region: region)
530
+ @@ec2_api[region]
531
+ end
532
+
533
+ # Amazon's Autoscaling API
534
+ def self.autoscale(region = MU.curRegion)
535
+ region ||= myRegion
536
+ @@autoscale_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "AutoScaling", region: region)
537
+ @@autoscale_api[region]
538
+ end
539
+
540
+ # Amazon's ElasticLoadBalancing API
541
+ def self.elb(region = MU.curRegion)
542
+ region ||= myRegion
543
+ @@elb_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "ElasticLoadBalancing", region: region)
544
+ @@elb_api[region]
545
+ end
546
+
547
+ # Amazon's ElasticLoadBalancingV2 (ALB) API
548
+ def self.elb2(region = MU.curRegion)
549
+ region ||= myRegion
550
+ @@elb2_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "ElasticLoadBalancingV2", region: region)
551
+ @@elb2_api[region]
552
+ end
553
+
554
+ # Amazon's Route53 API
555
+ def self.route53(region = MU.curRegion)
556
+ region ||= myRegion
557
+ @@route53_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "Route53", region: region)
558
+ @@route53_api[region]
559
+ end
560
+
561
+ # Amazon's RDS API
562
+ def self.rds(region = MU.curRegion)
563
+ region ||= myRegion
564
+ @@rds_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "RDS", region: region)
565
+ @@rds_api[region]
566
+ end
567
+
568
+ # Amazon's CloudFormation API
569
+ def self.cloudformation(region = MU.curRegion)
570
+ region ||= myRegion
571
+ @@cloudformation_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "CloudFormation", region: region)
572
+ @@cloudformation_api[region]
573
+ end
574
+
575
+ # Amazon's S3 API
576
+ def self.s3(region = MU.curRegion)
577
+ region ||= myRegion
578
+ @@s3_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "S3", region: region)
579
+ @@s3_api[region]
580
+ end
581
+
582
+ # Amazon's CloudTrail API
583
+ def self.cloudtrail(region = MU.curRegion)
584
+ region ||= myRegion
585
+ @@cloudtrail_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "CloudTrail", region: region)
586
+ @@cloudtrail_api[region]
587
+ end
588
+
589
+ # Amazon's CloudWatch API
590
+ def self.cloudwatch(region = MU.curRegion)
591
+ region ||= myRegion
592
+ @@cloudwatch_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "CloudWatch", region: region)
593
+ @@cloudwatch_api[region]
594
+ end
595
+
596
+ # Amazon's Web Application Firewall API (Global, for CloudFront et al)
597
+ def self.wafglobal(region = MU.curRegion)
598
+ region ||= myRegion
599
+ @@wafglobal[region] ||= MU::Cloud::AWS::Endpoint.new(api: "WAF", region: region)
600
+ @@wafglobal[region]
601
+ end
602
+
603
+
604
+ # Amazon's Web Application Firewall API (Regional, for ALBs et al)
605
+ def self.waf(region = MU.curRegion)
606
+ region ||= myRegion
607
+ @@waf[region] ||= MU::Cloud::AWS::Endpoint.new(api: "WAFRegional", region: region)
608
+ @@waf[region]
609
+ end
610
+
611
+ # Amazon's CloudWatchLogs API
612
+ def self.cloudwatchlogs(region = MU.curRegion)
613
+ region ||= myRegion
614
+ @@cloudwatchlogs_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "CloudWatchLogs", region: region)
615
+ @@cloudwatchlogs_api[region]
616
+ end
617
+
618
+ # Amazon's CloudFront API
619
+ def self.cloudfront(region = MU.curRegion)
620
+ region ||= myRegion
621
+ @@cloudfront_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "CloudFront", region: region)
622
+ @@cloudfront_api[region]
623
+ end
624
+
625
+ # Amazon's ElastiCache API
626
+ def self.elasticache(region = MU.curRegion)
627
+ region ||= myRegion
628
+ @@elasticache_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "ElastiCache", region: region)
629
+ @@elasticache_api[region]
630
+ end
631
+
632
+ # Amazon's SNS API
633
+ def self.sns(region = MU.curRegion)
634
+ region ||= myRegion
635
+ @@sns_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "SNS", region: region)
636
+ @@sns_api[region]
637
+ end
638
+
639
+ # Amazon's SQS API
640
+ def self.sqs(region = MU.curRegion)
641
+ region ||= myRegion
642
+ @@sqs_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "SQS", region: region)
643
+ @@sqs_api[region]
644
+ end
645
+
646
+ # Amazon's EFS API
647
+ def self.efs(region = MU.curRegion)
648
+ region ||= myRegion
649
+ @@efs_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "EFS", region: region)
650
+ @@efs_api[region]
651
+ end
652
+
653
+ # Amazon's Lambda API
654
+ def self.lambda(region = MU.curRegion)
655
+ region ||= myRegion
656
+ @@lambda_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "Lambda", region: region)
657
+ @@lambda_api[region]
658
+ end
659
+
660
+ # Amazon's API Gateway API
661
+ def self.apig(region = MU.curRegion)
662
+ region ||= myRegion
663
+ @@apig_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "APIGateway", region: region)
664
+ @@apig_api[region]
665
+ end
666
+
667
+ # Amazon's Cloudwatch Events API
668
+ def self.cloudwatch_events(region = MU.cureRegion)
669
+ region ||= myRegion
670
+ @@cloudwatch_events_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "CloudWatchEvents", region: region)
671
+ @@cloudwatch_events_api
672
+ end
673
+
674
+ # Amazon's ECS API
675
+ def self.ecs(region = MU.curRegion)
676
+ region ||= myRegion
677
+ @@ecs_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "ECS", region: region)
678
+ @@ecs_api[region]
679
+ end
680
+
681
+ # Amazon's EKS API
682
+ def self.eks(region = MU.curRegion)
683
+ region ||= myRegion
684
+ @@eks_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "EKS", region: region)
685
+ @@eks_api[region]
686
+ end
687
+
688
+ # Amazon's Pricing API
689
+ def self.pricing(region = MU.curRegion)
690
+ region ||= myRegion
691
+ @@pricing_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "Pricing", region: region)
692
+ @@pricing_api[region]
693
+ end
694
+
695
+ # Amazon's Simple Systems Manager API
696
+ def self.ssm(region = MU.curRegion)
697
+ region ||= myRegion
698
+ @@ssm_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "SSM", region: region)
699
+ @@ssm_api[region]
700
+ end
701
+
702
+ # Amazon's Elasticsearch API
703
+ def self.elasticsearch(region = MU.curRegion)
704
+ region ||= myRegion
705
+ @@elasticsearch_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "ElasticsearchService", region: region)
706
+ @@elasticsearch_api[region]
707
+ end
708
+
709
+ # Amazon's Cognito Identity API
710
+ def self.cognito_ident(region = MU.curRegion)
711
+ region ||= myRegion
712
+ @@cognito_ident_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "CognitoIdentity", region: region)
713
+ @@cognito_ident_api[region]
714
+ end
715
+
716
+ # Amazon's Cognito Identity Provider API
717
+ def self.cognito_user(region = MU.curRegion)
718
+ region ||= myRegion
719
+ @@cognito_user_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "CognitoIdentityProvider", region: region)
720
+ @@cognito_user_api[region]
721
+ end
722
+
723
+ # Amazon's KMS API
724
+ def self.kms(region = MU.curRegion)
725
+ region ||= myRegion
726
+ @@kms_api[region] ||= MU::Cloud::AWS::Endpoint.new(api: "KMS", region: region)
727
+ @@kms_api[region]
728
+ end
729
+
730
+ # Fetch an Amazon instance metadata parameter (example: public-ipv4).
731
+ # @param param [String]: The parameter name to fetch
732
+ # @return [String, nil]
733
+ def self.getAWSMetaData(param)
734
+ base_url = "http://169.254.169.254/latest/meta-data/"
735
+ begin
736
+ response = nil
737
+ Timeout.timeout(2) do
738
+ response = open("#{base_url}/#{param}").read
739
+ end
740
+
741
+ response
742
+ rescue OpenURI::HTTPError, Timeout::Error, SocketError, Errno::ENETUNREACH, Net::HTTPServerException, Errno::EHOSTUNREACH => e
743
+ # This is fairly normal, just handle it gracefully
744
+ logger = MU::Logger.new
745
+ logger.log "Failed metadata request #{base_url}/#{param}: #{e.inspect}", MU::DEBUG
746
+ return nil
747
+ end
748
+ end
749
+
750
+ @syslog_port_semaphore = Mutex.new
751
+ # Punch AWS security group holes for client nodes to talk back to us, the
752
+ # Mu Master, if we're in AWS.
753
+ # @return [void]
754
+ def self.openFirewallForClients
755
+ MU::Cloud.loadCloudType("AWS", :FirewallRule)
756
+ if File.exists?(Etc.getpwuid(Process.uid).dir+"/.chef/knife.rb")
757
+ ::Chef::Config.from_file(Etc.getpwuid(Process.uid).dir+"/.chef/knife.rb")
758
+ end
759
+ ::Chef::Config[:environment] = MU.environment
760
+
761
+ # This is the set of (TCP) ports we're opening to clients. We assume that
762
+ # we can and and remove these without impacting anything a human has
763
+ # created.
764
+
765
+ my_ports = [10514]
766
+
767
+ my_instance_id = MU::Cloud::AWS.getAWSMetaData("instance-id")
768
+ my_client_sg_name = "Mu Client Rules for #{MU.mu_public_ip}"
769
+ my_sgs = Array.new
770
+
771
+ MU.setVar("curRegion", myRegion) if !myRegion.nil?
772
+
773
+ MU.myCloudDescriptor.security_groups.each { |sg|
774
+ my_sgs << sg.group_id
775
+ }
776
+ resp = MU::Cloud::AWS.ec2.describe_security_groups(
777
+ filters: [
778
+ {name: "tag:MU-MASTER-IP", values: [MU.mu_public_ip]},
779
+ {name: "tag:Name", values: [my_client_sg_name]}
780
+ ]
781
+ )
782
+
783
+ if resp.nil? or resp.security_groups.nil? or resp.security_groups.size == 0
784
+ if MU.myCloudDescriptor.vpc_id.nil?
785
+ sg_id = my_sgs.first
786
+ resp = MU::Cloud::AWS.ec2.describe_security_groups(group_ids: [sg_id])
787
+ group = resp.security_groups.first
788
+ MU.log "We don't have a security group named '#{my_client_sg_name}' available, and we are in EC2 Classic and so cannot create a new group. Defaulting to #{group.group_name}.", MU::NOTICE
789
+ else
790
+ group = MU::Cloud::AWS.ec2.create_security_group(
791
+ group_name: my_client_sg_name,
792
+ description: my_client_sg_name,
793
+ vpc_id: MU.myCloudDescriptor.vpc_id
794
+ )
795
+ sg_id = group.group_id
796
+ my_sgs << sg_id
797
+ MU::MommaCat.createTag sg_id, "Name", my_client_sg_name
798
+ MU::MommaCat.createTag sg_id, "MU-MASTER-IP", MU.mu_public_ip
799
+ MU::Cloud::AWS.ec2.modify_instance_attribute(
800
+ instance_id: my_instance_id,
801
+ groups: my_sgs
802
+ )
803
+ end
804
+ elsif resp.security_groups.size == 1
805
+ sg_id = resp.security_groups.first.group_id
806
+ resp = MU::Cloud::AWS.ec2.describe_security_groups(group_ids: [sg_id])
807
+ group = resp.security_groups.first
808
+ else
809
+ MU.log "Found more than one security group named #{my_client_sg_name}, aborting", MU::ERR
810
+ exit 1
811
+ end
812
+
813
+ if !my_sgs.include?(sg_id)
814
+ my_sgs << sg_id
815
+ MU.log "Associating #{my_client_sg_name} with #{MU.myInstanceId}", MU::NOTICE
816
+ MU::Cloud::AWS.ec2.modify_instance_attribute(
817
+ instance_id: MU.myInstanceId,
818
+ groups: my_sgs
819
+ )
820
+ end
821
+
822
+ begin
823
+ MU.log "Using AWS Security Group '#{group.group_name}' (#{sg_id})"
824
+ rescue NoMethodError
825
+ MU.log "Using AWS Security Group #{sg_id}"
826
+ end
827
+
828
+ allow_ips = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
829
+ MU::MommaCat.listAllNodes.each_pair { |node, data|
830
+ next if data.nil? or !data.is_a?(Hash)
831
+ ["public_ip_address"].each { |key|
832
+ if data.has_key?(key) and !data[key].nil? and !data[key].empty?
833
+ allow_ips << data[key] + "/32"
834
+ end
835
+ }
836
+ }
837
+ allow_ips.uniq!
838
+
839
+ @syslog_port_semaphore.synchronize {
840
+ my_ports.each { |port|
841
+ begin
842
+ group.ip_permissions.each { |rule|
843
+ if rule.ip_protocol == "tcp" and
844
+ rule.from_port == port and rule.to_port == port
845
+ MU.log "Revoking old rules for port #{port.to_s} from #{sg_id}", MU::NOTICE
846
+ begin
847
+ MU::Cloud::AWS.ec2(myRegion).revoke_security_group_ingress(
848
+ group_id: sg_id,
849
+ ip_permissions: [
850
+ {
851
+ ip_protocol: "tcp",
852
+ from_port: port,
853
+ to_port: port,
854
+ ip_ranges: MU.structToHash(rule.ip_ranges)
855
+ }
856
+ ]
857
+ )
858
+ rescue Aws::EC2::Errors::InvalidPermissionNotFound => e
859
+ MU.log "Permission disappeared from #{sg_id} (port #{port.to_s}) before I could remove it", MU::WARN, details: MU.structToHash(rule.ip_ranges)
860
+ end
861
+ end
862
+ }
863
+ rescue NoMethodError
864
+ # XXX this is ok
865
+ end
866
+ MU.log "Adding current IP list to allow rule for port #{port.to_s} in #{sg_id}", details: allow_ips
867
+
868
+ allow_ips_cidr = []
869
+ allow_ips.each { |cidr|
870
+ allow_ips_cidr << {"cidr_ip" => cidr}
871
+ }
872
+
873
+ begin
874
+ MU::Cloud::AWS.ec2(myRegion).authorize_security_group_ingress(
875
+ group_id: sg_id,
876
+ ip_permissions: [
877
+ {
878
+ ip_protocol: "tcp",
879
+ from_port: 10514,
880
+ to_port: 10514,
881
+ ip_ranges: allow_ips_cidr
882
+ }
883
+ ]
884
+ )
885
+ rescue Aws::EC2::Errors::InvalidPermissionDuplicate => e
886
+ MU.log "Got #{e.inspect} in MU::Cloud::AWS.openFirewallForClients", MU::WARN, details: allow_ips_cidr
887
+ end
888
+ }
889
+ }
890
+ end
891
+
892
+ private
893
+
894
+ # XXX we shouldn't have to do this, but AWS does not provide a way to look
895
+ # it up, and the pricing API only returns the human-readable strings.
896
+ @@regionLookup = {
897
+ "us-east-1" => "US East (N. Virginia)",
898
+ "us-east-2" => "US East (Ohio)",
899
+ "us-west-1" => "US West (N. California)",
900
+ "us-west-2" => "US West (Oregon)",
901
+ "us-gov-west-1" => "AWS GovCloud (US)",
902
+ "us-gov-east-1" => "AWS GovCloud (US)",
903
+ "ap-northeast-1" => "Asia Pacific (Tokyo)",
904
+ "ap-northeast-2" => "Asia Pacific (Seoul)",
905
+ "ap-south-1" => "Asia Pacific (Mumbai)",
906
+ "ap-southeast-1" => "Asia Pacific (Singapore)",
907
+ "ap-southeast-2" => "Asia Pacific (Sydney)",
908
+ "ca-central-1" => "Canada (Central)",
909
+ "eu-central-1" => "EU (Frankfurt)",
910
+ "eu-west-1" => "EU (Ireland)",
911
+ "eu-west-2" => "EU (London)",
912
+ "eu-west-3" => "EU (Paris)",
913
+ "sa-east-1" => "South America (Sao Paulo)"
914
+ }.freeze
915
+ @@regionNameLookup = @@regionLookup.invert.freeze
916
+
917
+ # Wrapper class for the EC2 API, so that we can catch some common transient
918
+ # endpoint errors without having to spray rescues all over the codebase.
919
+ class Endpoint
920
+ @api = nil
921
+ @region = nil
922
+
923
+ # Create an AWS API client
924
+ # @param region [String]: Amazon region so we know what endpoint to use
925
+ # @param api [String]: Which API are we wrapping?
926
+ def initialize(region: MU.curRegion, api: "EC2")
927
+ @region = region
928
+ if region
929
+ @api = Object.const_get("Aws::#{api}::Client").new(region: region)
930
+ else
931
+ @api = Object.const_get("Aws::#{api}::Client").new
932
+ end
933
+ end
934
+
935
+ @instance_cache = {}
936
+ # Catch-all for AWS client methods. Essentially a pass-through with some
937
+ # rescues for known silly endpoint behavior.
938
+ def method_missing(method_sym, *arguments)
939
+ MU::Cloud::AWS.loadCredentials
940
+ retries = 0
941
+ begin
942
+ MU.log "Calling #{method_sym} in #{@region}", MU::DEBUG, details: arguments
943
+ retval = nil
944
+ if !arguments.nil? and arguments.size == 1
945
+ retval = @api.method(method_sym).call(arguments[0])
946
+ elsif !arguments.nil? and arguments.size > 0
947
+ retval = @api.method(method_sym).call(*arguments)
948
+ else
949
+ retval = @api.method(method_sym).call
950
+ end
951
+ return retval
952
+ rescue Aws::EC2::Errors::InternalError, Aws::EC2::Errors::RequestLimitExceeded, Aws::EC2::Errors::Unavailable, Aws::Route53::Errors::Throttling, Aws::ElasticLoadBalancing::Errors::HttpFailureException, Aws::EC2::Errors::Http503Error, Aws::AutoScaling::Errors::Http503Error, Aws::AutoScaling::Errors::InternalFailure, Aws::AutoScaling::Errors::ServiceUnavailable, Aws::Route53::Errors::ServiceUnavailable, Aws::ElasticLoadBalancing::Errors::Throttling, Aws::RDS::Errors::ClientUnavailable, Aws::Waiters::Errors::UnexpectedError, Aws::ElasticLoadBalancing::Errors::ServiceUnavailable, Aws::ElasticLoadBalancingV2::Errors::Throttling, Seahorse::Client::NetworkingError, Aws::IAM::Errors::Throttling => e
953
+ if e.class.name == "Seahorse::Client::NetworkingError" and e.message.match(/Name or service not known/)
954
+ MU.log e.inspect, MU::ERR
955
+ raise e
956
+ end
957
+ retries = retries + 1
958
+ debuglevel = MU::DEBUG
959
+ interval = 5 + Random.rand(4) - 2
960
+ if retries < 10 and retries > 2
961
+ debuglevel = MU::NOTICE
962
+ interval = 20 + Random.rand(10) - 3
963
+ # elsif retries >= 10 and retries <= 100
964
+ elsif retries >= 10
965
+ debuglevel = MU::WARN
966
+ interval = 40 + Random.rand(15) - 5
967
+ # elsif retries > 100
968
+ # raise MuError, "Exhausted retries after #{retries} attempts while calling EC2's #{method_sym} in #{@region}. Args were: #{arguments}"
969
+ end
970
+ MU.log "Got #{e.inspect} calling EC2's #{method_sym} in #{@region}, waiting #{interval.to_s}s and retrying. Args were: #{arguments}", debuglevel, details: caller
971
+ sleep interval
972
+ retry
973
+ end
974
+ end
975
+ end
976
+ @@iam_api = {}
977
+ @@acm_api = {}
978
+ @@ec2_api = {}
979
+ @@autoscale_api = {}
980
+ @@elb_api = {}
981
+ @@elb2_api = {}
982
+ @@route53_api = {}
983
+ @@rds_api = {}
984
+ @@cloudformation_api = {}
985
+ @@s3_api = {}
986
+ @@cloudtrail_api = {}
987
+ @@cloudwatch_api = {}
988
+ @@wafglobal = {}
989
+ @@waf = {}
990
+ @@cloudwatchlogs_api = {}
991
+ @@cloudfront_api = {}
992
+ @@elasticache_api = {}
993
+ @@sns_api = {}
994
+ @@sqs_api = {}
995
+ @@efs_api ={}
996
+ @@lambda_api ={}
997
+ @@cloudwatch_events_api = {}
998
+ @@apig_api ={}
999
+ @@ecs_api ={}
1000
+ @@eks_api ={}
1001
+ @@pricing_api ={}
1002
+ @@ssm_api ={}
1003
+ @@elasticsearch_api ={}
1004
+ @@cognito_ident_api ={}
1005
+ @@cognito_user_api ={}
1006
+ @@kms_api ={}
1007
+ end
1008
+ end
1009
+ end