cloud-mu 3.5.0 → 3.6.3
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 +4 -4
- data/Berksfile +5 -2
- data/Berksfile.lock +135 -0
- data/ansible/roles/mu-base/README.md +33 -0
- data/ansible/roles/mu-base/defaults/main.yml +2 -0
- data/ansible/roles/mu-base/files/check_apm.cfg +1 -0
- data/ansible/roles/mu-base/files/check_apm.sh +18 -0
- data/ansible/roles/mu-base/files/check_disk.cfg +1 -0
- data/ansible/roles/mu-base/files/check_elastic_shards.cfg +1 -0
- data/ansible/roles/mu-base/files/check_elastic_shards.sh +12 -0
- data/ansible/roles/mu-base/files/check_logstash.cfg +1 -0
- data/ansible/roles/mu-base/files/check_logstash.sh +14 -0
- data/ansible/roles/mu-base/files/check_mem.cfg +1 -0
- data/ansible/roles/mu-base/files/check_updates.cfg +1 -0
- data/ansible/roles/mu-base/files/logrotate.conf +35 -0
- data/ansible/roles/mu-base/files/nrpe-apm-sudo +1 -0
- data/ansible/roles/mu-base/files/nrpe-elasticshards-sudo +2 -0
- data/ansible/roles/mu-base/handlers/main.yml +5 -0
- data/ansible/roles/mu-base/meta/main.yml +53 -0
- data/ansible/roles/mu-base/tasks/main.yml +113 -0
- data/ansible/roles/mu-base/templates/nrpe.cfg.j2 +231 -0
- data/ansible/roles/mu-base/tests/inventory +2 -0
- data/ansible/roles/mu-base/tests/test.yml +5 -0
- data/ansible/roles/mu-base/vars/main.yml +1 -0
- data/ansible/roles/mu-compliance/README.md +33 -0
- data/ansible/roles/mu-compliance/defaults/main.yml +2 -0
- data/ansible/roles/mu-compliance/files/U_MS_Windows_Server_2016_V2R1_STIG_SCAP_1-2_Benchmark.xml +15674 -0
- data/ansible/roles/mu-compliance/files/U_MS_Windows_Server_2019_V2R1_STIG_SCAP_1-2_Benchmark.xml +17553 -0
- data/ansible/roles/mu-compliance/handlers/main.yml +2 -0
- data/ansible/roles/mu-compliance/meta/main.yml +53 -0
- data/ansible/roles/mu-compliance/tasks/main.yml +45 -0
- data/ansible/roles/mu-compliance/tests/inventory +2 -0
- data/ansible/roles/mu-compliance/tests/test.yml +5 -0
- data/ansible/roles/mu-compliance/vars/main.yml +4 -0
- data/ansible/roles/mu-elastic/README.md +51 -0
- data/ansible/roles/mu-elastic/defaults/main.yml +2 -0
- data/ansible/roles/mu-elastic/files/jvm.options +93 -0
- data/ansible/roles/mu-elastic/handlers/main.yml +10 -0
- data/ansible/roles/mu-elastic/meta/main.yml +52 -0
- data/ansible/roles/mu-elastic/tasks/main.yml +186 -0
- data/ansible/roles/mu-elastic/templates/elasticsearch.yml.j2 +110 -0
- data/ansible/roles/mu-elastic/templates/kibana.yml.j2 +131 -0
- data/ansible/roles/mu-elastic/templates/password_set.expect.j2 +19 -0
- data/ansible/roles/mu-elastic/tests/inventory +2 -0
- data/ansible/roles/mu-elastic/tests/test.yml +5 -0
- data/ansible/roles/mu-elastic/vars/main.yml +2 -0
- data/ansible/roles/mu-logstash/README.md +51 -0
- data/ansible/roles/mu-logstash/defaults/main.yml +2 -0
- data/ansible/roles/mu-logstash/files/02-beats-input.conf +5 -0
- data/ansible/roles/mu-logstash/files/10-rails-filter.conf +16 -0
- data/ansible/roles/mu-logstash/files/jvm.options +84 -0
- data/ansible/roles/mu-logstash/files/logstash.yml +304 -0
- data/ansible/roles/mu-logstash/handlers/main.yml +20 -0
- data/ansible/roles/mu-logstash/meta/main.yml +52 -0
- data/ansible/roles/mu-logstash/tasks/main.yml +254 -0
- data/ansible/roles/mu-logstash/templates/20-cloudtrail.conf.j2 +28 -0
- data/ansible/roles/mu-logstash/templates/30-elasticsearch-output.conf.j2 +19 -0
- data/ansible/roles/mu-logstash/templates/apm-server.yml.j2 +33 -0
- data/ansible/roles/mu-logstash/templates/heartbeat.yml.j2 +29 -0
- data/ansible/roles/mu-logstash/templates/nginx/apm.conf.j2 +25 -0
- data/ansible/roles/mu-logstash/templates/nginx/default.conf.j2 +56 -0
- data/ansible/roles/mu-logstash/templates/nginx/elastic.conf.j2 +27 -0
- data/ansible/roles/mu-logstash/tests/inventory +2 -0
- data/ansible/roles/mu-logstash/tests/test.yml +5 -0
- data/ansible/roles/mu-logstash/vars/main.yml +2 -0
- data/ansible/roles/mu-rdp/README.md +33 -0
- data/ansible/roles/mu-rdp/meta/main.yml +53 -0
- data/ansible/roles/mu-rdp/tasks/main.yml +9 -0
- data/ansible/roles/mu-rdp/tests/inventory +2 -0
- data/ansible/roles/mu-rdp/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/tasks/main.yml +3 -0
- data/bin/mu-ansible-secret +1 -1
- data/bin/mu-aws-setup +4 -3
- data/bin/mu-azure-setup +5 -5
- data/bin/mu-configure +25 -17
- data/bin/mu-firewall-allow-clients +1 -0
- data/bin/mu-gcp-setup +3 -3
- data/bin/mu-load-config.rb +1 -0
- data/bin/mu-node-manage +66 -33
- data/bin/mu-self-update +2 -2
- data/bin/mu-upload-chef-artifacts +6 -1
- data/bin/mu-user-manage +1 -1
- data/cloud-mu.gemspec +25 -23
- data/cookbooks/firewall/CHANGELOG.md +417 -224
- data/cookbooks/firewall/LICENSE +202 -0
- data/cookbooks/firewall/README.md +153 -126
- data/cookbooks/firewall/TODO.md +6 -0
- data/cookbooks/firewall/attributes/firewalld.rb +7 -0
- data/cookbooks/firewall/attributes/iptables.rb +3 -3
- data/cookbooks/firewall/chefignore +115 -0
- data/cookbooks/firewall/libraries/helpers.rb +5 -0
- data/cookbooks/firewall/libraries/helpers_firewalld.rb +1 -1
- data/cookbooks/firewall/libraries/helpers_firewalld_dbus.rb +72 -0
- data/cookbooks/firewall/libraries/helpers_iptables.rb +3 -3
- data/cookbooks/firewall/libraries/helpers_nftables.rb +170 -0
- data/cookbooks/firewall/libraries/helpers_ufw.rb +7 -0
- data/cookbooks/firewall/libraries/helpers_windows.rb +8 -9
- data/cookbooks/firewall/libraries/provider_firewall_firewalld.rb +9 -9
- data/cookbooks/firewall/libraries/provider_firewall_iptables.rb +7 -7
- data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb +12 -8
- data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb +13 -9
- data/cookbooks/firewall/libraries/provider_firewall_rule.rb +1 -1
- data/cookbooks/firewall/libraries/provider_firewall_ufw.rb +5 -5
- data/cookbooks/firewall/libraries/provider_firewall_windows.rb +4 -4
- data/cookbooks/firewall/libraries/resource_firewall_rule.rb +3 -3
- data/cookbooks/firewall/metadata.json +40 -1
- data/cookbooks/firewall/metadata.rb +15 -0
- data/cookbooks/firewall/recipes/default.rb +7 -7
- data/cookbooks/firewall/recipes/disable_firewall.rb +1 -1
- data/cookbooks/firewall/recipes/firewalld.rb +87 -0
- data/cookbooks/firewall/renovate.json +18 -0
- data/cookbooks/firewall/resources/firewalld.rb +28 -0
- data/cookbooks/firewall/resources/firewalld_config.rb +39 -0
- data/cookbooks/firewall/resources/firewalld_helpers.rb +106 -0
- data/cookbooks/firewall/resources/firewalld_icmptype.rb +88 -0
- data/cookbooks/firewall/resources/firewalld_ipset.rb +104 -0
- data/cookbooks/firewall/resources/firewalld_policy.rb +115 -0
- data/cookbooks/firewall/resources/firewalld_service.rb +98 -0
- data/cookbooks/firewall/resources/firewalld_zone.rb +118 -0
- data/cookbooks/firewall/resources/nftables.rb +71 -0
- data/cookbooks/firewall/resources/nftables_rule.rb +113 -0
- data/cookbooks/mu-activedirectory/Berksfile +1 -1
- data/cookbooks/mu-activedirectory/metadata.rb +1 -1
- data/cookbooks/mu-firewall/metadata.rb +2 -2
- data/cookbooks/mu-master/Berksfile +4 -3
- data/cookbooks/mu-master/attributes/default.rb +5 -2
- data/cookbooks/mu-master/files/default/check_elastic.sh +761 -0
- data/cookbooks/mu-master/files/default/check_kibana.rb +45 -0
- data/cookbooks/mu-master/libraries/mu.rb +24 -0
- data/cookbooks/mu-master/metadata.rb +5 -5
- data/cookbooks/mu-master/recipes/default.rb +31 -20
- data/cookbooks/mu-master/recipes/firewall-holes.rb +5 -0
- data/cookbooks/mu-master/recipes/init.rb +58 -19
- data/cookbooks/mu-master/recipes/update_nagios_only.rb +251 -178
- data/cookbooks/mu-master/templates/default/nagios.conf.erb +5 -11
- data/cookbooks/mu-master/templates/default/web_app.conf.erb +3 -0
- data/cookbooks/mu-php54/Berksfile +1 -1
- data/cookbooks/mu-php54/metadata.rb +2 -2
- data/cookbooks/mu-tools/Berksfile +2 -3
- data/cookbooks/mu-tools/attributes/default.rb +3 -4
- data/cookbooks/mu-tools/files/amazon/etc/bashrc +90 -0
- data/cookbooks/mu-tools/files/amazon/etc/login.defs +292 -0
- data/cookbooks/mu-tools/files/amazon/etc/profile +77 -0
- data/cookbooks/mu-tools/files/amazon/etc/security/limits.conf +63 -0
- data/cookbooks/mu-tools/files/amazon/etc/sysconfig/init +19 -0
- data/cookbooks/mu-tools/files/amazon/etc/sysctl.conf +82 -0
- data/cookbooks/mu-tools/files/amazon-2023/etc/login.defs +294 -0
- data/cookbooks/mu-tools/files/default/logrotate.conf +35 -0
- data/cookbooks/mu-tools/files/default/nrpe_conf_d.pp +0 -0
- data/cookbooks/mu-tools/libraries/helper.rb +21 -9
- data/cookbooks/mu-tools/metadata.rb +4 -4
- data/cookbooks/mu-tools/recipes/apply_security.rb +3 -2
- data/cookbooks/mu-tools/recipes/aws_api.rb +23 -5
- data/cookbooks/mu-tools/recipes/base_repositories.rb +4 -1
- data/cookbooks/mu-tools/recipes/gcloud.rb +56 -56
- data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
- data/cookbooks/mu-tools/recipes/nrpe.rb +20 -2
- data/cookbooks/mu-tools/recipes/rsyslog.rb +12 -1
- data/cookbooks/mu-tools/recipes/set_local_fw.rb +1 -1
- data/data_bags/nagios_services/apm_backend_connect.json +5 -0
- data/data_bags/nagios_services/apm_listen.json +5 -0
- data/data_bags/nagios_services/elastic_shards.json +5 -0
- data/data_bags/nagios_services/logstash.json +5 -0
- data/data_bags/nagios_services/rhel7_updates.json +8 -0
- data/extras/image-generators/AWS/centos7.yaml +1 -0
- data/extras/image-generators/AWS/rhel7.yaml +21 -0
- data/extras/image-generators/AWS/win2k12r2.yaml +1 -0
- data/extras/image-generators/AWS/win2k16.yaml +1 -0
- data/extras/image-generators/AWS/win2k19.yaml +1 -0
- data/extras/list-stock-amis +0 -0
- data/extras/ruby_rpm/muby.spec +8 -5
- data/extras/vault_tools/export_vaults.sh +1 -1
- data/extras/vault_tools/recreate_vaults.sh +0 -0
- data/extras/vault_tools/test_vaults.sh +0 -0
- data/install/deprecated-bash-library.sh +1 -1
- data/install/installer +4 -2
- data/modules/mommacat.ru +3 -1
- data/modules/mu/adoption.rb +1 -1
- data/modules/mu/cloud/dnszone.rb +2 -2
- data/modules/mu/cloud/machine_images.rb +26 -25
- data/modules/mu/cloud/resource_base.rb +213 -182
- data/modules/mu/cloud/server_pool.rb +1 -1
- data/modules/mu/cloud/ssh_sessions.rb +7 -5
- data/modules/mu/cloud/wrappers.rb +2 -2
- data/modules/mu/cloud.rb +1 -1
- data/modules/mu/config/bucket.rb +1 -1
- data/modules/mu/config/function.rb +6 -1
- data/modules/mu/config/loadbalancer.rb +24 -2
- data/modules/mu/config/ref.rb +12 -0
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/schema_helpers.rb +42 -9
- data/modules/mu/config/server.rb +43 -27
- data/modules/mu/config/tail.rb +19 -10
- data/modules/mu/config.rb +6 -5
- data/modules/mu/defaults/AWS.yaml +78 -114
- data/modules/mu/deploy.rb +9 -2
- data/modules/mu/groomer.rb +12 -4
- data/modules/mu/groomers/ansible.rb +104 -20
- data/modules/mu/groomers/chef.rb +15 -6
- data/modules/mu/master.rb +9 -4
- data/modules/mu/mommacat/daemon.rb +4 -2
- data/modules/mu/mommacat/naming.rb +1 -2
- data/modules/mu/mommacat/storage.rb +7 -2
- data/modules/mu/mommacat.rb +33 -6
- data/modules/mu/providers/aws/database.rb +161 -8
- data/modules/mu/providers/aws/dnszone.rb +11 -6
- data/modules/mu/providers/aws/endpoint.rb +81 -6
- data/modules/mu/providers/aws/firewall_rule.rb +254 -172
- data/modules/mu/providers/aws/function.rb +65 -3
- data/modules/mu/providers/aws/loadbalancer.rb +39 -28
- data/modules/mu/providers/aws/log.rb +2 -1
- data/modules/mu/providers/aws/role.rb +25 -7
- data/modules/mu/providers/aws/server.rb +36 -12
- data/modules/mu/providers/aws/server_pool.rb +237 -127
- data/modules/mu/providers/aws/storage_pool.rb +7 -1
- data/modules/mu/providers/aws/user.rb +1 -1
- data/modules/mu/providers/aws/userdata/linux.erb +6 -2
- data/modules/mu/providers/aws/userdata/windows.erb +7 -5
- data/modules/mu/providers/aws/vpc.rb +49 -25
- data/modules/mu/providers/aws.rb +13 -8
- data/modules/mu/providers/azure/container_cluster.rb +1 -1
- data/modules/mu/providers/azure/loadbalancer.rb +2 -2
- data/modules/mu/providers/azure/server.rb +5 -2
- data/modules/mu/providers/azure/userdata/linux.erb +1 -1
- data/modules/mu/providers/azure.rb +11 -8
- data/modules/mu/providers/cloudformation/dnszone.rb +1 -1
- data/modules/mu/providers/google/container_cluster.rb +15 -2
- data/modules/mu/providers/google/folder.rb +2 -1
- data/modules/mu/providers/google/function.rb +130 -4
- data/modules/mu/providers/google/habitat.rb +2 -1
- data/modules/mu/providers/google/loadbalancer.rb +407 -160
- data/modules/mu/providers/google/role.rb +16 -3
- data/modules/mu/providers/google/server.rb +5 -1
- data/modules/mu/providers/google/user.rb +25 -18
- data/modules/mu/providers/google/userdata/linux.erb +1 -1
- data/modules/mu/providers/google/vpc.rb +53 -7
- data/modules/mu/providers/google.rb +39 -39
- data/modules/mu.rb +8 -8
- data/modules/tests/elk.yaml +46 -0
- data/test/mu-master-test/controls/all_in_one.rb +1 -1
- metadata +207 -112
- data/cookbooks/firewall/CONTRIBUTING.md +0 -2
- data/cookbooks/firewall/MAINTAINERS.md +0 -19
- data/cookbooks/firewall/libraries/matchers.rb +0 -30
- data/extras/image-generators/AWS/rhel71.yaml +0 -17
|
@@ -19,6 +19,7 @@ module MU
|
|
|
19
19
|
class Groomer
|
|
20
20
|
# Support for Ansible as a host configuration management layer.
|
|
21
21
|
class Ansible
|
|
22
|
+
require 'open3'
|
|
22
23
|
|
|
23
24
|
# Failure to load or create a deploy
|
|
24
25
|
class NoAnsibleExecError < MuError;
|
|
@@ -77,7 +78,7 @@ module MU
|
|
|
77
78
|
# @param data [Hash]: Data to save
|
|
78
79
|
# @param permissions [Boolean]: If true, save the secret under the current active deploy (if any), rather than in the global location for this user
|
|
79
80
|
# @param deploy_dir [String]: If permissions is +true+, save the secret here
|
|
80
|
-
def self.saveSecret(vault: nil, item: nil, data: nil, permissions: false, deploy_dir: nil)
|
|
81
|
+
def self.saveSecret(vault: nil, item: nil, data: nil, permissions: false, deploy_dir: nil, quiet: false)
|
|
81
82
|
|
|
82
83
|
if vault.nil? or vault.empty? or item.nil? or item.empty?
|
|
83
84
|
raise MuError, "Must call saveSecret with vault and item names"
|
|
@@ -86,6 +87,7 @@ module MU
|
|
|
86
87
|
raise MuError, "Ansible vault/item names cannot include forward slashes"
|
|
87
88
|
end
|
|
88
89
|
pwfile = vaultPasswordFile
|
|
90
|
+
vault_cmd = %Q{#{ansibleExecDir}/ansible-vault}
|
|
89
91
|
|
|
90
92
|
dir = if permissions
|
|
91
93
|
if deploy_dir
|
|
@@ -104,7 +106,7 @@ module MU
|
|
|
104
106
|
FileUtils.mkdir_p(dir, mode: 0700)
|
|
105
107
|
end
|
|
106
108
|
|
|
107
|
-
if File.exist?(path)
|
|
109
|
+
if File.exist?(path) and !quiet
|
|
108
110
|
MU.log "Overwriting existing vault #{vault} item #{item}"
|
|
109
111
|
end
|
|
110
112
|
|
|
@@ -112,14 +114,36 @@ module MU
|
|
|
112
114
|
f.write data.to_yaml
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
cmd = %Q{#{
|
|
116
|
-
MU.log cmd
|
|
117
|
+
cmd = %Q{#{vault_cmd} encrypt #{path} --vault-password-file #{pwfile}}
|
|
118
|
+
MU.log cmd if !quiet
|
|
117
119
|
raise MuError, "Failed Ansible command: #{cmd}" if !system(cmd)
|
|
120
|
+
|
|
121
|
+
# If we're stashing things under a deploy, go ahead and munge them into
|
|
122
|
+
# variables that actual Ansible tasks can get at
|
|
123
|
+
if permissions
|
|
124
|
+
encrypted_string = File.read(path).chomp
|
|
125
|
+
dir = (deploy_dir ? deploy_dir : MU.mommacat.deploy_dir)+"/ansible"
|
|
126
|
+
FileUtils.mkdir_p(dir, mode: 0700) if !Dir.exist?(dir)
|
|
127
|
+
FileUtils.mkdir_p(dir+"/vars", mode: 0700) if !Dir.exist?(dir+"/vars")
|
|
128
|
+
vars_file = "#{dir}/vars/#{vault}.yml"
|
|
129
|
+
|
|
130
|
+
vars = if File.exist?(vars_file)
|
|
131
|
+
YAML.load(File.read(vars_file))
|
|
132
|
+
else
|
|
133
|
+
{}
|
|
134
|
+
end
|
|
135
|
+
vars[item] = encrypted_string
|
|
136
|
+
File.open(vars_file, File::CREAT|File::RDWR|File::TRUNC, 0600) { |f|
|
|
137
|
+
f.flock(File::LOCK_EX)
|
|
138
|
+
f.puts vars.to_yaml
|
|
139
|
+
f.flock(File::LOCK_UN)
|
|
140
|
+
}
|
|
141
|
+
end
|
|
118
142
|
end
|
|
119
143
|
|
|
120
144
|
# see {MU::Groomer::Ansible.saveSecret}
|
|
121
|
-
def saveSecret(vault: @server.mu_name, item: nil, data: nil, permissions: true)
|
|
122
|
-
self.class.saveSecret(vault: vault, item: item, data: data, permissions: permissions, deploy_dir: @server.deploy.deploy_dir)
|
|
145
|
+
def saveSecret(vault: @server.mu_name, item: nil, data: nil, permissions: true, quiet: false)
|
|
146
|
+
self.class.saveSecret(vault: vault, item: item, data: data, permissions: permissions, deploy_dir: @server.deploy.deploy_dir, quiet: quiet)
|
|
123
147
|
end
|
|
124
148
|
|
|
125
149
|
# Retrieve sensitive data, which hopefully we're storing and retrieving
|
|
@@ -128,7 +152,7 @@ module MU
|
|
|
128
152
|
# @param item [String]: The item within the repository to retrieve
|
|
129
153
|
# @param field [String]: OPTIONAL - A specific field within the item to return.
|
|
130
154
|
# @return [Hash]
|
|
131
|
-
def self.getSecret(vault: nil, item: nil, field: nil, deploy_dir: nil)
|
|
155
|
+
def self.getSecret(vault: nil, item: nil, field: nil, deploy_dir: nil, quiet: false, cmd_only: false)
|
|
132
156
|
if vault.nil? or vault.empty?
|
|
133
157
|
raise MuError, "Must call getSecret with at least a vault name"
|
|
134
158
|
end
|
|
@@ -137,7 +161,7 @@ module MU
|
|
|
137
161
|
dir = nil
|
|
138
162
|
try = [secret_dir+"/"+vault]
|
|
139
163
|
try << deploy_dir+"/ansible/vaults/"+vault if deploy_dir
|
|
140
|
-
try << MU.mommacat.deploy_dir+"/ansible/vaults/"+vault if MU.mommacat.deploy_dir
|
|
164
|
+
try << MU.mommacat.deploy_dir+"/ansible/vaults/"+vault if MU.mommacat and MU.mommacat.deploy_dir
|
|
141
165
|
try.each { |maybe_dir|
|
|
142
166
|
if Dir.exist?(maybe_dir) and (item.nil? or File.exist?(maybe_dir+"/"+item))
|
|
143
167
|
dir = maybe_dir
|
|
@@ -155,7 +179,8 @@ module MU
|
|
|
155
179
|
raise MuNoSuchSecret, "No such item #{item} in vault #{vault}"
|
|
156
180
|
end
|
|
157
181
|
cmd = %Q{#{ansibleExecDir}/ansible-vault view #{itempath} --vault-password-file #{pwfile}}
|
|
158
|
-
|
|
182
|
+
return cmd if cmd_only
|
|
183
|
+
MU.log cmd if !quiet
|
|
159
184
|
a = `#{cmd}`
|
|
160
185
|
# If we happen to have stored recognizeable JSON or YAML, return it
|
|
161
186
|
# as parsed, which is a behavior we're used to from Chef vault.
|
|
@@ -187,8 +212,8 @@ module MU
|
|
|
187
212
|
end
|
|
188
213
|
|
|
189
214
|
# see {MU::Groomer::Ansible.getSecret}
|
|
190
|
-
def getSecret(vault:
|
|
191
|
-
self.class.getSecret(vault: vault, item: item, field: field, deploy_dir: @server.deploy.deploy_dir)
|
|
215
|
+
def getSecret(vault: @server.mu_name, item: nil, field: nil, quiet: false, cmd_only: false)
|
|
216
|
+
self.class.getSecret(vault: vault, item: item, field: field, deploy_dir: @server.deploy.deploy_dir, quiet: quiet, cmd_only: cmd_only)
|
|
192
217
|
end
|
|
193
218
|
|
|
194
219
|
# Delete a Ansible data bag / Vault
|
|
@@ -259,6 +284,16 @@ module MU
|
|
|
259
284
|
|
|
260
285
|
cmd = %Q{cd #{@ansible_path} && echo "#{purpose}" && #{@ansible_execs}/ansible-playbook -i hosts #{playbook} --limit=#{@server.windows? ? @server.canonicalIP : @server.mu_name} --vault-password-file #{pwfile} --timeout=30 --vault-password-file #{@ansible_path}/.vault_pw -u #{ssh_user}}
|
|
261
286
|
|
|
287
|
+
if @server.config['vault_access']
|
|
288
|
+
@server.config['vault_access'].each { |entry|
|
|
289
|
+
vault = entry['vault'] || @server.deploy.deploy_id
|
|
290
|
+
begin
|
|
291
|
+
MU.log "To retrieve secret #{vault}:#{entry['item']} - "+getSecret(vault: vault, item: entry['item'], cmd_only: true), MU::SUMMARY
|
|
292
|
+
rescue MuNoSuchSecret
|
|
293
|
+
end
|
|
294
|
+
}
|
|
295
|
+
end
|
|
296
|
+
|
|
262
297
|
retries = 0
|
|
263
298
|
begin
|
|
264
299
|
MU.log cmd
|
|
@@ -315,8 +350,13 @@ module MU
|
|
|
315
350
|
play["become"] = "yes"
|
|
316
351
|
end
|
|
317
352
|
|
|
318
|
-
if @server.
|
|
319
|
-
play["roles"] =
|
|
353
|
+
if @server.windows?
|
|
354
|
+
play["roles"] = ["mu-windows"]
|
|
355
|
+
else
|
|
356
|
+
play["roles"] = ["mu-base"]
|
|
357
|
+
end
|
|
358
|
+
if @server.config['run_list']
|
|
359
|
+
play["roles"].concat(@server.config['run_list'])
|
|
320
360
|
end
|
|
321
361
|
|
|
322
362
|
if @server.config['ansible_vars']
|
|
@@ -326,6 +366,7 @@ module MU
|
|
|
326
366
|
if @server.windows?
|
|
327
367
|
play["vars"] ||= {}
|
|
328
368
|
play["vars"]["ansible_connection"] = "winrm"
|
|
369
|
+
play["vars"]['ansible_python_interpreter'] = "c:/bin/python/python310/python.exe"
|
|
329
370
|
play["vars"]["ansible_winrm_scheme"] = "https"
|
|
330
371
|
play["vars"]["ansible_winrm_transport"] = "ntlm"
|
|
331
372
|
play["vars"]["ansible_winrm_server_cert_validation"] = "ignore" # XXX this sucks; use Mu_CA.pem if we can get it to work
|
|
@@ -355,18 +396,43 @@ module MU
|
|
|
355
396
|
allvars = {
|
|
356
397
|
"mu_deployment" => MU::Config.stripConfig(@server.deploy.deployment),
|
|
357
398
|
"mu_service_name" => @config["name"],
|
|
399
|
+
"mu_name" => @server.mu_name,
|
|
400
|
+
"mu_deploy_id" => @server.deploy.deploy_id,
|
|
358
401
|
"mu_canonical_ip" => @server.canonicalIP,
|
|
359
402
|
"mu_admin_email" => $MU_CFG['mu_admin_email'],
|
|
360
|
-
"mu_environment" => MU.environment.downcase
|
|
403
|
+
"mu_environment" => MU.environment.downcase,
|
|
404
|
+
"mu_vaults" => {}
|
|
361
405
|
}
|
|
362
406
|
allvars['mu_deployment']['ssh_public_key'] = @server.deploy.ssh_public_key
|
|
363
407
|
|
|
408
|
+
vaultdir = @ansible_path+"/vaults"
|
|
409
|
+
if Dir.exist?(vaultdir)
|
|
410
|
+
Dir.entries(vaultdir).each { |v|
|
|
411
|
+
next if !File.directory?(vaultdir+"/"+v)
|
|
412
|
+
next if [".", ".."].include?(v)
|
|
413
|
+
Dir.entries(vaultdir+"/"+v).each { |i|
|
|
414
|
+
next if File.directory?(vaultdir+"/"+v+"/"+i)
|
|
415
|
+
value = getSecret(vault: v, item: i, quiet: true)
|
|
416
|
+
next if !value # ignore corrupted data
|
|
417
|
+
|
|
418
|
+
# Ansible struggles to actually use this. The only thing that
|
|
419
|
+
# seems to work is writing it (decrypted) to a tmp file on the
|
|
420
|
+
# target host then reading that back, which is both ugly and
|
|
421
|
+
# insecure. None of these workarounds seem to do the thing:
|
|
422
|
+
# https://github.com/ansible/ansible/issues/24425
|
|
423
|
+
allvars["mu_vaults"][v] ||= {}
|
|
424
|
+
allvars["mu_vaults"][v].merge!(YAML.load(self.class.encryptString(value.to_yaml, i)))
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
end
|
|
428
|
+
|
|
364
429
|
if @server.config['cloud'] == "AWS"
|
|
365
430
|
allvars["ec2"] = MU.structToHash(@server.cloud_desc, stringify_keys: true)
|
|
366
431
|
end
|
|
367
432
|
|
|
368
433
|
if @server.windows?
|
|
369
434
|
allvars['windows_admin_username'] = @config['windows_admin_username']
|
|
435
|
+
allvars['ansible_python_interpreter'] = "c:/bin/python/python310/python.exe"
|
|
370
436
|
end
|
|
371
437
|
|
|
372
438
|
if !@server.cloud.nil?
|
|
@@ -380,6 +446,9 @@ module MU
|
|
|
380
446
|
}
|
|
381
447
|
|
|
382
448
|
groupvars = allvars.dup
|
|
449
|
+
if @server.windows? and @server.mu_windows_name
|
|
450
|
+
groupvars['mu_windows_name'] = @server.mu_windows_name
|
|
451
|
+
end
|
|
383
452
|
if @server.deploy.original_config.has_key?('parameters')
|
|
384
453
|
groupvars["mu_parameters"] = @server.deploy.original_config['parameters']
|
|
385
454
|
end
|
|
@@ -433,17 +502,23 @@ module MU
|
|
|
433
502
|
found
|
|
434
503
|
end
|
|
435
504
|
|
|
436
|
-
# Encrypt a string using +ansible-vault encrypt_string+ and
|
|
437
|
-
# the results to +STDOUT+.
|
|
438
|
-
# @param name [String]: The variable name to use for the string's YAML key
|
|
505
|
+
# Encrypt a string using +ansible-vault encrypt_string+ and return +STDOUT+
|
|
439
506
|
# @param string [String]: The string to encrypt
|
|
440
|
-
|
|
507
|
+
# @param name [String]: A name to use for the string's YAML key
|
|
508
|
+
def self.encryptString(string, name = nil)
|
|
441
509
|
pwfile = vaultPasswordFile
|
|
442
510
|
cmd = %Q{#{ansibleExecDir}/ansible-vault}
|
|
443
|
-
|
|
511
|
+
|
|
512
|
+
stdout, status = if name
|
|
513
|
+
Open3.capture2(cmd, "encrypt_string", string, "--name", name, "--vault-password-file", pwfile)
|
|
514
|
+
else
|
|
515
|
+
Open3.capture2(cmd, "encrypt_string", string, "--vault-password-file", pwfile)
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
if !status.success?
|
|
444
519
|
raise MuError, "Failed Ansible command: #{cmd} encrypt_string <redacted> --name #{name} --vault-password-file"
|
|
445
520
|
end
|
|
446
|
-
|
|
521
|
+
stdout.strip
|
|
447
522
|
end
|
|
448
523
|
|
|
449
524
|
# Hunt down and return a path for a Python executable
|
|
@@ -630,6 +705,14 @@ module MU
|
|
|
630
705
|
File.symlink(MU.myRoot+"/ansible/roles/"+role, roledir+"/"+role)
|
|
631
706
|
}
|
|
632
707
|
|
|
708
|
+
coldir = "#{Etc.getpwuid(Process.uid).dir}/.ansible/collections/ansible_collections"
|
|
709
|
+
["ansible.windows", "community.general.gem"].each { |coll|
|
|
710
|
+
%x{#{@ansible_execs}/ansible-galaxy collection list -p "#{coldir}"}
|
|
711
|
+
if $? != 0
|
|
712
|
+
system(%Q{#{@ansible_execs}/ansible-galaxy}, "collection", "install", coll, "-p", coldir)
|
|
713
|
+
end
|
|
714
|
+
}
|
|
715
|
+
|
|
633
716
|
if @server.config['run_list']
|
|
634
717
|
@server.config['run_list'].each { |role|
|
|
635
718
|
found = false
|
|
@@ -655,6 +738,7 @@ module MU
|
|
|
655
738
|
end
|
|
656
739
|
}
|
|
657
740
|
end
|
|
741
|
+
|
|
658
742
|
end
|
|
659
743
|
|
|
660
744
|
# Upload the certificate to a Chef Vault for this node
|
data/modules/mu/groomers/chef.rb
CHANGED
|
@@ -58,6 +58,9 @@ module MU
|
|
|
58
58
|
require 'chef/knife/ssh'
|
|
59
59
|
require 'mu/monkey_patches/chef_knife_ssh'
|
|
60
60
|
require 'chef/knife/bootstrap'
|
|
61
|
+
require 'chef/knife/bootstrap/train_connector'
|
|
62
|
+
require 'chef/knife/bootstrap/chef_vault_handler'
|
|
63
|
+
require 'chef/knife/bootstrap/client_builder'
|
|
61
64
|
require 'chef/knife/node_delete'
|
|
62
65
|
require 'chef/knife/client_delete'
|
|
63
66
|
require 'chef/knife/data_bag_delete'
|
|
@@ -96,11 +99,11 @@ module MU
|
|
|
96
99
|
}
|
|
97
100
|
end
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
@@knife = "cd #{MU.myRoot} && env -i HOME=#{Etc.getpwnam(MU.mu_user).dir} PATH=/usr/local/ruby-current/bin:/opt/chef/embedded/bin:/usr/bin:/usr/sbin knife"
|
|
100
103
|
# The canonical path to invoke Chef's *knife* utility with a clean environment.
|
|
101
104
|
# @return [String]
|
|
102
|
-
def self.knife
|
|
103
|
-
|
|
105
|
+
def self.knife
|
|
106
|
+
@@knife
|
|
104
107
|
end
|
|
105
108
|
|
|
106
109
|
attr_reader :knife
|
|
@@ -218,7 +221,7 @@ module MU
|
|
|
218
221
|
end
|
|
219
222
|
|
|
220
223
|
# see {MU::Groomer::Chef.getSecret}
|
|
221
|
-
def getSecret(vault:
|
|
224
|
+
def getSecret(vault: @server.mu_name, item: nil, field: nil)
|
|
222
225
|
self.class.getSecret(vault: vault, item: item, field: field)
|
|
223
226
|
end
|
|
224
227
|
|
|
@@ -618,8 +621,10 @@ module MU
|
|
|
618
621
|
kb.name_args = "#{canonical_addr}"
|
|
619
622
|
kb.config[:distro] = 'chef-full'
|
|
620
623
|
kb.config[:ssh_user] = ssh_user
|
|
624
|
+
kb.config[:ssh_verify_host_key] = :accept_new
|
|
621
625
|
kb.config[:forward_agent] = ssh_user
|
|
622
626
|
kb.config[:identity_file] = "#{Etc.getpwuid(Process.uid).dir}/.ssh/#{ssh_key_name}"
|
|
627
|
+
kb.config[:ssh_identity_file] = "#{Etc.getpwuid(Process.uid).dir}/.ssh/#{ssh_key_name}"
|
|
623
628
|
else
|
|
624
629
|
kb = ::Chef::Knife::BootstrapWindowsWinrm.new([@server.mu_name])
|
|
625
630
|
kb.name_args = [@server.mu_name]
|
|
@@ -628,6 +633,7 @@ module MU
|
|
|
628
633
|
kb.config[:winrm_port] = 5986
|
|
629
634
|
kb.config[:session_timeout] = timeout
|
|
630
635
|
kb.config[:operation_timeout] = timeout
|
|
636
|
+
# kb.config[:bootstrap_curl_options] = ""
|
|
631
637
|
if retries % 2 == 0
|
|
632
638
|
kb.config[:host] = canonical_addr
|
|
633
639
|
kb.config[:winrm_authentication_protocol] = :basic
|
|
@@ -658,7 +664,9 @@ module MU
|
|
|
658
664
|
kb.config[:json_attribs] = JSON.generate(json_attribs) if json_attribs.size > 1
|
|
659
665
|
kb.config[:run_list] = run_list
|
|
660
666
|
kb.config[:chef_node_name] = @server.mu_name
|
|
667
|
+
kb.config[:bootstrap_product] = "chef"
|
|
661
668
|
kb.config[:bootstrap_version] = MU.chefVersion
|
|
669
|
+
kb.config[:channel] = "stable"
|
|
662
670
|
# XXX key off of MU verbosity level
|
|
663
671
|
kb.config[:log_level] = :debug
|
|
664
672
|
# kb.config[:ssh_gateway] = "#{nat_ssh_user}@#{nat_ssh_host}" if !nat_ssh_host.nil? # Breaking bootsrap
|
|
@@ -898,7 +906,7 @@ retry
|
|
|
898
906
|
vaults_to_clean.each { |vault|
|
|
899
907
|
MU::MommaCat.lock("vault-#{vault['vault']}", false, true)
|
|
900
908
|
MU.log "Purging unknown clients from #{vault['vault']} #{vault['item']}", MU::DEBUG
|
|
901
|
-
output = %x{#{
|
|
909
|
+
output = %x{#{knife} data bag show "#{vault['vault']}" "#{vault['item']}_keys" --format json}
|
|
902
910
|
# This is an ugly workaround for --clean-unknown-clients, which in
|
|
903
911
|
# fact cleans known clients.
|
|
904
912
|
if output
|
|
@@ -941,7 +949,7 @@ retry
|
|
|
941
949
|
MU::MommaCat.lock("vault-#{vault}", false, true)
|
|
942
950
|
MU.log "Granting #{host} access to #{vault} #{item}"
|
|
943
951
|
begin
|
|
944
|
-
::Chef::Knife.run(['vault', 'update', vault, item, "--
|
|
952
|
+
::Chef::Knife.run(['vault', 'update', vault, item, "--clients", "#{host}"])
|
|
945
953
|
rescue StandardError => e
|
|
946
954
|
MU.log e.inspect, MU::ERR, details: caller
|
|
947
955
|
end
|
|
@@ -1087,6 +1095,7 @@ retry
|
|
|
1087
1095
|
def grantSecretAccess(vault, item)
|
|
1088
1096
|
return if @secrets_granted["#{vault}:#{item}"] == item
|
|
1089
1097
|
self.class.grantSecretAccess(@server.mu_name, vault, item)
|
|
1098
|
+
MU.log %Q{To retrieve secret #{vault}:#{item} - #{self.class.knife} vault show "#{vault}" "#{item}"}, MU::SUMMARY
|
|
1090
1099
|
@secrets_granted["#{vault}:#{item}"] = item
|
|
1091
1100
|
end
|
|
1092
1101
|
|
data/modules/mu/master.rb
CHANGED
|
@@ -202,6 +202,7 @@ module MU
|
|
|
202
202
|
else
|
|
203
203
|
device.dup
|
|
204
204
|
end
|
|
205
|
+
|
|
205
206
|
alias_device = cryptfile ? "/dev/mapper/"+path.gsub(/[^0-9a-z_\-]/i, "_") : realdevice
|
|
206
207
|
|
|
207
208
|
if !File.exist?(realdevice)
|
|
@@ -212,7 +213,7 @@ module MU
|
|
|
212
213
|
cloud_id: MU.myInstanceId,
|
|
213
214
|
kitten_cfg: {}
|
|
214
215
|
)
|
|
215
|
-
dummy_svr.addVolume(device, size)
|
|
216
|
+
dummy_svr.addVolume(dev: device, size: size)
|
|
216
217
|
MU::Cloud::AWS::Server.tagVolumes(
|
|
217
218
|
MU.myInstanceId,
|
|
218
219
|
device: device,
|
|
@@ -228,7 +229,7 @@ module MU
|
|
|
228
229
|
cloud_id: MU.myInstanceId,
|
|
229
230
|
kitten_cfg: { 'project' => MU::Cloud::Google.myProject, 'availability_zone' => MU.myAZ }
|
|
230
231
|
)
|
|
231
|
-
dummy_svr.addVolume(device, size) # This will tag itself sensibly
|
|
232
|
+
dummy_svr.addVolume(dev: device, size: size) # This will tag itself sensibly
|
|
232
233
|
else
|
|
233
234
|
raise MuError, "Not in a familiar cloud, so I don't know how to create volumes for myself"
|
|
234
235
|
end
|
|
@@ -271,14 +272,16 @@ module MU
|
|
|
271
272
|
end
|
|
272
273
|
|
|
273
274
|
%x{/usr/sbin/xfs_admin -l "#{alias_device}" > /dev/null 2>&1}
|
|
275
|
+
|
|
274
276
|
if $?.exitstatus != 0
|
|
275
277
|
MU.log "Formatting #{alias_device}", MU::NOTICE
|
|
276
278
|
%x{/sbin/mkfs.xfs "#{alias_device}"}
|
|
277
279
|
%x{/usr/sbin/xfs_admin -L "#{path.gsub(/[^0-9a-z_\-]/i, "_")}" "#{alias_device}"}
|
|
278
280
|
end
|
|
279
281
|
Dir.mkdir(path, 0700) if !Dir.exist?(path) # XXX recursive
|
|
282
|
+
|
|
280
283
|
%x{/usr/sbin/xfs_info "#{alias_device}" > /dev/null 2>&1}
|
|
281
|
-
if $?.exitstatus
|
|
284
|
+
if $?.exitstatus == 0 and !File.open("/etc/mtab").read.match(/ #{path} /)
|
|
282
285
|
MU.log "Mounting #{alias_device} to #{path}"
|
|
283
286
|
%x{/bin/mount "#{alias_device}" "#{path}"}
|
|
284
287
|
end
|
|
@@ -797,6 +800,7 @@ module MU
|
|
|
797
800
|
nagios_threads = []
|
|
798
801
|
nagios_threads << Thread.new {
|
|
799
802
|
MU.dupGlobals(parent_thread_id)
|
|
803
|
+
Thread.current.thread_variable_set("syncMonitoringConfig", "<main>")
|
|
800
804
|
realhome = Etc.getpwnam("nagios").dir
|
|
801
805
|
[NAGIOS_HOME, "#{NAGIOS_HOME}/.ssh"].each { |dir|
|
|
802
806
|
Dir.mkdir(dir, 0711) if !Dir.exist?(dir)
|
|
@@ -839,6 +843,7 @@ module MU
|
|
|
839
843
|
MU.dupGlobals(parent_thread_id)
|
|
840
844
|
threads << Thread.new {
|
|
841
845
|
MU::MommaCat.setThreadContext(deploy)
|
|
846
|
+
Thread.current.thread_variable_set("syncMonitoringConfig",server.mu_name)
|
|
842
847
|
MU.log "Adding #{server.mu_name} to #{NAGIOS_HOME}/.ssh/config", MU::DEBUG
|
|
843
848
|
MU::Master.addHostToSSHConfig(
|
|
844
849
|
server,
|
|
@@ -941,7 +946,7 @@ module MU
|
|
|
941
946
|
return true if l =~ /^\/dev\/nvme\d/
|
|
942
947
|
}
|
|
943
948
|
else
|
|
944
|
-
return true if File.
|
|
949
|
+
return true if File.exist?("/dev/nvme0n1")
|
|
945
950
|
end
|
|
946
951
|
false
|
|
947
952
|
end
|
|
@@ -213,6 +213,7 @@ module MU
|
|
|
213
213
|
need_reload = false
|
|
214
214
|
@cleanup_threads << Thread.new {
|
|
215
215
|
MU.dupGlobals(parent_thread_id)
|
|
216
|
+
Thread.current.thread_variable_set("cleanTerminatedInstances", deploy_id)
|
|
216
217
|
deploy = MU::MommaCat.getLitter(deploy_id, set_context_to_me: true)
|
|
217
218
|
purged_this_deploy = 0
|
|
218
219
|
MU.log "#{deploy_id} has some kittens in it", loglevel, details: deploy.kittens.keys
|
|
@@ -225,7 +226,8 @@ module MU
|
|
|
225
226
|
servers.each_pair { |mu_name, server|
|
|
226
227
|
server.describe
|
|
227
228
|
if !server.cloud_id
|
|
228
|
-
MU.log "Checking for presence of #{mu_name}, but unable to fetch its cloud_id", MU::WARN,
|
|
229
|
+
MU.log "Checking for presence of instance '#{mu_name}', but unable to fetch its cloud_id", MU::WARN, server.class.name
|
|
230
|
+
pp servers.keys
|
|
229
231
|
elsif !server.active?
|
|
230
232
|
next if File.exist?(deploy_dir(deploy_id)+"/.cleanup-"+server.cloud_id)
|
|
231
233
|
deletia << mu_name
|
|
@@ -313,7 +315,7 @@ module MU
|
|
|
313
315
|
return 0
|
|
314
316
|
end
|
|
315
317
|
|
|
316
|
-
File.unlink(daemonPidFile) if File.
|
|
318
|
+
File.unlink(daemonPidFile) if File.exist?(daemonPidFile)
|
|
317
319
|
MU.log "Starting Momma Cat on port #{MU.mommaCatPort}, logging to #{daemonLogFile}, PID file #{daemonPidFile}"
|
|
318
320
|
origdir = Dir.getwd
|
|
319
321
|
Dir.chdir(MU.myRoot+"/modules")
|
|
@@ -305,9 +305,8 @@ module MU
|
|
|
305
305
|
zones = MU::Cloud::DNSZone.find(cloud_id: "platform-mu")
|
|
306
306
|
mu_zone = zones.values.first if !zones.nil?
|
|
307
307
|
end
|
|
308
|
-
|
|
309
308
|
if !mu_zone.nil?
|
|
310
|
-
MU::Cloud::DNSZone.genericMuDNSEntry(name: node.gsub(/[^a-z0-9!"\#$%&'\(\)\*\+,\-\/:;<=>\?@\[\]\^_`{\|}~\.]
|
|
309
|
+
MU::Cloud::DNSZone.genericMuDNSEntry(name: node.gsub(/[^a-z0-9!"\#$%&'\(\)\*\+,\-\/:;<=>\?@\[\]\^_`{\|}~\.]/i, '-').gsub(/--|^-/, ''), target: server.canonicalIP, cloudclass: MU::Cloud::Server, sync_wait: sync_wait)
|
|
311
310
|
else
|
|
312
311
|
MU::Master.addInstanceToEtcHosts(server.canonicalIP, node)
|
|
313
312
|
end
|
|
@@ -179,6 +179,7 @@ module MU
|
|
|
179
179
|
# return [false, nil]
|
|
180
180
|
def self.lock(id, nonblock = false, global = false, retries: 0, deploy_id: MU.deploy_id)
|
|
181
181
|
raise MuError, "Can't pass a nil id to MU::MommaCat.lock" if id.nil?
|
|
182
|
+
called_by = caller[0]
|
|
182
183
|
|
|
183
184
|
if !global
|
|
184
185
|
lockdir = "#{deploy_dir(deploy_id)}/locks"
|
|
@@ -200,6 +201,10 @@ module MU
|
|
|
200
201
|
@locks[Thread.current.object_id][id] = File.open("#{lockdir}/#{id}.lock", File::CREAT|File::RDWR, 0600)
|
|
201
202
|
}
|
|
202
203
|
|
|
204
|
+
thr_to_s = Proc.new { |t|
|
|
205
|
+
"#{t.object_id} (#{t.thread_variables.map { |v| "#{v.to_s}: #{t.thread_variable_get(v).to_s}" }.join(", ")})"
|
|
206
|
+
}
|
|
207
|
+
|
|
203
208
|
MU.log "Getting a lock on #{lockdir}/#{id}.lock (thread #{Thread.current.object_id})...", MU::DEBUG, details: caller
|
|
204
209
|
show_relevant = Proc.new {
|
|
205
210
|
@lock_semaphore.synchronize {
|
|
@@ -208,7 +213,7 @@ module MU
|
|
|
208
213
|
if lockid == id
|
|
209
214
|
thread = Thread.list.select { |t| t.object_id == thread_id }.first
|
|
210
215
|
if thread.object_id != Thread.current.object_id
|
|
211
|
-
MU.log "#{
|
|
216
|
+
MU.log "Thread #{thr_to_s.call(thread)} sitting on #{id}, which is needed by #{thr_to_s.call(Thread.current)} at #{called_by}", MU::WARN, thread.backtrace
|
|
212
217
|
end
|
|
213
218
|
end
|
|
214
219
|
}
|
|
@@ -585,7 +590,7 @@ module MU
|
|
|
585
590
|
orig_cfg = findResourceConfig(type, res_name)
|
|
586
591
|
|
|
587
592
|
if orig_cfg.nil?
|
|
588
|
-
MU.log "Failed to locate original config for #{attrs[:cfg_name]} #{res_name} in #{@deploy_id}", MU::
|
|
593
|
+
MU.log "Failed to locate original config for #{attrs[:cfg_name]} #{res_name}, seen in cached deployment.json for #{@deploy_id}", MU::DEBUG
|
|
589
594
|
next
|
|
590
595
|
end
|
|
591
596
|
|
data/modules/mu/mommacat.rb
CHANGED
|
@@ -150,6 +150,7 @@ module MU
|
|
|
150
150
|
@deploy_id = deploy_id
|
|
151
151
|
@mu_user = mu_user.dup
|
|
152
152
|
@no_artifacts = no_artifacts
|
|
153
|
+
@ssh_key_generated = false
|
|
153
154
|
|
|
154
155
|
# Make sure mu_user and chef_user are sane.
|
|
155
156
|
if @mu_user == "root"
|
|
@@ -167,7 +168,6 @@ module MU
|
|
|
167
168
|
@need_deploy_flush = false
|
|
168
169
|
@node_cert_semaphore = Mutex.new
|
|
169
170
|
@deployment = deployment_data
|
|
170
|
-
|
|
171
171
|
@deployment['mu_public_ip'] = MU.mu_public_ip
|
|
172
172
|
@private_key = nil
|
|
173
173
|
@public_key = nil
|
|
@@ -175,6 +175,7 @@ module MU
|
|
|
175
175
|
@secrets['instance_secret'] = Hash.new
|
|
176
176
|
@secrets['windows_admin_password'] = Hash.new
|
|
177
177
|
@ssh_key_name = ssh_key_name
|
|
178
|
+
@ssh_key_name ||= "deploy-#{@deploy_id}"
|
|
178
179
|
@ssh_private_key = ssh_private_key
|
|
179
180
|
@ssh_public_key = ssh_public_key
|
|
180
181
|
@clouds = {}
|
|
@@ -195,6 +196,7 @@ module MU
|
|
|
195
196
|
setDeploySecret
|
|
196
197
|
MU::MommaCat.setThreadContext(self) if set_context_to_me
|
|
197
198
|
save!
|
|
199
|
+
generatePasswords
|
|
198
200
|
end
|
|
199
201
|
|
|
200
202
|
@appname ||= MU.appname
|
|
@@ -202,6 +204,7 @@ module MU
|
|
|
202
204
|
@environment ||= MU.environment
|
|
203
205
|
|
|
204
206
|
loadDeploy(set_context_to_me: set_context_to_me)
|
|
207
|
+
@deployment['mu_all_ips'] ||= [MU.mu_public_ip, MU.my_private_ip].uniq
|
|
205
208
|
if !deploy_secret.nil? and !authKey(deploy_secret)
|
|
206
209
|
raise DeployInitializeError, "Client request did not include a valid deploy authorization secret. Verify that userdata runs correctly?"
|
|
207
210
|
end
|
|
@@ -224,6 +227,29 @@ module MU
|
|
|
224
227
|
# if !@@litter_semaphore.owned?
|
|
225
228
|
end # end of initialize()
|
|
226
229
|
|
|
230
|
+
def generatePasswords
|
|
231
|
+
return if !@original_config['generate_passwords']
|
|
232
|
+
|
|
233
|
+
@original_config['generate_passwords'].each { |pw|
|
|
234
|
+
password = MU.generatePassword(safe_pattern: pw['safe_chars'], length: pw['minlength'])
|
|
235
|
+
MU.supportedGroomers.each { |g|
|
|
236
|
+
groomclass = MU.loadGroomer(g)
|
|
237
|
+
begin
|
|
238
|
+
groomclass.getSecret(vault: @deploy_id,
|
|
239
|
+
item: pw['itemname'],
|
|
240
|
+
field: 'password')
|
|
241
|
+
rescue MU::Groomer::MuNoSuchSecret
|
|
242
|
+
pwdata = { "password" => password }
|
|
243
|
+
pwdata["username"] = pw["username"] if pw["username"]
|
|
244
|
+
groomclass.saveSecret(vault: @deploy_id,
|
|
245
|
+
item: pw['itemname'],
|
|
246
|
+
data: pwdata,
|
|
247
|
+
permissions: (g == "Ansible"))
|
|
248
|
+
end
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
end
|
|
252
|
+
|
|
227
253
|
# List all the cloud providers declared by resources in our deploy.
|
|
228
254
|
def cloudsUsed
|
|
229
255
|
seen = []
|
|
@@ -490,7 +516,7 @@ module MU
|
|
|
490
516
|
# Return the parts and pieces of this deploy's node ssh key set. Generate
|
|
491
517
|
# or load if that hasn't been done already.
|
|
492
518
|
def SSHKey
|
|
493
|
-
return [@ssh_key_name, @ssh_private_key, @ssh_public_key] if
|
|
519
|
+
return [@ssh_key_name, @ssh_private_key, @ssh_public_key] if @ssh_key_generated
|
|
494
520
|
if numKittens(types: ["Server", "ServerPool", "ContainerCluster"]) == 0
|
|
495
521
|
return []
|
|
496
522
|
end
|
|
@@ -535,6 +561,7 @@ module MU
|
|
|
535
561
|
}
|
|
536
562
|
end
|
|
537
563
|
|
|
564
|
+
@ssh_key_generated = true
|
|
538
565
|
return [@ssh_key_name, @ssh_private_key, @ssh_public_key]
|
|
539
566
|
end
|
|
540
567
|
|
|
@@ -549,8 +576,8 @@ module MU
|
|
|
549
576
|
# @param triggering_node [MU::Cloud]: A cloud object calling this notify, usually on behalf of itself
|
|
550
577
|
# @param remove [Boolean]: Remove this resource from the deploy structure, instead of adding it.
|
|
551
578
|
# @return [void]
|
|
552
|
-
def notify(type, key, data, mu_name: nil, remove: false, triggering_node: nil, delayed_save: false)
|
|
553
|
-
no_write
|
|
579
|
+
def notify(type, key, data, mu_name: nil, remove: false, triggering_node: nil, delayed_save: false, no_write: nil)
|
|
580
|
+
no_write ||= (@no_artifacts or !caller.grep(/\/mommacat\.rb:\d+:in `notify'/).empty?)
|
|
554
581
|
|
|
555
582
|
begin
|
|
556
583
|
if !no_write
|
|
@@ -831,7 +858,7 @@ MAIL_HEAD_END
|
|
|
831
858
|
next if sibling.config.has_key?("groom") and !sibling.config["groom"]
|
|
832
859
|
threads << Thread.new {
|
|
833
860
|
Thread.abort_on_exception = true
|
|
834
|
-
Thread.current.thread_variable_set("
|
|
861
|
+
Thread.current.thread_variable_set("syncLitterThread", sibling.mu_name)
|
|
835
862
|
MU.setVar("syncLitterThread", true)
|
|
836
863
|
begin
|
|
837
864
|
sibling.groomer.saveDeployData
|
|
@@ -874,7 +901,7 @@ MAIL_HEAD_END
|
|
|
874
901
|
sans << resource.mu_name.downcase if resource.mu_name and resource.mu_name != cert_cn
|
|
875
902
|
# XXX were there other names we wanted to include?
|
|
876
903
|
key = MU::Master::SSL.getKey(cert_cn, keysize: keysize)
|
|
877
|
-
cert, pfx_cert = MU::Master::SSL.getCert(cert_cn, "/CN=#{cert_cn}/O=Mu/C=US", sans: sans, pfx:
|
|
904
|
+
cert, pfx_cert = MU::Master::SSL.getCert(cert_cn, "/CN=#{cert_cn}/O=Mu/C=US", sans: sans, pfx: true)
|
|
878
905
|
results[cert_cn] = [key, cert]
|
|
879
906
|
|
|
880
907
|
winrm_cert = nil
|