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.
- checksums.yaml +7 -0
- data/Berksfile +56 -0
- data/Berksfile.lock +250 -0
- data/Jenkinsfile +184 -0
- data/LICENSE.md +37 -0
- data/README.md +26 -0
- data/bin/mu-aws-setup +376 -0
- data/bin/mu-cleanup +68 -0
- data/bin/mu-configure +1133 -0
- data/bin/mu-deploy +166 -0
- data/bin/mu-firewall-allow-clients +30 -0
- data/bin/mu-gcp-setup +200 -0
- data/bin/mu-gen-docs +34 -0
- data/bin/mu-gen-env +42 -0
- data/bin/mu-load-config.rb +158 -0
- data/bin/mu-node-manage +683 -0
- data/bin/mu-self-update +228 -0
- data/bin/mu-ssh +23 -0
- data/bin/mu-tunnel-nagios +144 -0
- data/bin/mu-upload-chef-artifacts +757 -0
- data/bin/mu-user-manage +275 -0
- data/cookbooks/awscli/LICENSE +37 -0
- data/cookbooks/awscli/README.md +58 -0
- data/cookbooks/awscli/attributes/default.rb +1 -0
- data/cookbooks/awscli/libraries/instance_metadata.rb +21 -0
- data/cookbooks/awscli/metadata.rb +20 -0
- data/cookbooks/awscli/recipes/default.rb +56 -0
- data/cookbooks/awscli/templates/default/config.erb +18 -0
- data/cookbooks/mu-activedirectory/CHANGELOG.md +13 -0
- data/cookbooks/mu-activedirectory/LICENSE +37 -0
- data/cookbooks/mu-activedirectory/README.md +6 -0
- data/cookbooks/mu-activedirectory/attributes/default.rb +98 -0
- data/cookbooks/mu-activedirectory/files/default/password-auth +32 -0
- data/cookbooks/mu-activedirectory/files/default/sshd_pol.pp +0 -0
- data/cookbooks/mu-activedirectory/files/default/sshd_pol.te +32 -0
- data/cookbooks/mu-activedirectory/files/default/syslogd_oddjobd.pp +0 -0
- data/cookbooks/mu-activedirectory/files/default/syslogd_oddjobd.te +10 -0
- data/cookbooks/mu-activedirectory/files/default/system-auth +34 -0
- data/cookbooks/mu-activedirectory/files/default/winbindpol.pp +0 -0
- data/cookbooks/mu-activedirectory/files/default/winbindpol.te +37 -0
- data/cookbooks/mu-activedirectory/libraries/config.rb +106 -0
- data/cookbooks/mu-activedirectory/libraries/helper.rb +86 -0
- data/cookbooks/mu-activedirectory/metadata.rb +17 -0
- data/cookbooks/mu-activedirectory/providers/domain.rb +152 -0
- data/cookbooks/mu-activedirectory/providers/domain_controller.rb +89 -0
- data/cookbooks/mu-activedirectory/providers/domain_node.rb +275 -0
- data/cookbooks/mu-activedirectory/recipes/default.rb +8 -0
- data/cookbooks/mu-activedirectory/recipes/domain-controller.rb +44 -0
- data/cookbooks/mu-activedirectory/recipes/domain-node.rb +50 -0
- data/cookbooks/mu-activedirectory/recipes/domain.rb +43 -0
- data/cookbooks/mu-activedirectory/recipes/sssd.rb +185 -0
- data/cookbooks/mu-activedirectory/resources/domain.rb +25 -0
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +25 -0
- data/cookbooks/mu-activedirectory/resources/domain_node.rb +20 -0
- data/cookbooks/mu-activedirectory/templates/default/dhclient-eth0.conf.erb +4 -0
- data/cookbooks/mu-activedirectory/templates/default/interface +0 -0
- data/cookbooks/mu-activedirectory/templates/default/krb5.conf.erb +23 -0
- data/cookbooks/mu-activedirectory/templates/default/ntp.conf.erb +56 -0
- data/cookbooks/mu-activedirectory/templates/default/smb.conf.erb +33 -0
- data/cookbooks/mu-activedirectory/templates/default/sssd.conf.erb +60 -0
- data/cookbooks/mu-activedirectory/templates/windows/Backup.xml.erb +20 -0
- data/cookbooks/mu-activedirectory/templates/windows/bkupInfo.xml.erb +1 -0
- data/cookbooks/mu-activedirectory/templates/windows/gpreprt.xml.erb +198 -0
- data/cookbooks/mu-activedirectory/templates/windows/gptmpl.inf.erb +12 -0
- data/cookbooks/mu-activedirectory/templates/windows/manifest.xml.erb +1 -0
- data/cookbooks/mu-firewall/CHANGELOG.md +11 -0
- data/cookbooks/mu-firewall/LICENSE +37 -0
- data/cookbooks/mu-firewall/README.md +5 -0
- data/cookbooks/mu-firewall/attributes/default.rb +3 -0
- data/cookbooks/mu-firewall/metadata.rb +16 -0
- data/cookbooks/mu-firewall/recipes/default.rb +10 -0
- data/cookbooks/mu-glusterfs/CHANGELOG.md +13 -0
- data/cookbooks/mu-glusterfs/LICENSE +37 -0
- data/cookbooks/mu-glusterfs/README.md +5 -0
- data/cookbooks/mu-glusterfs/attributes/default.rb +34 -0
- data/cookbooks/mu-glusterfs/metadata.rb +17 -0
- data/cookbooks/mu-glusterfs/recipes/client.rb +62 -0
- data/cookbooks/mu-glusterfs/recipes/default.rb +16 -0
- data/cookbooks/mu-glusterfs/recipes/samba.rb +57 -0
- data/cookbooks/mu-glusterfs/recipes/server.rb +200 -0
- data/cookbooks/mu-glusterfs/templates/default/mu-gluster-client.erb +71 -0
- data/cookbooks/mu-glusterfs/templates/default/smb.conf.erb +14 -0
- data/cookbooks/mu-jenkins/CHANGELOG.md +13 -0
- data/cookbooks/mu-jenkins/LICENSE +37 -0
- data/cookbooks/mu-jenkins/README.md +105 -0
- data/cookbooks/mu-jenkins/attributes/default.rb +42 -0
- data/cookbooks/mu-jenkins/files/default/cleanup_deploy_config.xml +73 -0
- data/cookbooks/mu-jenkins/files/default/deploy_config.xml +44 -0
- data/cookbooks/mu-jenkins/metadata.rb +21 -0
- data/cookbooks/mu-jenkins/recipes/default.rb +195 -0
- data/cookbooks/mu-jenkins/recipes/node-ssh-config.rb +54 -0
- data/cookbooks/mu-jenkins/recipes/public_key.rb +24 -0
- data/cookbooks/mu-jenkins/templates/default/example_job.config.xml.erb +24 -0
- data/cookbooks/mu-jenkins/templates/default/org.jvnet.hudson.plugins.SSHBuildWrapper.xml.erb +14 -0
- data/cookbooks/mu-jenkins/templates/default/ssh_config.erb +6 -0
- data/cookbooks/mu-master/CHANGELOG.md +13 -0
- data/cookbooks/mu-master/LICENSE +37 -0
- data/cookbooks/mu-master/README.md +6 -0
- data/cookbooks/mu-master/attributes/default.rb +95 -0
- data/cookbooks/mu-master/files/default/0-mu-log-server.conf +19 -0
- data/cookbooks/mu-master/files/default/addRSA.ldif +8 -0
- data/cookbooks/mu-master/files/default/check_mem.pl +197 -0
- data/cookbooks/mu-master/files/default/cloudamatic.png +0 -0
- data/cookbooks/mu-master/files/default/dirsrv_admin.pp +0 -0
- data/cookbooks/mu-master/files/default/dirsrv_admin.te +13 -0
- data/cookbooks/mu-master/files/default/nagios_selinux.pp +0 -0
- data/cookbooks/mu-master/files/default/nagios_selinux.te +51 -0
- data/cookbooks/mu-master/files/default/nagios_selinux_7.pp +0 -0
- data/cookbooks/mu-master/files/default/nagios_selinux_7.te +17 -0
- data/cookbooks/mu-master/files/default/pam_sshd +18 -0
- data/cookbooks/mu-master/files/default/ssl_enable.ldif +18 -0
- data/cookbooks/mu-master/files/default/syslogd_oddjobd.pp +0 -0
- data/cookbooks/mu-master/files/default/syslogd_oddjobd.te +10 -0
- data/cookbooks/mu-master/files/default/vimrc +19 -0
- data/cookbooks/mu-master/libraries/mu.rb +29 -0
- data/cookbooks/mu-master/metadata.rb +30 -0
- data/cookbooks/mu-master/providers/user.rb +41 -0
- data/cookbooks/mu-master/recipes/389ds.rb +164 -0
- data/cookbooks/mu-master/recipes/basepackages.rb +58 -0
- data/cookbooks/mu-master/recipes/caching_nameserver.rb +37 -0
- data/cookbooks/mu-master/recipes/default.rb +451 -0
- data/cookbooks/mu-master/recipes/eks-kubectl.rb +41 -0
- data/cookbooks/mu-master/recipes/firewall-holes.rb +70 -0
- data/cookbooks/mu-master/recipes/init.rb +542 -0
- data/cookbooks/mu-master/recipes/ssl-certs.rb +109 -0
- data/cookbooks/mu-master/recipes/sssd.rb +89 -0
- data/cookbooks/mu-master/recipes/update_nagios_only.rb +242 -0
- data/cookbooks/mu-master/recipes/vault.rb +111 -0
- data/cookbooks/mu-master/resources/user.rb +19 -0
- data/cookbooks/mu-master/templates/default/389-directory-setup.inf.erb +28 -0
- data/cookbooks/mu-master/templates/default/chef-server.rb.erb +18 -0
- data/cookbooks/mu-master/templates/default/dhclient-eth0.conf.erb +9 -0
- data/cookbooks/mu-master/templates/default/mu-momma-cat.erb +149 -0
- data/cookbooks/mu-master/templates/default/mu.rc.erb +9 -0
- data/cookbooks/mu-master/templates/default/openssl.cnf.erb +354 -0
- data/cookbooks/mu-master/templates/default/sssd.conf.erb +44 -0
- data/cookbooks/mu-master/templates/default/web_app.conf.erb +90 -0
- data/cookbooks/mu-mongo/CHANGELOG.md +13 -0
- data/cookbooks/mu-mongo/LICENSE +37 -0
- data/cookbooks/mu-mongo/README.md +5 -0
- data/cookbooks/mu-mongo/attributes/default.rb +22 -0
- data/cookbooks/mu-mongo/files/default/keyfile +16 -0
- data/cookbooks/mu-mongo/files/default/remove_nodes.js +5 -0
- data/cookbooks/mu-mongo/metadata.rb +17 -0
- data/cookbooks/mu-mongo/recipes/default.rb +149 -0
- data/cookbooks/mu-mongo/recipes/yum-update-rule.rb +18 -0
- data/cookbooks/mu-mongo/templates/default/mongo_create_openfema_db.js.erb +2 -0
- data/cookbooks/mu-mongo/templates/default/mongo_init.js.erb +1 -0
- data/cookbooks/mu-mongo/templates/default/mongo_logrotate.erb +14 -0
- data/cookbooks/mu-mongo/templates/default/mongo_replset_addnodes.js.erb +6 -0
- data/cookbooks/mu-mongo/templates/default/replset_init.js.erb +2 -0
- data/cookbooks/mu-openvpn/CHANGELOG.md +13 -0
- data/cookbooks/mu-openvpn/LICENSE +37 -0
- data/cookbooks/mu-openvpn/README.md +6 -0
- data/cookbooks/mu-openvpn/attributes/default.rb +119 -0
- data/cookbooks/mu-openvpn/metadata.rb +18 -0
- data/cookbooks/mu-openvpn/recipes/default.rb +108 -0
- data/cookbooks/mu-openvpn/templates/default/users.json.erb +42 -0
- data/cookbooks/mu-php54/CHANGELOG.md +12 -0
- data/cookbooks/mu-php54/LICENSE +37 -0
- data/cookbooks/mu-php54/README.md +0 -0
- data/cookbooks/mu-php54/files/centos/php.ini +1802 -0
- data/cookbooks/mu-php54/files/ubuntu/php.ini +1870 -0
- data/cookbooks/mu-php54/metadata.rb +21 -0
- data/cookbooks/mu-php54/recipes/default.rb +97 -0
- data/cookbooks/mu-splunk/CHANGELOG.md +37 -0
- data/cookbooks/mu-splunk/LICENSE +37 -0
- data/cookbooks/mu-splunk/README.md +451 -0
- data/cookbooks/mu-splunk/attributes/default.rb +95 -0
- data/cookbooks/mu-splunk/attributes/upgrade.rb +49 -0
- data/cookbooks/mu-splunk/definitions/splunk_installer.rb +103 -0
- data/cookbooks/mu-splunk/files/default/splunk-nocheck +10 -0
- data/cookbooks/mu-splunk/libraries/helpers.rb +72 -0
- data/cookbooks/mu-splunk/libraries/splunk_app_provider.rb +156 -0
- data/cookbooks/mu-splunk/libraries/splunk_app_resource.rb +43 -0
- data/cookbooks/mu-splunk/metadata.json +30 -0
- data/cookbooks/mu-splunk/metadata.rb +17 -0
- data/cookbooks/mu-splunk/recipes/client.rb +143 -0
- data/cookbooks/mu-splunk/recipes/default.rb +31 -0
- data/cookbooks/mu-splunk/recipes/disabled.rb +41 -0
- data/cookbooks/mu-splunk/recipes/install_forwarder.rb +23 -0
- data/cookbooks/mu-splunk/recipes/install_server.rb +23 -0
- data/cookbooks/mu-splunk/recipes/server.rb +53 -0
- data/cookbooks/mu-splunk/recipes/service.rb +95 -0
- data/cookbooks/mu-splunk/recipes/setup_auth.rb +49 -0
- data/cookbooks/mu-splunk/recipes/setup_ssl.rb +63 -0
- data/cookbooks/mu-splunk/recipes/upgrade.rb +94 -0
- data/cookbooks/mu-splunk/recipes/user.rb +34 -0
- data/cookbooks/mu-splunk/templates/default/base_logs_unix_inputs.conf.erb +26 -0
- data/cookbooks/mu-splunk/templates/default/inputs.conf.erb +13 -0
- data/cookbooks/mu-splunk/templates/default/outputs.conf.erb +9 -0
- data/cookbooks/mu-splunk/templates/default/splunk-init.erb +74 -0
- data/cookbooks/mu-splunk/templates/default/system-web.conf.erb +7 -0
- data/cookbooks/mu-tools/CHANGELOG.md +12 -0
- data/cookbooks/mu-tools/LICENSE +37 -0
- data/cookbooks/mu-tools/README.md +188 -0
- data/cookbooks/mu-tools/attributes/default.rb +142 -0
- data/cookbooks/mu-tools/attributes/ebs_rolling_snapshots.rb +3 -0
- data/cookbooks/mu-tools/files/amazon/etc/freshclam.conf +235 -0
- data/cookbooks/mu-tools/files/centos/CentOS-Base.repo +52 -0
- data/cookbooks/mu-tools/files/centos/etc/bashrc +93 -0
- data/cookbooks/mu-tools/files/centos/etc/freshclam.conf +235 -0
- data/cookbooks/mu-tools/files/centos/etc/login.defs +72 -0
- data/cookbooks/mu-tools/files/centos/etc/profile +77 -0
- data/cookbooks/mu-tools/files/centos/etc/security/limits.conf +57 -0
- data/cookbooks/mu-tools/files/centos/etc/sysconfig/init +19 -0
- data/cookbooks/mu-tools/files/centos/etc/sysctl.conf +82 -0
- data/cookbooks/mu-tools/files/centos-6/README_MU +0 -0
- data/cookbooks/mu-tools/files/centos-6/etc/audit/stig.rules +173 -0
- data/cookbooks/mu-tools/files/centos-6/etc/bashrc +90 -0
- data/cookbooks/mu-tools/files/centos-6/etc/login.defs +70 -0
- data/cookbooks/mu-tools/files/centos-6/etc/pam.d/su +12 -0
- data/cookbooks/mu-tools/files/centos-6/etc/profile +83 -0
- data/cookbooks/mu-tools/files/centos-6/etc/securetty +12 -0
- data/cookbooks/mu-tools/files/centos-6/etc/sysconfig/init +30 -0
- data/cookbooks/mu-tools/files/centos-6/etc/sysctl.conf +40 -0
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +34 -0
- data/cookbooks/mu-tools/files/default/PSWindowsUpdate.zip +0 -0
- data/cookbooks/mu-tools/files/default/ebs_snapshots.py +123 -0
- data/cookbooks/mu-tools/files/default/etc/BANNER +0 -0
- data/cookbooks/mu-tools/files/default/etc/BANNER-FEDERAL +19 -0
- data/cookbooks/mu-tools/files/default/gpo_no_uac.zip +0 -0
- data/cookbooks/mu-tools/files/default/mypol.pp +0 -0
- data/cookbooks/mu-tools/files/default/mypol.te +37 -0
- data/cookbooks/mu-tools/files/default/nrpe_c7.pp +0 -0
- data/cookbooks/mu-tools/files/default/nrpe_c7.te +31 -0
- data/cookbooks/mu-tools/files/default/nrpe_check_disk.pp +0 -0
- data/cookbooks/mu-tools/files/default/nrpe_check_disk.te +11 -0
- data/cookbooks/mu-tools/files/default/nrpe_disk.pp +0 -0
- data/cookbooks/mu-tools/files/default/nrpe_disk.te +10 -0
- data/cookbooks/mu-tools/files/default/nrpe_file.pp +0 -0
- data/cookbooks/mu-tools/files/default/nrpe_file.te +31 -0
- data/cookbooks/mu-tools/files/default/ntrights +0 -0
- data/cookbooks/mu-tools/files/default/serverclass.conf +18 -0
- data/cookbooks/mu-tools/files/default/splunk-apps/base_logs_unix/local/app.conf +1 -0
- data/cookbooks/mu-tools/files/default/splunk-apps/base_logs_unix/local/inputs.conf +13 -0
- data/cookbooks/mu-tools/files/default/splunk-apps/base_logs_windows/local/app.conf +1 -0
- data/cookbooks/mu-tools/files/default/splunk-apps/base_logs_windows/local/inputs.conf +8 -0
- data/cookbooks/mu-tools/files/default/sshd_pol.pp +0 -0
- data/cookbooks/mu-tools/files/default/sshd_pol.te +32 -0
- data/cookbooks/mu-tools/files/redhat/etc/bashrc +93 -0
- data/cookbooks/mu-tools/files/redhat/etc/freshclam.conf +235 -0
- data/cookbooks/mu-tools/files/redhat/etc/login.defs +72 -0
- data/cookbooks/mu-tools/files/redhat/etc/profile +77 -0
- data/cookbooks/mu-tools/files/redhat/etc/security/limits.conf +57 -0
- data/cookbooks/mu-tools/files/redhat/etc/sysconfig/init +19 -0
- data/cookbooks/mu-tools/files/redhat/etc/sysctl.conf +82 -0
- data/cookbooks/mu-tools/files/redhat-6/README_MU +0 -0
- data/cookbooks/mu-tools/files/redhat-6/etc/audit/stig.rules +173 -0
- data/cookbooks/mu-tools/files/redhat-6/etc/bashrc +90 -0
- data/cookbooks/mu-tools/files/redhat-6/etc/login.defs +70 -0
- data/cookbooks/mu-tools/files/redhat-6/etc/pam.d/su +12 -0
- data/cookbooks/mu-tools/files/redhat-6/etc/profile +83 -0
- data/cookbooks/mu-tools/files/redhat-6/etc/securetty +12 -0
- data/cookbooks/mu-tools/files/redhat-6/etc/sysconfig/init +30 -0
- data/cookbooks/mu-tools/files/redhat-6/etc/sysctl.conf +40 -0
- data/cookbooks/mu-tools/files/redhat-7.1/etc/freshclam.conf +235 -0
- data/cookbooks/mu-tools/files/ubuntu-12.04/etc/bash.bashrc +64 -0
- data/cookbooks/mu-tools/files/ubuntu-12.04/etc/common-session +30 -0
- data/cookbooks/mu-tools/files/ubuntu-12.04/etc/login.defs +338 -0
- data/cookbooks/mu-tools/files/ubuntu-12.04/etc/profile +30 -0
- data/cookbooks/mu-tools/files/ubuntu-12.04/etc/security/limits.conf +56 -0
- data/cookbooks/mu-tools/files/ubuntu-12.04/etc/sysctl.conf +60 -0
- data/cookbooks/mu-tools/libraries/helper.rb +292 -0
- data/cookbooks/mu-tools/metadata.rb +28 -0
- data/cookbooks/mu-tools/recipes/add_admin_ssh_keys.rb +35 -0
- data/cookbooks/mu-tools/recipes/apply_security.rb +440 -0
- data/cookbooks/mu-tools/recipes/aws_api.rb +23 -0
- data/cookbooks/mu-tools/recipes/base_repositories.rb +31 -0
- data/cookbooks/mu-tools/recipes/cisbenchmark.rb +59 -0
- data/cookbooks/mu-tools/recipes/clamav.rb +53 -0
- data/cookbooks/mu-tools/recipes/cloudinit.rb +58 -0
- data/cookbooks/mu-tools/recipes/configure_oracle_tools.rb +81 -0
- data/cookbooks/mu-tools/recipes/disable-requiretty.rb +22 -0
- data/cookbooks/mu-tools/recipes/ebs_rolling_snapshots.rb +75 -0
- data/cookbooks/mu-tools/recipes/efs.rb +70 -0
- data/cookbooks/mu-tools/recipes/eks.rb +160 -0
- data/cookbooks/mu-tools/recipes/gcloud.rb +98 -0
- data/cookbooks/mu-tools/recipes/google_api.rb +25 -0
- data/cookbooks/mu-tools/recipes/maldet.rb +67 -0
- data/cookbooks/mu-tools/recipes/nagios.rb +19 -0
- data/cookbooks/mu-tools/recipes/newclient.rb +23 -0
- data/cookbooks/mu-tools/recipes/nrpe.rb +115 -0
- data/cookbooks/mu-tools/recipes/python_pip.rb +35 -0
- data/cookbooks/mu-tools/recipes/retrieve_application.rb +51 -0
- data/cookbooks/mu-tools/recipes/rsyslog.rb +65 -0
- data/cookbooks/mu-tools/recipes/set_local_fw.rb +57 -0
- data/cookbooks/mu-tools/recipes/set_mu_hostname.rb +81 -0
- data/cookbooks/mu-tools/recipes/split_var_partitions.rb +86 -0
- data/cookbooks/mu-tools/recipes/splunk-client.rb +69 -0
- data/cookbooks/mu-tools/recipes/splunk-server.rb +104 -0
- data/cookbooks/mu-tools/recipes/store_inspec_attr.rb +8 -0
- data/cookbooks/mu-tools/recipes/updates.rb +96 -0
- data/cookbooks/mu-tools/recipes/windows-client.rb +202 -0
- data/cookbooks/mu-tools/resources/aws_windows.rb +33 -0
- data/cookbooks/mu-tools/resources/disk.rb +88 -0
- data/cookbooks/mu-tools/resources/mommacat_request.rb +11 -0
- data/cookbooks/mu-tools/resources/scheduled_tasks.rb +29 -0
- data/cookbooks/mu-tools/resources/sshd_service.rb +45 -0
- data/cookbooks/mu-tools/resources/windows_users.rb +242 -0
- data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +168 -0
- data/cookbooks/mu-tools/templates/centos-6/sshd_config.erb +212 -0
- data/cookbooks/mu-tools/templates/centos-7/sshd_config.erb +215 -0
- data/cookbooks/mu-tools/templates/default/0-mu-log-client.conf.erb +13 -0
- data/cookbooks/mu-tools/templates/default/conf.maldet.erb +137 -0
- data/cookbooks/mu-tools/templates/default/etc_hosts.erb +30 -0
- data/cookbooks/mu-tools/templates/default/etc_pamd_password-auth.erb +14 -0
- data/cookbooks/mu-tools/templates/default/etc_pamd_system-auth.erb +14 -0
- data/cookbooks/mu-tools/templates/default/etc_sysconfig_network.erb +12 -0
- data/cookbooks/mu-tools/templates/default/kubeconfig.erb +29 -0
- data/cookbooks/mu-tools/templates/default/kubelet.service.erb +35 -0
- data/cookbooks/mu-tools/templates/default/maldet_scanall.sh.erb +15 -0
- data/cookbooks/mu-tools/templates/default/nrpe.cfg.erb +233 -0
- data/cookbooks/mu-tools/templates/redhat-6/sshd_config.erb +213 -0
- data/cookbooks/mu-tools/templates/redhat-7/sshd_config.erb +215 -0
- data/cookbooks/mu-tools/templates/ubuntu-12.04/sshd_config.erb +146 -0
- data/cookbooks/mu-tools/templates/ubuntu-14.04/sshd_config.erb +145 -0
- data/cookbooks/mu-tools/templates/windows/Backup.xml.erb +20 -0
- data/cookbooks/mu-tools/templates/windows/bkupInfo.xml.erb +1 -0
- data/cookbooks/mu-tools/templates/windows/gpreprt.xml.erb +214 -0
- data/cookbooks/mu-tools/templates/windows/gptmpl.inf.erb +12 -0
- data/cookbooks/mu-tools/templates/windows/manifest.xml.erb +1 -0
- data/cookbooks/mu-tools/templates/windows/set_ad_dns_scheduled_task.ps1.erb +6 -0
- data/cookbooks/mu-tools/templates/windows/sshd_config.erb +136 -0
- data/cookbooks/mu-utility/CHANGELOG.md +12 -0
- data/cookbooks/mu-utility/LICENSE +37 -0
- data/cookbooks/mu-utility/README.md +6 -0
- data/cookbooks/mu-utility/attributes/default.rb +1 -0
- data/cookbooks/mu-utility/libraries/matchers.rb +21 -0
- data/cookbooks/mu-utility/metadata.rb +16 -0
- data/cookbooks/mu-utility/recipes/apt.rb +23 -0
- data/cookbooks/mu-utility/recipes/cleanup_image_helper.rb +118 -0
- data/cookbooks/mu-utility/recipes/iptables.rb +26 -0
- data/cookbooks/mu-utility/recipes/luks.rb +18 -0
- data/cookbooks/mu-utility/recipes/nat.rb +104 -0
- data/cookbooks/mu-utility/recipes/php.rb +33 -0
- data/cookbooks/mu-utility/recipes/rdp_gateway.rb +83 -0
- data/cookbooks/mu-utility/recipes/remi.rb +44 -0
- data/cookbooks/mu-utility/recipes/vim.rb +26 -0
- data/cookbooks/mu-utility/recipes/windows_basics.rb +37 -0
- data/cookbooks/mu-utility/recipes/zip.rb +26 -0
- data/cookbooks/mu-utility/templates/default/BundleConfig.xml.erb +34 -0
- data/cookbooks/mu-utility/templates/default/config.xml.erb +60 -0
- data/cookbooks/nagios/Berksfile +8 -0
- data/cookbooks/nagios/CHANGELOG.md +589 -0
- data/cookbooks/nagios/CONTRIBUTING.md +11 -0
- data/cookbooks/nagios/LICENSE +37 -0
- data/cookbooks/nagios/README.md +328 -0
- data/cookbooks/nagios/TESTING.md +2 -0
- data/cookbooks/nagios/attributes/config.rb +171 -0
- data/cookbooks/nagios/attributes/default.rb +228 -0
- data/cookbooks/nagios/chefignore +102 -0
- data/cookbooks/nagios/definitions/command.rb +33 -0
- data/cookbooks/nagios/definitions/contact.rb +33 -0
- data/cookbooks/nagios/definitions/contactgroup.rb +33 -0
- data/cookbooks/nagios/definitions/host.rb +33 -0
- data/cookbooks/nagios/definitions/hostdependency.rb +33 -0
- data/cookbooks/nagios/definitions/hostescalation.rb +34 -0
- data/cookbooks/nagios/definitions/hostgroup.rb +33 -0
- data/cookbooks/nagios/definitions/nagios_conf.rb +38 -0
- data/cookbooks/nagios/definitions/resource.rb +33 -0
- data/cookbooks/nagios/definitions/service.rb +33 -0
- data/cookbooks/nagios/definitions/servicedependency.rb +33 -0
- data/cookbooks/nagios/definitions/serviceescalation.rb +34 -0
- data/cookbooks/nagios/definitions/servicegroup.rb +33 -0
- data/cookbooks/nagios/definitions/timeperiod.rb +33 -0
- data/cookbooks/nagios/libraries/base.rb +314 -0
- data/cookbooks/nagios/libraries/command.rb +91 -0
- data/cookbooks/nagios/libraries/contact.rb +230 -0
- data/cookbooks/nagios/libraries/contactgroup.rb +112 -0
- data/cookbooks/nagios/libraries/custom_option.rb +36 -0
- data/cookbooks/nagios/libraries/data_bag_helper.rb +23 -0
- data/cookbooks/nagios/libraries/default.rb +90 -0
- data/cookbooks/nagios/libraries/host.rb +412 -0
- data/cookbooks/nagios/libraries/hostdependency.rb +181 -0
- data/cookbooks/nagios/libraries/hostescalation.rb +173 -0
- data/cookbooks/nagios/libraries/hostgroup.rb +119 -0
- data/cookbooks/nagios/libraries/nagios.rb +282 -0
- data/cookbooks/nagios/libraries/resource.rb +59 -0
- data/cookbooks/nagios/libraries/service.rb +455 -0
- data/cookbooks/nagios/libraries/servicedependency.rb +215 -0
- data/cookbooks/nagios/libraries/serviceescalation.rb +195 -0
- data/cookbooks/nagios/libraries/servicegroup.rb +144 -0
- data/cookbooks/nagios/libraries/timeperiod.rb +160 -0
- data/cookbooks/nagios/libraries/users_helper.rb +54 -0
- data/cookbooks/nagios/metadata.rb +25 -0
- data/cookbooks/nagios/recipes/_load_databag_config.rb +153 -0
- data/cookbooks/nagios/recipes/_load_default_config.rb +241 -0
- data/cookbooks/nagios/recipes/apache.rb +48 -0
- data/cookbooks/nagios/recipes/default.rb +204 -0
- data/cookbooks/nagios/recipes/nginx.rb +82 -0
- data/cookbooks/nagios/recipes/pagerduty.rb +143 -0
- data/cookbooks/nagios/recipes/server_package.rb +40 -0
- data/cookbooks/nagios/recipes/server_source.rb +164 -0
- data/cookbooks/nagios/templates/default/apache2.conf.erb +96 -0
- data/cookbooks/nagios/templates/default/cgi.cfg.erb +266 -0
- data/cookbooks/nagios/templates/default/commands.cfg.erb +13 -0
- data/cookbooks/nagios/templates/default/contacts.cfg.erb +37 -0
- data/cookbooks/nagios/templates/default/hostgroups.cfg.erb +25 -0
- data/cookbooks/nagios/templates/default/hosts.cfg.erb +15 -0
- data/cookbooks/nagios/templates/default/htpasswd.users.erb +6 -0
- data/cookbooks/nagios/templates/default/nagios.cfg.erb +22 -0
- data/cookbooks/nagios/templates/default/nginx.conf.erb +62 -0
- data/cookbooks/nagios/templates/default/pagerduty.cgi.erb +185 -0
- data/cookbooks/nagios/templates/default/resource.cfg.erb +27 -0
- data/cookbooks/nagios/templates/default/servicedependencies.cfg.erb +15 -0
- data/cookbooks/nagios/templates/default/servicegroups.cfg.erb +14 -0
- data/cookbooks/nagios/templates/default/services.cfg.erb +14 -0
- data/cookbooks/nagios/templates/default/templates.cfg.erb +31 -0
- data/cookbooks/nagios/templates/default/timeperiods.cfg.erb +13 -0
- data/cookbooks/s3fs/CHANGELOG.md +13 -0
- data/cookbooks/s3fs/LICENSE +37 -0
- data/cookbooks/s3fs/README.md +6 -0
- data/cookbooks/s3fs/attributes/default.rb +15 -0
- data/cookbooks/s3fs/files/default/fuse-2.9.3.zip +0 -0
- data/cookbooks/s3fs/metadata.rb +16 -0
- data/cookbooks/s3fs/recipes/default.rb +91 -0
- data/data_bags/demo/app.json +7 -0
- data/data_bags/nagios_services/chef.json +6 -0
- data/data_bags/nagios_services/linux_diskspace.json +5 -0
- data/data_bags/nagios_services/momma_cat.json +6 -0
- data/data_bags/nagios_services/mu-master-memory.json +5 -0
- data/data_bags/nagios_services/nagios_ui.json +6 -0
- data/data_bags/nagios_services/node_ssh.json +6 -0
- data/data_bags/nagios_services/ssh.json +6 -0
- data/demo/lambda_test.yaml +29 -0
- data/environments/DEV.json +8 -0
- data/environments/PROD.json +8 -0
- data/environments/dev.json +8 -0
- data/environments/development.json +8 -0
- data/environments/prod.json +8 -0
- data/extras/README.md +1 -0
- data/extras/admin-role-binding.yaml +16 -0
- data/extras/admin-user.yaml +6 -0
- data/extras/aws-auth-cm.yaml.erb +12 -0
- data/extras/clean-stock-amis +48 -0
- data/extras/git-fix-permissions-hook +12 -0
- data/extras/gitlab-eks-helper.sh.erb +20 -0
- data/extras/image-generators/README.md +2 -0
- data/extras/image-generators/aws/centos6.yaml +18 -0
- data/extras/image-generators/aws/centos7-govcloud.yaml +24 -0
- data/extras/image-generators/aws/centos7.yaml +17 -0
- data/extras/image-generators/aws/rhel7.yaml +17 -0
- data/extras/image-generators/aws/win2k12.yaml +16 -0
- data/extras/image-generators/aws/win2k16.yaml +16 -0
- data/extras/image-generators/aws/windows.yaml +18 -0
- data/extras/image-generators/gcp/centos6.yaml +17 -0
- data/extras/lambda_waf_domain_blacklist.py +103 -0
- data/extras/platform_berksfile_base +50 -0
- data/extras/ruby_rpm/build.sh +17 -0
- data/extras/ruby_rpm/muby.spec +44 -0
- data/extras/vault_tools/README.md +6 -0
- data/extras/vault_tools/export_vaults.sh +3 -0
- data/extras/vault_tools/recreate_vaults.sh +5 -0
- data/extras/vault_tools/test_vaults.sh +5 -0
- data/install/README.md +8 -0
- data/install/cfn_create_mu_master.json +1034 -0
- data/install/chef-server.rb.erb +19 -0
- data/install/deprecated-bash-library.sh +1891 -0
- data/install/images/Usage.png +0 -0
- data/install/installer +71 -0
- data/install/jenkinskeys.rb +8 -0
- data/install/user-dot-murc.erb +14 -0
- data/modules/html.erb +19 -0
- data/modules/mommacat.ru +426 -0
- data/modules/mu/cleanup.rb +339 -0
- data/modules/mu/cloud.rb +1446 -0
- data/modules/mu/clouds/README.md +201 -0
- data/modules/mu/clouds/aws/alarm.rb +319 -0
- data/modules/mu/clouds/aws/cache_cluster.rb +1010 -0
- data/modules/mu/clouds/aws/collection.rb +373 -0
- data/modules/mu/clouds/aws/container_cluster.rb +667 -0
- data/modules/mu/clouds/aws/database.rb +1836 -0
- data/modules/mu/clouds/aws/dnszone.rb +911 -0
- data/modules/mu/clouds/aws/firewall_rule.rb +641 -0
- data/modules/mu/clouds/aws/folder.rb +92 -0
- data/modules/mu/clouds/aws/function.rb +349 -0
- data/modules/mu/clouds/aws/group.rb +251 -0
- data/modules/mu/clouds/aws/loadbalancer.rb +888 -0
- data/modules/mu/clouds/aws/log.rb +363 -0
- data/modules/mu/clouds/aws/msg_queue.rb +480 -0
- data/modules/mu/clouds/aws/notification.rb +139 -0
- data/modules/mu/clouds/aws/role.rb +656 -0
- data/modules/mu/clouds/aws/search_domain.rb +646 -0
- data/modules/mu/clouds/aws/server.rb +2294 -0
- data/modules/mu/clouds/aws/server_pool.rb +1388 -0
- data/modules/mu/clouds/aws/storage_pool.rb +495 -0
- data/modules/mu/clouds/aws/user.rb +382 -0
- data/modules/mu/clouds/aws/userdata/README.md +4 -0
- data/modules/mu/clouds/aws/userdata/linux.erb +179 -0
- data/modules/mu/clouds/aws/userdata/windows.erb +278 -0
- data/modules/mu/clouds/aws/vpc.rb +1943 -0
- data/modules/mu/clouds/aws.rb +1009 -0
- data/modules/mu/clouds/cloudformation/alarm.rb +146 -0
- data/modules/mu/clouds/cloudformation/cache_cluster.rb +167 -0
- data/modules/mu/clouds/cloudformation/collection.rb +117 -0
- data/modules/mu/clouds/cloudformation/database.rb +278 -0
- data/modules/mu/clouds/cloudformation/dnszone.rb +274 -0
- data/modules/mu/clouds/cloudformation/firewall_rule.rb +308 -0
- data/modules/mu/clouds/cloudformation/loadbalancer.rb +193 -0
- data/modules/mu/clouds/cloudformation/log.rb +170 -0
- data/modules/mu/clouds/cloudformation/server.rb +370 -0
- data/modules/mu/clouds/cloudformation/server_pool.rb +279 -0
- data/modules/mu/clouds/cloudformation/vpc.rb +322 -0
- data/modules/mu/clouds/cloudformation.rb +733 -0
- data/modules/mu/clouds/docker.rb +30 -0
- data/modules/mu/clouds/google/container_cluster.rb +290 -0
- data/modules/mu/clouds/google/database.rb +152 -0
- data/modules/mu/clouds/google/firewall_rule.rb +267 -0
- data/modules/mu/clouds/google/group.rb +164 -0
- data/modules/mu/clouds/google/loadbalancer.rb +479 -0
- data/modules/mu/clouds/google/server.rb +1510 -0
- data/modules/mu/clouds/google/server_pool.rb +274 -0
- data/modules/mu/clouds/google/user.rb +266 -0
- data/modules/mu/clouds/google/userdata/README.md +4 -0
- data/modules/mu/clouds/google/userdata/linux.erb +137 -0
- data/modules/mu/clouds/google/userdata/windows.erb +275 -0
- data/modules/mu/clouds/google/vpc.rb +890 -0
- data/modules/mu/clouds/google.rb +811 -0
- data/modules/mu/config/README.md +11 -0
- data/modules/mu/config/alarm.rb +271 -0
- data/modules/mu/config/cache_cluster.rb +172 -0
- data/modules/mu/config/collection.rb +87 -0
- data/modules/mu/config/container_cluster.rb +103 -0
- data/modules/mu/config/container_cluster.yml +36 -0
- data/modules/mu/config/database.rb +458 -0
- data/modules/mu/config/database.yml +26 -0
- data/modules/mu/config/dnszone.rb +327 -0
- data/modules/mu/config/firewall_rule.rb +118 -0
- data/modules/mu/config/folder.rb +70 -0
- data/modules/mu/config/function.rb +140 -0
- data/modules/mu/config/group.rb +64 -0
- data/modules/mu/config/loadbalancer.rb +482 -0
- data/modules/mu/config/log.rb +47 -0
- data/modules/mu/config/log.yml +6 -0
- data/modules/mu/config/msg_queue.rb +47 -0
- data/modules/mu/config/msg_queue.yml +9 -0
- data/modules/mu/config/notification.rb +44 -0
- data/modules/mu/config/project.rb +71 -0
- data/modules/mu/config/role.rb +102 -0
- data/modules/mu/config/search_domain.rb +61 -0
- data/modules/mu/config/search_domain.yml +25 -0
- data/modules/mu/config/server.rb +587 -0
- data/modules/mu/config/server.yml +8 -0
- data/modules/mu/config/server_pool.rb +216 -0
- data/modules/mu/config/server_pool.yml +71 -0
- data/modules/mu/config/storage_pool.rb +145 -0
- data/modules/mu/config/user.rb +78 -0
- data/modules/mu/config/vpc.rb +743 -0
- data/modules/mu/config/vpc.yml +6 -0
- data/modules/mu/config.rb +2000 -0
- data/modules/mu/defaults/README.md +2 -0
- data/modules/mu/defaults/amazon_images.yaml +121 -0
- data/modules/mu/defaults/google_images.yaml +16 -0
- data/modules/mu/deploy.rb +686 -0
- data/modules/mu/groomer.rb +123 -0
- data/modules/mu/groomers/README.md +58 -0
- data/modules/mu/groomers/chef.rb +1024 -0
- data/modules/mu/kittens.rb +11319 -0
- data/modules/mu/logger.rb +208 -0
- data/modules/mu/master/README.md +27 -0
- data/modules/mu/master/chef.rb +471 -0
- data/modules/mu/master/ldap.rb +1005 -0
- data/modules/mu/master.rb +415 -0
- data/modules/mu/mommacat.rb +2703 -0
- data/modules/mu-load-config.rb +1 -0
- data/modules/mu.rb +724 -0
- data/modules/scratchpad.erb +1 -0
- data/modules/tests/super_complex_bok.yml +41 -0
- data/modules/tests/super_simple_bok.yml +40 -0
- data/mu.gemspec +62 -0
- data/roles/demo-dbservice-configure.json +19 -0
- data/roles/demo-portal-configure.json +19 -0
- data/roles/mu-master-jenkins.json +24 -0
- data/roles/mu-master-nagios-only.json +13 -0
- data/roles/mu-master.json +12 -0
- data/roles/mu-node.json +19 -0
- data/roles/mu-splunk-server.json +13 -0
- data/roles/mu-splunk.json +13 -0
- data/test/clean_up.py +25 -0
- data/test/demo-test-profile/README.md +3 -0
- data/test/demo-test-profile/controls/flask.rb +84 -0
- data/test/demo-test-profile/inspec.lock +7 -0
- data/test/demo-test-profile/inspec.yml +11 -0
- data/test/etco-test-profile/README.md +3 -0
- data/test/etco-test-profile/controls/all-in-one.rb +182 -0
- data/test/etco-test-profile/inspec.lock +7 -0
- data/test/etco-test-profile/inspec.yml +11 -0
- data/test/exec_inspec.py +246 -0
- data/test/exec_mu_install.py +241 -0
- data/test/exec_retry.py +44 -0
- data/test/mu-master-test/README.md +3 -0
- data/test/mu-master-test/controls/all_in_one.rb +557 -0
- data/test/mu-master-test/inspec.lock +3 -0
- data/test/mu-master-test/inspec.yml +11 -0
- data/test/mu-tools-test/README.md +3 -0
- data/test/mu-tools-test/controls/base.rb +265 -0
- data/test/mu-tools-test/inspec.lock +3 -0
- data/test/mu-tools-test/inspec.yml +8 -0
- data/test/simple-server-php-test/README.md +3 -0
- data/test/simple-server-php-test/controls/apachephp.rb +25 -0
- data/test/simple-server-php-test/controls/example.rb +19 -0
- data/test/simple-server-php-test/inspec.lock +7 -0
- data/test/simple-server-php-test/inspec.yml +12 -0
- data/test/simple-server-rails-test/README.md +3 -0
- data/test/simple-server-rails-test/controls/rails.rb +188 -0
- data/test/simple-server-rails-test/inspec.lock +7 -0
- data/test/simple-server-rails-test/inspec.yml +11 -0
- data/test/simple-windows-test/README.md +3 -0
- data/test/simple-windows-test/controls/windows.rb +20 -0
- data/test/simple-windows-test/inspec.lock +7 -0
- data/test/simple-windows-test/inspec.yml +11 -0
- data/test/smoke_test.rb +75 -0
- data/test/wordpress-test/README.md +3 -0
- data/test/wordpress-test/controls/wordpress.rb +97 -0
- data/test/wordpress-test/inspec.lock +7 -0
- data/test/wordpress-test/inspec.yml +11 -0
- metadata +979 -0
|
@@ -0,0 +1,811 @@
|
|
|
1
|
+
# Copyright:: Copyright (c) 2017 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 'googleauth'
|
|
16
|
+
require "net/http"
|
|
17
|
+
require 'net/https'
|
|
18
|
+
require 'multi_json'
|
|
19
|
+
require 'stringio'
|
|
20
|
+
|
|
21
|
+
module MU
|
|
22
|
+
class Cloud
|
|
23
|
+
# Support for Google Cloud Platform as a provisioning layer.
|
|
24
|
+
class Google
|
|
25
|
+
@@authtoken = nil
|
|
26
|
+
@@default_project = nil
|
|
27
|
+
@@myRegion_var = nil
|
|
28
|
+
@@authorizers = {}
|
|
29
|
+
|
|
30
|
+
# Any cloud-specific instance methods we require our resource
|
|
31
|
+
# implementations to have, above and beyond the ones specified by
|
|
32
|
+
# {MU::Cloud}
|
|
33
|
+
# @return [Array<Symbol>]
|
|
34
|
+
def self.required_instance_methods
|
|
35
|
+
[]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# If we're running this cloud, return the $MU_CFG blob we'd use to
|
|
39
|
+
# describe this environment as our target one.
|
|
40
|
+
def self.hosted_config
|
|
41
|
+
return nil if !hosted?
|
|
42
|
+
getGoogleMetaData("instance/zone").match(/^projects\/[^\/]+\/zones\/([^\/]+)$/)
|
|
43
|
+
zone = Regexp.last_match[1]
|
|
44
|
+
{
|
|
45
|
+
"project" => MU::Cloud::Google.getGoogleMetaData("project/project-id"),
|
|
46
|
+
"region" => zone.sub(/-[a-z]$/, "")
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# A non-working example configuration
|
|
51
|
+
def self.config_example
|
|
52
|
+
sample = hosted_config
|
|
53
|
+
sample ||= {
|
|
54
|
+
"project" => "my-project",
|
|
55
|
+
"region" => "us-east4"
|
|
56
|
+
}
|
|
57
|
+
sample["credentials_file"] = "#{Etc.getpwuid(Process.uid).dir}/gcp_serviceacct.json"
|
|
58
|
+
sample["log_bucket_name"] = "my-mu-cloud-storage-bucket"
|
|
59
|
+
sample
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# If we've configured Google as a provider, or are simply hosted in GCP,
|
|
63
|
+
# decide what our default region is.
|
|
64
|
+
def self.myRegion
|
|
65
|
+
if $MU_CFG['google'] and $MU_CFG['google']['region']
|
|
66
|
+
@@myRegion_var = $MU_CFG['google']['region']
|
|
67
|
+
elsif MU::Cloud::Google.hosted?
|
|
68
|
+
zone = MU::Cloud::Google.getGoogleMetaData("instance/zone")
|
|
69
|
+
@@myRegion_var = zone.gsub(/^.*?\/|\-\d+$/, "")
|
|
70
|
+
end
|
|
71
|
+
@@myRegion_var
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Plant a Mu deploy secret into a storage bucket somewhere for so our kittens can consume it
|
|
75
|
+
# @param deploy_id [String]: The deploy for which we're writing the secret
|
|
76
|
+
# @param value [String]: The contents of the secret
|
|
77
|
+
def self.writeDeploySecret(deploy_id, value)
|
|
78
|
+
name = deploy_id+"-secret"
|
|
79
|
+
begin
|
|
80
|
+
MU.log "Writing #{name} to Cloud Storage bucket #{$MU_CFG['google']['log_bucket_name']}"
|
|
81
|
+
f = Tempfile.new(name) # XXX this is insecure and stupid
|
|
82
|
+
f.write value
|
|
83
|
+
f.close
|
|
84
|
+
objectobj = MU::Cloud::Google.storage(:Object).new(
|
|
85
|
+
bucket: $MU_CFG['google']['log_bucket_name'],
|
|
86
|
+
name: name
|
|
87
|
+
)
|
|
88
|
+
ebs_key = MU::Cloud::Google.storage.insert_object(
|
|
89
|
+
$MU_CFG['google']['log_bucket_name'],
|
|
90
|
+
objectobj,
|
|
91
|
+
upload_source: f.path
|
|
92
|
+
)
|
|
93
|
+
f.unlink
|
|
94
|
+
rescue ::Google::Apis::ClientError => e
|
|
95
|
+
# XXX comment for NCBI tests
|
|
96
|
+
# raise MU::MommaCat::DeployInitializeError, "Got #{e.inspect} trying to write #{name} to #{$MU_CFG['google']['log_bucket_name']}"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Remove the service account and various deploy secrets associated with a deployment. Intended for invocation from MU::Cleanup.
|
|
101
|
+
# @param deploy_id [String]: The deploy for which we're granting the secret
|
|
102
|
+
# @param noop [Boolean]: If true, will only print what would be done
|
|
103
|
+
def self.removeDeploySecretsAndRoles(deploy_id = MU.deploy_id, flags: {}, noop: false)
|
|
104
|
+
return if !$MU_CFG['google'] or !$MU_CFG['google']['project']
|
|
105
|
+
flags["project"] ||= MU::Cloud::Google.defaultProject
|
|
106
|
+
name = deploy_id+"-secret"
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Grant access to appropriate Cloud Storage objects in our log/secret bucket for a deploy member.
|
|
111
|
+
# @param acct [String]: The service account (by email addr) to which we'll grant access
|
|
112
|
+
# @param deploy_id [String]: The deploy for which we're granting the secret
|
|
113
|
+
# XXX add equivalent for AWS and call agnostically
|
|
114
|
+
def self.grantDeploySecretAccess(acct, deploy_id = MU.deploy_id)
|
|
115
|
+
name = deploy_id+"-secret"
|
|
116
|
+
begin
|
|
117
|
+
MU.log "Granting #{acct} access to list Cloud Storage bucket #{$MU_CFG['google']['log_bucket_name']}"
|
|
118
|
+
MU::Cloud::Google.storage.insert_bucket_access_control(
|
|
119
|
+
$MU_CFG['google']['log_bucket_name'],
|
|
120
|
+
MU::Cloud::Google.storage(:BucketAccessControl).new(
|
|
121
|
+
bucket: $MU_CFG['google']['log_bucket_name'],
|
|
122
|
+
role: "READER",
|
|
123
|
+
entity: "user-"+acct
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
aclobj = MU::Cloud::Google.storage(:ObjectAccessControl).new(
|
|
128
|
+
bucket: $MU_CFG['google']['log_bucket_name'],
|
|
129
|
+
role: "READER",
|
|
130
|
+
entity: "user-"+acct
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
[name, "log_vol_ebs_key"].each { |obj|
|
|
134
|
+
MU.log "Granting #{acct} access to #{obj} in Cloud Storage bucket #{$MU_CFG['google']['log_bucket_name']}"
|
|
135
|
+
MU::Cloud::Google.storage.insert_object_access_control(
|
|
136
|
+
$MU_CFG['google']['log_bucket_name'],
|
|
137
|
+
obj,
|
|
138
|
+
aclobj
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
rescue ::Google::Apis::ClientError => e
|
|
142
|
+
raise MuError, "Got #{e.inspect} trying to set ACLs for #{deploy_id} in #{$MU_CFG['google']['log_bucket_name']}"
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
@@is_in_gcp = nil
|
|
147
|
+
|
|
148
|
+
# Alias for #{MU::Cloud::Google.hosted?}
|
|
149
|
+
def self.hosted
|
|
150
|
+
MU::Cloud::Google.hosted?
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Determine whether we (the Mu master, presumably) are hosted in this
|
|
154
|
+
# cloud.
|
|
155
|
+
# @return [Boolean]
|
|
156
|
+
def self.hosted?
|
|
157
|
+
if !@@is_in_gcp.nil?
|
|
158
|
+
return @@is_in_gcp
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
if getGoogleMetaData("instance/name")
|
|
162
|
+
@@is_in_gcp = true
|
|
163
|
+
return true
|
|
164
|
+
end
|
|
165
|
+
@@is_in_gcp = false
|
|
166
|
+
false
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Fetch a Google instance metadata parameter (example: instance/id).
|
|
170
|
+
# @param param [String]: The parameter name to fetch
|
|
171
|
+
# @return [String, nil]
|
|
172
|
+
def self.getGoogleMetaData(param)
|
|
173
|
+
base_url = "http://metadata.google.internal/computeMetadata/v1"
|
|
174
|
+
begin
|
|
175
|
+
Timeout.timeout(2) do
|
|
176
|
+
response = open(
|
|
177
|
+
"#{base_url}/#{param}",
|
|
178
|
+
"Metadata-Flavor" => "Google"
|
|
179
|
+
).read
|
|
180
|
+
return response
|
|
181
|
+
end
|
|
182
|
+
rescue Net::HTTPServerException, OpenURI::HTTPError, Timeout::Error, SocketError, Errno::EHOSTUNREACH, Errno::ENETUNREACH => e
|
|
183
|
+
# This is fairly normal, just handle it gracefully
|
|
184
|
+
logger = MU::Logger.new
|
|
185
|
+
logger.log "Failed metadata request #{base_url}/#{param}: #{e.inspect}", MU::DEBUG
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
nil
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Create an SSL Certificate resource from some local x509 cert files.
|
|
192
|
+
# @param name [String]: A resource name for the certificate
|
|
193
|
+
# @param cert [String,OpenSSL::X509::Certificate]: An x509 certificate
|
|
194
|
+
# @param key [String,OpenSSL::PKey]: An x509 private key
|
|
195
|
+
# @return [Google::Apis::ComputeBeta::SslCertificate]
|
|
196
|
+
def self.createSSLCertificate(name, cert, key, flags = {})
|
|
197
|
+
flags["project"] ||= MU::Cloud::Google.defaultProject
|
|
198
|
+
flags["description"] ||= MU.deploy_id
|
|
199
|
+
certobj = ::Google::Apis::ComputeBeta::SslCertificate.new(
|
|
200
|
+
name: name,
|
|
201
|
+
certificate: cert.to_s,
|
|
202
|
+
private_key: key.to_s,
|
|
203
|
+
description: flags["description"]
|
|
204
|
+
)
|
|
205
|
+
MU::Cloud::Google.compute.insert_ssl_certificate(flags["project"], certobj)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
@@svc_account_name = nil
|
|
209
|
+
# Fetch the name of the service account we were using last time we loaded
|
|
210
|
+
# GCP credentials.
|
|
211
|
+
# @return [String]
|
|
212
|
+
def self.svc_account_name
|
|
213
|
+
@@svc_account_name
|
|
214
|
+
end
|
|
215
|
+
# Pull our global Google Cloud Platform credentials out of their secure
|
|
216
|
+
# vault, feed them to the googleauth gem, and stash the results on hand
|
|
217
|
+
# for consumption by the various GCP APIs.
|
|
218
|
+
# @param scopes [Array<String>]: One or more scopes for which to authorizer the caller. Will vary depending on the API you're calling.
|
|
219
|
+
def self.loadCredentials(scopes = nil)
|
|
220
|
+
return @@authorizers[scopes.to_s] if @@authorizers[scopes.to_s]
|
|
221
|
+
|
|
222
|
+
if $MU_CFG.has_key?("google")
|
|
223
|
+
data = nil
|
|
224
|
+
|
|
225
|
+
def self.get_machine_credentials(scopes)
|
|
226
|
+
@@svc_account_name = MU::Cloud::Google.getGoogleMetaData("instance/service-accounts/default/email")
|
|
227
|
+
MU.log "We are hosted in GCP, so I will attempt to use the service account #{@@svc_account_name} to make API requests.", MU::DEBUG
|
|
228
|
+
|
|
229
|
+
@@authorizers[scopes.to_s] = ::Google::Auth.get_application_default(scopes)
|
|
230
|
+
@@authorizers[scopes.to_s].fetch_access_token!
|
|
231
|
+
@@default_project ||= MU::Cloud::Google.getGoogleMetaData("project/project-id")
|
|
232
|
+
@@authorizers[scopes.to_s]
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
if $MU_CFG["google"]["credentials_file"]
|
|
236
|
+
begin
|
|
237
|
+
data = JSON.parse(File.read($MU_CFG["google"]["credentials_file"]))
|
|
238
|
+
@@default_project ||= data["project_id"]
|
|
239
|
+
creds = {
|
|
240
|
+
:json_key_io => StringIO.new(MultiJson.dump(data)),
|
|
241
|
+
:scope => scopes
|
|
242
|
+
}
|
|
243
|
+
@@svc_account_name = data["client_email"]
|
|
244
|
+
@@authorizers[scopes.to_s] = ::Google::Auth::ServiceAccountCredentials.make_creds(creds)
|
|
245
|
+
return @@authorizers[scopes.to_s]
|
|
246
|
+
rescue JSON::ParserError, Errno::ENOENT, Errno::EACCES => e
|
|
247
|
+
if !MU::Cloud::Google.hosted?
|
|
248
|
+
raise MuError, "Google Cloud credentials file #{$MU_CFG["google"]["credentials_file"]} is missing or invalid (#{e.message})"
|
|
249
|
+
end
|
|
250
|
+
MU.log "Google Cloud credentials file #{$MU_CFG["google"]["credentials_file"]} is missing or invalid", MU::WARN, details: e.message
|
|
251
|
+
return get_machine_credentials(scopes)
|
|
252
|
+
end
|
|
253
|
+
elsif $MU_CFG["google"]["credentials"]
|
|
254
|
+
begin
|
|
255
|
+
vault, item = $MU_CFG["google"]["credentials"].split(/:/)
|
|
256
|
+
data = MU::Groomer::Chef.getSecret(vault: vault, item: item).to_h
|
|
257
|
+
rescue MU::Groomer::Chef::MuNoSuchSecret
|
|
258
|
+
if !MU::Cloud::Google.hosted?
|
|
259
|
+
raise MuError, "Google Cloud credentials not found in Vault #{vault}:#{item}"
|
|
260
|
+
end
|
|
261
|
+
MU.log "Google Cloud credentials not found in Vault #{vault}:#{item}", MU::WARN
|
|
262
|
+
return get_machine_credentials(scopes)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
@@default_project ||= data["project_id"]
|
|
266
|
+
creds = {
|
|
267
|
+
:json_key_io => StringIO.new(MultiJson.dump(data)),
|
|
268
|
+
:scope => scopes
|
|
269
|
+
}
|
|
270
|
+
@@svc_account_name = data["client_email"]
|
|
271
|
+
@@authorizers[scopes.to_s] = ::Google::Auth::ServiceAccountCredentials.make_creds(creds)
|
|
272
|
+
return @@authorizers[scopes.to_s]
|
|
273
|
+
elsif MU::Cloud::Google.hosted?
|
|
274
|
+
return get_machine_credentials(scopes)
|
|
275
|
+
else
|
|
276
|
+
raise MuError, "Google Cloud credentials not configured"
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
end
|
|
280
|
+
nil
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# Fetch a URL
|
|
284
|
+
def self.get(url)
|
|
285
|
+
uri = URI url
|
|
286
|
+
resp = nil
|
|
287
|
+
|
|
288
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
|
289
|
+
resp = http.get(uri)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
unless resp.code == "200"
|
|
293
|
+
puts resp.code, resp.body
|
|
294
|
+
exit
|
|
295
|
+
end
|
|
296
|
+
resp.body
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# If this Mu master resides in the Google Cloud Platform, return the
|
|
300
|
+
# project id in which we reside. Nil if we're not in GCP.
|
|
301
|
+
def self.myProject
|
|
302
|
+
if MU::Cloud::Google.hosted?
|
|
303
|
+
return MU::Cloud::Google.getGoogleMetaData("project/project-id")
|
|
304
|
+
end
|
|
305
|
+
nil
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# If this Mu master resides in the Google Cloud Platform, return the
|
|
309
|
+
# default service account associated with its metadata.
|
|
310
|
+
def self.myServiceAccount
|
|
311
|
+
if MU::Cloud::Google.hosted?
|
|
312
|
+
MU::Cloud::Google.getGoogleMetaData("instance/service-accounts/default/email")
|
|
313
|
+
else
|
|
314
|
+
nil
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Our credentials map to a project, an organizational structure in Google
|
|
319
|
+
# Cloud. This fetches the identifier of the project associated with our
|
|
320
|
+
# default credentials.
|
|
321
|
+
def self.defaultProject
|
|
322
|
+
return myProject if !$MU_CFG['google'] or !$MU_CFG['google']['project']
|
|
323
|
+
loadCredentials if !@@default_project
|
|
324
|
+
@@default_project
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# List all Google Cloud Platform projects available to our credentials
|
|
328
|
+
def self.listProjects
|
|
329
|
+
return [] if !$MU_CFG['google'] or !$MU_CFG['google']['project']
|
|
330
|
+
result = MU::Cloud::Google.resource_manager.list_projects
|
|
331
|
+
result.projects.reject! { |p| p.lifecycle_state == "DELETE_REQUESTED" }
|
|
332
|
+
result.projects.map { |p| p.project_id }
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
@@regions = {}
|
|
336
|
+
# List all known Google Cloud Platform regions
|
|
337
|
+
# @param us_only [Boolean]: Restrict results to United States only
|
|
338
|
+
def self.listRegions(us_only = false)
|
|
339
|
+
if !MU::Cloud::Google.defaultProject
|
|
340
|
+
return []
|
|
341
|
+
end
|
|
342
|
+
if @@regions.size == 0
|
|
343
|
+
begin
|
|
344
|
+
result = MU::Cloud::Google.compute.list_regions(MU::Cloud::Google.defaultProject)
|
|
345
|
+
rescue ::Google::Apis::ClientError => e
|
|
346
|
+
if e.message.match(/forbidden/)
|
|
347
|
+
raise MuError, "Insufficient permissions to list Google Cloud region. The service account #{myServiceAccount} should probably have the project owner role."
|
|
348
|
+
end
|
|
349
|
+
raise e
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
regions = []
|
|
353
|
+
result.items.each { |region|
|
|
354
|
+
@@regions[region.name] = []
|
|
355
|
+
region.zones.each { |az|
|
|
356
|
+
@@regions[region.name] << az.sub(/^.*?\/([^\/]+)$/, '\1')
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
end
|
|
360
|
+
if us_only
|
|
361
|
+
@@regions.keys.delete_if { |r| !r.match(/^us/) }
|
|
362
|
+
else
|
|
363
|
+
@@regions.keys
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
@@instance_types = nil
|
|
369
|
+
# Query the GCP API for the list of valid EC2 instance types and some of
|
|
370
|
+
# their attributes. We can use this in config validation and to help
|
|
371
|
+
# "translate" machine types across cloud providers.
|
|
372
|
+
# @param region [String]: Supported machine types can vary from region to region, so we look for the set we're interested in specifically
|
|
373
|
+
# @return [Hash]
|
|
374
|
+
def self.listInstanceTypes(region = myRegion)
|
|
375
|
+
return @@instance_types if @@instance_types and @@instance_types[region]
|
|
376
|
+
if !MU::Cloud::Google.defaultProject
|
|
377
|
+
return {}
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
@@instance_types ||= {}
|
|
381
|
+
@@instance_types[region] ||= {}
|
|
382
|
+
result = MU::Cloud::Google.compute.list_machine_types(MU::Cloud::Google.defaultProject, listAZs(region).first)
|
|
383
|
+
result.items.each { |type|
|
|
384
|
+
@@instance_types[region][type.name] ||= {}
|
|
385
|
+
@@instance_types[region][type.name]["memory"] = sprintf("%.1f", type.memory_mb/1024.0).to_f
|
|
386
|
+
@@instance_types[region][type.name]["vcpu"] = type.guest_cpus.to_f
|
|
387
|
+
if type.is_shared_cpu
|
|
388
|
+
@@instance_types[region][type.name]["ecu"] = "Variable"
|
|
389
|
+
else
|
|
390
|
+
@@instance_types[region][type.name]["ecu"] = type.guest_cpus
|
|
391
|
+
end
|
|
392
|
+
}
|
|
393
|
+
@@instance_types
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# Google has fairly strict naming conventions (all lowercase, no
|
|
397
|
+
# underscores, etc). Provide a wrapper to our standard names to handle it.
|
|
398
|
+
def self.nameStr(name)
|
|
399
|
+
name.downcase.gsub(/[^a-z0-9\-]/, "-")
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# List the Availability Zones associated with a given Google Cloud
|
|
403
|
+
# region. If no region is given, search the one in which this MU master
|
|
404
|
+
# server resides (if it resides in this cloud provider's ecosystem).
|
|
405
|
+
# @param region [String]: The region to search.
|
|
406
|
+
# @return [Array<String>]: The Availability Zones in this region.
|
|
407
|
+
def self.listAZs(region = MU.curRegion)
|
|
408
|
+
MU::Cloud::Google.listRegions if !@@regions.has_key?(region)
|
|
409
|
+
raise MuError, "No such Google Cloud region '#{region}'" if !@@regions.has_key?(region)
|
|
410
|
+
@@regions[region]
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
# Google's Compute Service API
|
|
414
|
+
# @param subclass [<Google::Apis::ComputeBeta>]: If specified, will return the class ::Google::Apis::ComputeBeta::subclass instead of an API client instance
|
|
415
|
+
def self.compute(subclass = nil)
|
|
416
|
+
require 'google/apis/compute_beta'
|
|
417
|
+
|
|
418
|
+
if subclass.nil?
|
|
419
|
+
@@compute_api ||= MU::Cloud::Google::Endpoint.new(api: "ComputeBeta::ComputeService", scopes: ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/compute.readonly'])
|
|
420
|
+
return @@compute_api
|
|
421
|
+
elsif subclass.is_a?(Symbol)
|
|
422
|
+
return Object.const_get("::Google").const_get("Apis").const_get("ComputeBeta").const_get(subclass)
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
# Google's Storage Service API
|
|
427
|
+
# @param subclass [<Google::Apis::StorageV1>]: If specified, will return the class ::Google::Apis::StorageV1::subclass instead of an API client instance
|
|
428
|
+
def self.storage(subclass = nil)
|
|
429
|
+
require 'google/apis/storage_v1'
|
|
430
|
+
|
|
431
|
+
if subclass.nil?
|
|
432
|
+
@@storage_api ||= MU::Cloud::Google::Endpoint.new(api: "StorageV1::StorageService", scopes: ['https://www.googleapis.com/auth/cloud-platform'])
|
|
433
|
+
return @@storage_api
|
|
434
|
+
elsif subclass.is_a?(Symbol)
|
|
435
|
+
return Object.const_get("::Google").const_get("Apis").const_get("StorageV1").const_get(subclass)
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
# Google's IAM Service API
|
|
440
|
+
# @param subclass [<Google::Apis::IamV1>]: If specified, will return the class ::Google::Apis::IamV1::subclass instead of an API client instance
|
|
441
|
+
def self.iam(subclass = nil)
|
|
442
|
+
require 'google/apis/iam_v1'
|
|
443
|
+
|
|
444
|
+
if subclass.nil?
|
|
445
|
+
@@iam_api ||= MU::Cloud::Google::Endpoint.new(api: "IamV1::IamService", scopes: ['https://www.googleapis.com/auth/cloud-platform'])
|
|
446
|
+
return @@iam_api
|
|
447
|
+
elsif subclass.is_a?(Symbol)
|
|
448
|
+
return Object.const_get("::Google").const_get("Apis").const_get("IamV1").const_get(subclass)
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
# GCP's AdminDirectory Service API
|
|
453
|
+
# @param subclass [<Google::Apis::AdminDirectoryV1>]: If specified, will return the class ::Google::Apis::AdminDirectoryV1::subclass instead of an API client instance
|
|
454
|
+
def self.admin_directory(subclass = nil)
|
|
455
|
+
require 'google/apis/admin_directory_v1'
|
|
456
|
+
|
|
457
|
+
if subclass.nil?
|
|
458
|
+
begin
|
|
459
|
+
@@admin_directory_api ||= MU::Cloud::Google::Endpoint.new(api: "AdminDirectoryV1::DirectoryService", scopes: ['https://www.googleapis.com/auth/admin.directory.group.member.readonly', 'https://www.googleapis.com/auth/admin.directory.group.readonly'], masquerade: $MU_CFG['google']['masquerade_as'])
|
|
460
|
+
rescue Signet::AuthorizationError => e
|
|
461
|
+
MU.log "Cannot masquerade as #{$MU_CFG['google']['masquerade_as']}", MU::ERROR, details: "You can only use masquerade_as with GSuite. For more information on delegating GSuite authority to a service account, see:\nhttps://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority"
|
|
462
|
+
raise e
|
|
463
|
+
end
|
|
464
|
+
return @@admin_directory_api
|
|
465
|
+
elsif subclass.is_a?(Symbol)
|
|
466
|
+
return Object.const_get("::Google").const_get("Apis").const_get("AdminDirectoryV1").const_get(subclass)
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
# Google's Cloud Resource Manager API
|
|
471
|
+
# @param subclass [<Google::Apis::CloudresourcemanagerV1>]: If specified, will return the class ::Google::Apis::CloudresourcemanagerV1::subclass instead of an API client instance
|
|
472
|
+
def self.resource_manager(subclass = nil)
|
|
473
|
+
require 'google/apis/cloudresourcemanager_v1'
|
|
474
|
+
|
|
475
|
+
if subclass.nil?
|
|
476
|
+
@@resource_api ||= MU::Cloud::Google::Endpoint.new(api: "CloudresourcemanagerV1::CloudResourceManagerService", scopes: ['https://www.googleapis.com/auth/cloud-platform'])
|
|
477
|
+
return @@resource_api
|
|
478
|
+
elsif subclass.is_a?(Symbol)
|
|
479
|
+
return Object.const_get("::Google").const_get("Apis").const_get("CloudresourcemanagerV1").const_get(subclass)
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
# Google's Container API
|
|
484
|
+
# @param subclass [<Google::Apis::ContainerV1>]: If specified, will return the class ::Google::Apis::ContainerV1::subclass instead of an API client instance
|
|
485
|
+
def self.container(subclass = nil)
|
|
486
|
+
require 'google/apis/container_v1'
|
|
487
|
+
|
|
488
|
+
if subclass.nil?
|
|
489
|
+
@@container_api ||= MU::Cloud::Google::Endpoint.new(api: "ContainerV1::ContainerService", scopes: ['https://www.googleapis.com/auth/cloud-platform'])
|
|
490
|
+
return @@container_api
|
|
491
|
+
elsif subclass.is_a?(Symbol)
|
|
492
|
+
return Object.const_get("::Google").const_get("Apis").const_get("ContainerV1").const_get(subclass)
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
# Google's Service Manager API (the one you use to enable pre-project APIs)
|
|
497
|
+
# @param subclass [<Google::Apis::ServicemanagementV1>]: If specified, will return the class ::Google::Apis::ServicemanagementV1::subclass instead of an API client instance
|
|
498
|
+
def self.service_manager(subclass = nil)
|
|
499
|
+
require 'google/apis/servicemanagement_v1'
|
|
500
|
+
|
|
501
|
+
if subclass.nil?
|
|
502
|
+
@@service_api ||= MU::Cloud::Google::Endpoint.new(api: "ServicemanagementV1::ServiceManagementService", scopes: ['https://www.googleapis.com/auth/cloud-platform'])
|
|
503
|
+
return @@service_api
|
|
504
|
+
elsif subclass.is_a?(Symbol)
|
|
505
|
+
return Object.const_get("::Google").const_get("Apis").const_get("ServicemanagementV1").const_get(subclass)
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
# Google's SQL Service API
|
|
510
|
+
# @param subclass [<Google::Apis::SqladminV1beta4>]: If specified, will return the class ::Google::Apis::SqladminV1beta4::subclass instead of an API client instance
|
|
511
|
+
def self.sql(subclass = nil)
|
|
512
|
+
require 'google/apis/sqladmin_v1beta4'
|
|
513
|
+
|
|
514
|
+
if subclass.nil?
|
|
515
|
+
@@sql_api ||= MU::Cloud::Google::Endpoint.new(api: "SqladminV1beta4::SQLAdminService", scopes: ['https://www.googleapis.com/auth/cloud-platform'])
|
|
516
|
+
return @@sql_api
|
|
517
|
+
elsif subclass.is_a?(Symbol)
|
|
518
|
+
return Object.const_get("::Google").const_get("Apis").const_get("SqladminV1beta4").const_get(subclass)
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
# Google's StackDriver Logging Service API
|
|
523
|
+
# @param subclass [<Google::Apis::LoggingV2>]: If specified, will return the class ::Google::Apis::LoggingV2::subclass instead of an API client instance
|
|
524
|
+
def self.logging(subclass = nil)
|
|
525
|
+
require 'google/apis/logging_v2'
|
|
526
|
+
|
|
527
|
+
if subclass.nil?
|
|
528
|
+
@@logging_api ||= MU::Cloud::Google::Endpoint.new(api: "LoggingV2::LoggingService", scopes: ['https://www.googleapis.com/auth/cloud-platform'])
|
|
529
|
+
return @@logging_api
|
|
530
|
+
elsif subclass.is_a?(Symbol)
|
|
531
|
+
return Object.const_get("::Google").const_get("Apis").const_get("LoggingV2").const_get(subclass)
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
private
|
|
537
|
+
|
|
538
|
+
# Wrapper class for Google APIs, so that we can catch some common
|
|
539
|
+
# transient endpoint errors without having to spray rescues all over the
|
|
540
|
+
# codebase.
|
|
541
|
+
class Endpoint
|
|
542
|
+
@api = nil
|
|
543
|
+
|
|
544
|
+
# Create a Google Cloud Platform API client
|
|
545
|
+
# @param api [String]: Which API are we wrapping?
|
|
546
|
+
# @param scopes [Array<String>]: Google auth scopes applicable to this API
|
|
547
|
+
def initialize(api: "ComputeBeta::ComputeService", scopes: ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/compute.readonly'], masquerade: nil)
|
|
548
|
+
@api = Object.const_get("Google::Apis::#{api}").new
|
|
549
|
+
@api.authorization = MU::Cloud::Google.loadCredentials(scopes)
|
|
550
|
+
if masquerade
|
|
551
|
+
@api.authorization.sub = masquerade
|
|
552
|
+
@api.authorization.fetch_access_token!
|
|
553
|
+
end
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# Generic wrapper for deleting Compute resources
|
|
557
|
+
# @param type [String]: The type of resource, typically the string you'll find in all of the API calls referring to it
|
|
558
|
+
# @param project [String]: The project in which we should look for the resources
|
|
559
|
+
# @param region [String]: The region in which to loop for the resources
|
|
560
|
+
# @param noop [Boolean]: If true, will only log messages about resources to be deleted, without actually deleting them
|
|
561
|
+
# @param filter [String]: The Compute API filter string to use to isolate appropriate resources
|
|
562
|
+
def delete(type, project, region = nil, noop = false, filter = "description eq #{MU.deploy_id}")
|
|
563
|
+
list_sym = "list_#{type.sub(/y$/, "ie")}s".to_sym
|
|
564
|
+
resp = nil
|
|
565
|
+
begin
|
|
566
|
+
if region
|
|
567
|
+
resp = MU::Cloud::Google.compute.send(list_sym, project, region, filter: filter)
|
|
568
|
+
else
|
|
569
|
+
resp = MU::Cloud::Google.compute.send(list_sym, project, filter: filter)
|
|
570
|
+
end
|
|
571
|
+
rescue ::Google::Apis::ClientError => e
|
|
572
|
+
return if e.message.match(/^notFound: /)
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
if !resp.nil? and !resp.items.nil?
|
|
576
|
+
threads = []
|
|
577
|
+
parent_thread_id = Thread.current.object_id
|
|
578
|
+
resp.items.each { |obj|
|
|
579
|
+
threads << Thread.new {
|
|
580
|
+
MU.dupGlobals(parent_thread_id)
|
|
581
|
+
MU.log "Removing #{type.gsub(/_/, " ")} #{obj.name}"
|
|
582
|
+
delete_sym = "delete_#{type}".to_sym
|
|
583
|
+
if !noop
|
|
584
|
+
retries = 0
|
|
585
|
+
failed = false
|
|
586
|
+
begin
|
|
587
|
+
resp = nil
|
|
588
|
+
failed = false
|
|
589
|
+
if region
|
|
590
|
+
resp = MU::Cloud::Google.compute.send(delete_sym, project, region, obj.name)
|
|
591
|
+
else
|
|
592
|
+
resp = MU::Cloud::Google.compute.send(delete_sym, project, obj.name)
|
|
593
|
+
end
|
|
594
|
+
if resp.error and resp.error.errors and resp.error.errors.size > 0
|
|
595
|
+
failed = true
|
|
596
|
+
retries += 1
|
|
597
|
+
if resp.error.errors.first.code == "RESOURCE_IN_USE_BY_ANOTHER_RESOURCE" and retries < 3
|
|
598
|
+
sleep 10
|
|
599
|
+
else
|
|
600
|
+
MU.log "Error deleting #{type.gsub(/_/, " ")} #{obj.name}", MU::ERR, details: resp.error.errors
|
|
601
|
+
raise MuError, "Failed to delete #{type.gsub(/_/, " ")} #{obj.name}"
|
|
602
|
+
end
|
|
603
|
+
else
|
|
604
|
+
# TODO validate that the resource actually went away, because it seems not to do so very reliably
|
|
605
|
+
end
|
|
606
|
+
failed = false
|
|
607
|
+
rescue ::Google::Apis::ClientError => e
|
|
608
|
+
raise e if !e.message.match(/^notFound: /)
|
|
609
|
+
end while failed and retries < 3
|
|
610
|
+
end
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
threads.each do |t|
|
|
614
|
+
t.join
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
end
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
@instance_cache = {}
|
|
621
|
+
# Catch-all for AWS client methods. Essentially a pass-through with some
|
|
622
|
+
# rescues for known silly endpoint behavior.
|
|
623
|
+
def method_missing(method_sym, *arguments)
|
|
624
|
+
retries = 0
|
|
625
|
+
actual_resource = nil
|
|
626
|
+
begin
|
|
627
|
+
MU.log "Calling #{method_sym}", MU::DEBUG, details: arguments
|
|
628
|
+
retval = nil
|
|
629
|
+
retries = 0
|
|
630
|
+
begin
|
|
631
|
+
if !arguments.nil? and arguments.size == 1
|
|
632
|
+
retval = @api.method(method_sym).call(arguments[0])
|
|
633
|
+
elsif !arguments.nil? and arguments.size > 0
|
|
634
|
+
retval = @api.method(method_sym).call(*arguments)
|
|
635
|
+
else
|
|
636
|
+
retval = @api.method(method_sym).call
|
|
637
|
+
end
|
|
638
|
+
rescue ::Google::Apis::AuthorizationError => e
|
|
639
|
+
if arguments.size > 0
|
|
640
|
+
raise MU::MuError, "Service account #{MU::Cloud::Google.svc_account_name} has insufficient privileges to call #{method_sym} in project #{arguments.first}"
|
|
641
|
+
else
|
|
642
|
+
raise MU::MuError, "Service account #{MU::Cloud::Google.svc_account_name} has insufficient privileges to call #{method_sym}"
|
|
643
|
+
end
|
|
644
|
+
rescue ::Google::Apis::ClientError => e
|
|
645
|
+
if e.message.match(/^invalidParameter:/)
|
|
646
|
+
MU.log "#{method_sym.to_s}: "+e.message, MU::ERR, details: arguments
|
|
647
|
+
end
|
|
648
|
+
if retries <= 1 and e.message.match(/^accessNotConfigured/)
|
|
649
|
+
enable_obj = nil
|
|
650
|
+
project = arguments.size > 0 ? arguments.first.to_s : MU::Cloud::Google.defaultProject
|
|
651
|
+
enable_obj = MU::Cloud::Google.service_manager(:EnableServiceRequest).new(
|
|
652
|
+
consumer_id: "project:"+project
|
|
653
|
+
)
|
|
654
|
+
# XXX dumbass way to get this string
|
|
655
|
+
e.message.match(/Enable it by visiting https:\/\/console\.developers\.google\.com\/apis\/api\/(.+?)\//)
|
|
656
|
+
svc_name = Regexp.last_match[1]
|
|
657
|
+
save_verbosity = MU.verbosity
|
|
658
|
+
if svc_name != "servicemanagement.googleapis.com"
|
|
659
|
+
MU.setLogging(MU::Logger::NORMAL)
|
|
660
|
+
MU.log "Attempting to enable #{svc_name} in project #{project}, then waiting for 30s", MU::WARN
|
|
661
|
+
MU.setLogging(save_verbosity)
|
|
662
|
+
MU::Cloud::Google.service_manager.enable_service(svc_name, enable_obj)
|
|
663
|
+
sleep 30
|
|
664
|
+
retries += 1
|
|
665
|
+
retry
|
|
666
|
+
else
|
|
667
|
+
MU.setLogging(MU::Logger::NORMAL)
|
|
668
|
+
MU.log "Google Cloud's Service Management API must be enabled manually by visiting #{e.message.gsub(/.*?(https?:\/\/[^\s]+)(?:$|\s).*/, '\1')}", MU::ERR
|
|
669
|
+
MU.setLogging(save_verbosity)
|
|
670
|
+
raise MU::MuError, "Service Management API not yet enabled for this account/project"
|
|
671
|
+
end
|
|
672
|
+
elsif retries <= 10 and
|
|
673
|
+
e.message.match(/^resourceNotReady:/) or
|
|
674
|
+
(e.message.match(/^resourceInUseByAnotherResource:/) and method_sym.to_s.match(/^delete_/))
|
|
675
|
+
if retries > 0 and retries % 3 == 0
|
|
676
|
+
MU.log "Will retry #{method_sym} after #{e.message} (retry #{retries})", MU::NOTICE, details: arguments
|
|
677
|
+
else
|
|
678
|
+
MU.log "Will retry #{method_sym} after #{e.message} (retry #{retries})", MU::DEBUG, details: arguments
|
|
679
|
+
end
|
|
680
|
+
retries = retries + 1
|
|
681
|
+
sleep retries*10
|
|
682
|
+
retry
|
|
683
|
+
else
|
|
684
|
+
raise e
|
|
685
|
+
end
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
if retval.class == ::Google::Apis::ComputeBeta::Operation
|
|
689
|
+
retries = 0
|
|
690
|
+
orig_target = retval.name
|
|
691
|
+
begin
|
|
692
|
+
if retries > 0 and retries % 3 == 0
|
|
693
|
+
MU.log "Waiting for #{method_sym} to be done (retry #{retries})", MU::NOTICE
|
|
694
|
+
else
|
|
695
|
+
MU.log "Waiting for #{method_sym} to be done (retry #{retries})", MU::DEBUG, details: retval
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
if retval.status != "DONE"
|
|
699
|
+
sleep 7
|
|
700
|
+
begin
|
|
701
|
+
resp = MU::Cloud::Google.compute.get_global_operation(
|
|
702
|
+
arguments.first, # there's always a project id
|
|
703
|
+
retval.name
|
|
704
|
+
)
|
|
705
|
+
retval = resp
|
|
706
|
+
rescue ::Google::Apis::ClientError => e
|
|
707
|
+
# this is ok; just means the operation is done and went away
|
|
708
|
+
if e.message.match(/^notFound:/)
|
|
709
|
+
break
|
|
710
|
+
else
|
|
711
|
+
raise e
|
|
712
|
+
end
|
|
713
|
+
end
|
|
714
|
+
retries = retries + 1
|
|
715
|
+
end
|
|
716
|
+
end while retval.status != "DONE"
|
|
717
|
+
|
|
718
|
+
# Most insert methods have a predictable get_* counterpart. Let's
|
|
719
|
+
# take advantage.
|
|
720
|
+
# XXX might want to do something similar for delete ops? just the
|
|
721
|
+
# but where we wait for the operation to definitely be done
|
|
722
|
+
had_been_found = false
|
|
723
|
+
if method_sym.to_s.match(/^(insert|create)_/) and retval.target_link
|
|
724
|
+
# service["#MU_CLOUDCLASS"].instance_methods(false).include?(:groom)
|
|
725
|
+
get_method = method_sym.to_s.gsub(/^(insert|create_disk|create)_/, "get_").to_sym
|
|
726
|
+
cloud_id = retval.target_link.sub(/^.*?\/([^\/]+)$/, '\1')
|
|
727
|
+
faked_args = arguments.dup
|
|
728
|
+
faked_args.pop
|
|
729
|
+
if get_method == :get_snapshot
|
|
730
|
+
faked_args.pop
|
|
731
|
+
faked_args.pop
|
|
732
|
+
end
|
|
733
|
+
faked_args.push(cloud_id)
|
|
734
|
+
actual_resource = @api.method(get_method).call(*faked_args)
|
|
735
|
+
#if method_sym == :insert_instance
|
|
736
|
+
#MU.log "actual_resource", MU::WARN, details: actual_resource
|
|
737
|
+
#end
|
|
738
|
+
had_been_found = true
|
|
739
|
+
if actual_resource.respond_to?(:status) and
|
|
740
|
+
["PROVISIONING", "STAGING", "PENDING", "CREATING", "RESTORING"].include?(actual_resource.status)
|
|
741
|
+
retries = 0
|
|
742
|
+
begin
|
|
743
|
+
if retries > 0 and retries % 3 == 0
|
|
744
|
+
MU.log "Waiting for #{cloud_id} to get past #{actual_resource.status} (retry #{retries})", MU::NOTICE
|
|
745
|
+
else
|
|
746
|
+
MU.log "Waiting for #{cloud_id} to get past #{actual_resource.status} (retry #{retries})", MU::DEBUG, details: actual_resource
|
|
747
|
+
end
|
|
748
|
+
sleep 10
|
|
749
|
+
actual_resource = @api.method(get_method).call(*faked_args)
|
|
750
|
+
retries = retries + 1
|
|
751
|
+
end while ["PROVISIONING", "STAGING", "PENDING", "CREATING", "RESTORING"].include?(actual_resource.status)
|
|
752
|
+
end
|
|
753
|
+
return actual_resource
|
|
754
|
+
end
|
|
755
|
+
end
|
|
756
|
+
return retval
|
|
757
|
+
rescue ::Google::Apis::ServerError, ::Google::Apis::ClientError => e
|
|
758
|
+
if e.class.name == "Google::Apis::ClientError" and
|
|
759
|
+
(!method_sym.to_s.match(/^insert_/) or !e.message.match(/^notFound: /) or
|
|
760
|
+
(e.message.match(/^notFound: /) and method_sym.to_s.match(/^insert_/))
|
|
761
|
+
)
|
|
762
|
+
if e.message.match(/^notFound: /) and method_sym.to_s.match(/^insert_/)
|
|
763
|
+
logreq = MU::Cloud::Google.logging(:ListLogEntriesRequest).new(
|
|
764
|
+
resource_names: ["projects/"+arguments.first],
|
|
765
|
+
filter: %Q{labels."compute.googleapis.com/resource_id"="#{retval.target_id}" OR labels."ssl_certificate_id"="#{retval.target_id}"} # XXX I guess we need to cover all of the possible keys, ugh
|
|
766
|
+
)
|
|
767
|
+
logs = MU::Cloud::Google.logging.list_entry_log_entries(logreq)
|
|
768
|
+
details = nil
|
|
769
|
+
if logs.entries
|
|
770
|
+
details = logs.entries.map { |e| e.json_payload }
|
|
771
|
+
details.reject! { |e| e["error"].nil? or e["error"].size == 0 }
|
|
772
|
+
end
|
|
773
|
+
|
|
774
|
+
raise MuError, "#{method_sym.to_s} of #{retval.target_id} appeared to succeed, but then the resource disappeared! #{details.to_s}"
|
|
775
|
+
end
|
|
776
|
+
raise e
|
|
777
|
+
end
|
|
778
|
+
retries = retries + 1
|
|
779
|
+
debuglevel = MU::DEBUG
|
|
780
|
+
interval = 5 + Random.rand(4) - 2
|
|
781
|
+
if retries < 10 and retries > 2
|
|
782
|
+
debuglevel = MU::NOTICE
|
|
783
|
+
interval = 20 + Random.rand(10) - 3
|
|
784
|
+
# elsif retries >= 10 and retries <= 100
|
|
785
|
+
elsif retries >= 10
|
|
786
|
+
debuglevel = MU::WARN
|
|
787
|
+
interval = 40 + Random.rand(15) - 5
|
|
788
|
+
# elsif retries > 100
|
|
789
|
+
# raise MuError, "Exhausted retries after #{retries} attempts while calling EC2's #{method_sym} in #{@region}. Args were: #{arguments}"
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
MU.log "Got #{e.inspect} calling Google's #{method_sym}, waiting #{interval.to_s}s and retrying. Called from: #{caller[1]}", debuglevel, details: arguments
|
|
793
|
+
sleep interval
|
|
794
|
+
MU.log method_sym.to_s.bold+" "+e.inspect, MU::WARN, details: arguments
|
|
795
|
+
retry
|
|
796
|
+
end
|
|
797
|
+
end
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
@@compute_api = nil
|
|
801
|
+
@@container_api = nil
|
|
802
|
+
@@storage_api = nil
|
|
803
|
+
@@sql_api = nil
|
|
804
|
+
@@iam_api = nil
|
|
805
|
+
@@logging_api = nil
|
|
806
|
+
@@resource_api = nil
|
|
807
|
+
@@service_api = nil
|
|
808
|
+
@@admin_directory_api = nil
|
|
809
|
+
end
|
|
810
|
+
end
|
|
811
|
+
end
|