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