cloud-mu 3.1.2 → 3.2.0
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/Dockerfile +15 -3
- data/ansible/roles/mu-windows/README.md +33 -0
- data/ansible/roles/mu-windows/defaults/main.yml +2 -0
- data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
- data/ansible/roles/mu-windows/files/config.xml +76 -0
- data/ansible/roles/mu-windows/handlers/main.yml +2 -0
- data/ansible/roles/mu-windows/meta/main.yml +53 -0
- data/ansible/roles/mu-windows/tasks/main.yml +36 -0
- data/ansible/roles/mu-windows/tests/inventory +2 -0
- data/ansible/roles/mu-windows/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/vars/main.yml +2 -0
- data/bin/mu-adopt +10 -13
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +52 -0
- data/bin/mu-deploy +3 -3
- data/bin/mu-findstray-tests +25 -0
- data/bin/mu-gen-docs +2 -4
- data/bin/mu-load-config.rb +2 -3
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +135 -37
- data/cloud-mu.gemspec +22 -20
- data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
- data/cookbooks/mu-tools/libraries/helper.rb +3 -2
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
- data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
- data/cookbooks/mu-tools/recipes/eks.rb +2 -2
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +18 -13
- data/extras/image-generators/AWS/win2k16.yaml +18 -13
- data/extras/image-generators/AWS/win2k19.yaml +21 -0
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +6 -16
- data/modules/mu.rb +165 -111
- data/modules/mu/adoption.rb +401 -68
- data/modules/mu/cleanup.rb +199 -306
- data/modules/mu/cloud.rb +100 -1632
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +46 -0
- data/modules/mu/cloud/machine_images.rb +212 -0
- data/modules/mu/cloud/providers.rb +81 -0
- data/modules/mu/cloud/resource_base.rb +920 -0
- data/modules/mu/cloud/server.rb +40 -0
- data/modules/mu/cloud/server_pool.rb +1 -0
- data/modules/mu/cloud/ssh_sessions.rb +228 -0
- data/modules/mu/cloud/winrm_sessions.rb +237 -0
- data/modules/mu/cloud/wrappers.rb +165 -0
- data/modules/mu/config.rb +171 -1767
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +4 -4
- data/modules/mu/config/cache_cluster.rb +1 -1
- data/modules/mu/config/collection.rb +4 -4
- data/modules/mu/config/container_cluster.rb +9 -4
- data/modules/mu/config/database.rb +83 -104
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +6 -6
- data/modules/mu/config/doc_helpers.rb +516 -0
- data/modules/mu/config/endpoint.rb +4 -4
- data/modules/mu/config/firewall_rule.rb +103 -4
- data/modules/mu/config/folder.rb +4 -4
- data/modules/mu/config/function.rb +3 -3
- data/modules/mu/config/group.rb +4 -4
- data/modules/mu/config/habitat.rb +4 -4
- data/modules/mu/config/loadbalancer.rb +60 -14
- data/modules/mu/config/log.rb +4 -4
- data/modules/mu/config/msg_queue.rb +4 -4
- data/modules/mu/config/nosqldb.rb +4 -4
- data/modules/mu/config/notifier.rb +3 -3
- data/modules/mu/config/ref.rb +365 -0
- data/modules/mu/config/role.rb +4 -4
- data/modules/mu/config/schema_helpers.rb +509 -0
- data/modules/mu/config/search_domain.rb +4 -4
- data/modules/mu/config/server.rb +97 -70
- data/modules/mu/config/server.yml +1 -0
- data/modules/mu/config/server_pool.rb +5 -9
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +200 -0
- data/modules/mu/config/user.rb +4 -4
- data/modules/mu/config/vpc.rb +70 -27
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +83 -60
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +3 -2
- data/modules/mu/deploy.rb +30 -26
- data/modules/mu/groomer.rb +17 -2
- data/modules/mu/groomers/ansible.rb +188 -41
- data/modules/mu/groomers/chef.rb +116 -55
- data/modules/mu/logger.rb +127 -148
- data/modules/mu/master.rb +389 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -3
- data/modules/mu/mommacat.rb +217 -2612
- data/modules/mu/mommacat/daemon.rb +397 -0
- data/modules/mu/mommacat/naming.rb +473 -0
- data/modules/mu/mommacat/search.rb +495 -0
- data/modules/mu/mommacat/storage.rb +722 -0
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +271 -112
- data/modules/mu/{clouds → providers}/aws/alarm.rb +5 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +26 -22
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +33 -67
- data/modules/mu/{clouds → providers}/aws/collection.rb +24 -23
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +681 -721
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +64 -63
- data/modules/mu/{clouds → providers}/aws/endpoint.rb +22 -27
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +214 -244
- data/modules/mu/{clouds → providers}/aws/folder.rb +7 -7
- data/modules/mu/{clouds → providers}/aws/function.rb +17 -22
- data/modules/mu/{clouds → providers}/aws/group.rb +23 -23
- data/modules/mu/{clouds → providers}/aws/habitat.rb +17 -14
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +57 -48
- data/modules/mu/{clouds → providers}/aws/log.rb +15 -12
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +17 -16
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +18 -11
- data/modules/mu/{clouds → providers}/aws/notifier.rb +11 -6
- data/modules/mu/{clouds → providers}/aws/role.rb +112 -86
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +39 -33
- data/modules/mu/{clouds → providers}/aws/server.rb +835 -1133
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +56 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +24 -42
- data/modules/mu/{clouds → providers}/aws/user.rb +21 -22
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +523 -929
- data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
- data/modules/mu/{clouds → providers}/azure.rb +29 -9
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
- data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
- data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
- data/modules/mu/{clouds → providers}/azure/server.rb +95 -48
- data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
- data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
- data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
- data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
- data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
- data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
- data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +67 -30
- data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +84 -77
- data/modules/mu/{clouds → providers}/google/database.rb +10 -20
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
- data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
- data/modules/mu/{clouds → providers}/google/function.rb +139 -167
- data/modules/mu/{clouds → providers}/google/group.rb +29 -34
- data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +18 -20
- data/modules/mu/{clouds → providers}/google/role.rb +92 -58
- data/modules/mu/{clouds → providers}/google/server.rb +242 -155
- data/modules/mu/{clouds → providers}/google/server_pool.rb +25 -44
- data/modules/mu/{clouds → providers}/google/user.rb +95 -31
- data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/centos6.yaml +11 -0
- data/modules/tests/centos7.yaml +11 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +23 -0
- data/modules/tests/includes-and-params.yaml +2 -1
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +1 -0
- data/modules/tests/super_simple_bok.yml +1 -3
- data/modules/tests/win2k12.yaml +17 -5
- data/modules/tests/win2k16.yaml +25 -0
- data/modules/tests/win2k19.yaml +25 -0
- data/requirements.txt +1 -0
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +232 -154
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1985
|
@@ -195,48 +195,49 @@ action :config do
|
|
|
195
195
|
else
|
|
196
196
|
# We want to run ec2config as admin user so Windows userdata executes as admin, however the local admin account doesn't have Logon As a Service right. Domain privileges are set separately
|
|
197
197
|
|
|
198
|
-
cookbook_file "c:\\Windows\\SysWOW64\\ntrights.exe" do
|
|
199
|
-
source "ntrights"
|
|
200
|
-
end
|
|
201
|
-
[new_resource.ssh_user, new_resource.ec2config_user].each { |usr|
|
|
202
|
-
pass = if usr == new_resource.ec2config_user
|
|
203
|
-
new_resource.ec2config_password
|
|
204
|
-
elsif usr == new_resource.ssh_user
|
|
205
|
-
new_resource.ssh_password
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
user usr do
|
|
209
|
-
password pass
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
198
|
+
# cookbook_file "c:\\Windows\\SysWOW64\\ntrights.exe" do
|
|
199
|
+
# source "ntrights"
|
|
200
|
+
# end
|
|
201
|
+
# [new_resource.ssh_user, new_resource.ec2config_user].each { |usr|
|
|
202
|
+
# pass = if usr == new_resource.ec2config_user
|
|
203
|
+
# new_resource.ec2config_password
|
|
204
|
+
# elsif usr == new_resource.ssh_user
|
|
205
|
+
# new_resource.ssh_password
|
|
206
|
+
# end
|
|
207
|
+
#
|
|
208
|
+
# user usr do
|
|
209
|
+
# password pass
|
|
210
|
+
# action :modify
|
|
211
|
+
# end
|
|
212
|
+
#
|
|
213
|
+
# group "Administrators" do
|
|
214
|
+
# action :modify
|
|
215
|
+
# members usr
|
|
216
|
+
# append true
|
|
217
|
+
# end
|
|
218
|
+
#
|
|
219
|
+
# %w{SeDenyRemoteInteractiveLogonRight SeDenyInteractiveLogonRight SeServiceLogonRight}.each { |privilege|
|
|
220
|
+
# batch "Grant local user #{usr} logon as service right" do
|
|
221
|
+
# code "C:\\Windows\\SysWOW64\\ntrights +r #{privilege} -u #{usr}"
|
|
222
|
+
# end
|
|
223
|
+
# }
|
|
224
|
+
#
|
|
225
|
+
# # XXX user resource seems not to really be setting password, or is setting # in such a way that the user is being required to change it. Workaround.
|
|
226
|
+
# powershell_script "Adjust local account params for #{usr}" do
|
|
227
|
+
# code <<-EOH
|
|
228
|
+
# (([adsi]('WinNT://./#{usr}, user')).psbase.invoke('SetPassword', '#{pass}'))
|
|
229
|
+
# EOH
|
|
230
|
+
# end
|
|
231
|
+
#
|
|
232
|
+
# if usr == new_resource.ssh_user
|
|
233
|
+
#
|
|
234
|
+
# %w{SeCreateTokenPrivilege SeTcbPrivilege SeAssignPrimaryTokenPrivilege}.each { |privilege|
|
|
235
|
+
# batch "Grant local user #{usr} logon as service right" do
|
|
236
|
+
# code "C:\\Windows\\SysWOW64\\ntrights +r #{privilege} -u #{usr}"
|
|
237
|
+
# end
|
|
238
|
+
# }
|
|
239
|
+
#
|
|
240
|
+
# end
|
|
241
|
+
# }
|
|
241
242
|
end
|
|
242
243
|
end
|
data/extras/clean-stock-amis
CHANGED
|
@@ -18,37 +18,43 @@ require 'json'
|
|
|
18
18
|
require File.realpath(File.expand_path(File.dirname(__FILE__)+"/../bin/mu-load-config.rb"))
|
|
19
19
|
require 'mu'
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
$opts = Optimist::options do
|
|
22
|
+
banner <<-EOS
|
|
23
|
+
#{$0} [-c credentials] [-i imagename]
|
|
24
|
+
EOS
|
|
25
|
+
opt :credentials, "Use these AWS credentials from mu.yaml instead of the default set", :required => false, :type => :string
|
|
26
|
+
opt :image, "Purge a specific image, instead of just scrubing old ones", :required => false, :type => :string
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
filters = [
|
|
28
30
|
{
|
|
29
31
|
name: "owner-id",
|
|
30
|
-
values: [MU::Cloud::AWS.credToAcct(credentials)]
|
|
32
|
+
values: [MU::Cloud::AWS.credToAcct($opts[:credentials])]
|
|
31
33
|
}
|
|
32
34
|
]
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
MU::Cloud::AWS.listRegions.each { | r|
|
|
36
|
-
images = MU::Cloud::AWS.ec2(region: r, credentials: credentials).describe_images(
|
|
38
|
+
images = MU::Cloud::AWS.ec2(region: r, credentials: $opts[:credentials]).describe_images(
|
|
37
39
|
filters: filters + [{ "name" => "state", "values" => ["available"]}]
|
|
38
40
|
).images
|
|
39
41
|
images.each { |ami|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
42
|
+
if ($opts[:image] and ami.name == $opts[:image]) or
|
|
43
|
+
((DateTime.now.to_time - DateTime.parse(ami.creation_date).to_time) > 15552000 and ami.name.match(/^MU-(PROD|DEV)/))
|
|
44
|
+
snaps = []
|
|
45
|
+
ami.block_device_mappings.each { |dev|
|
|
46
|
+
if !dev.ebs.nil?
|
|
47
|
+
snaps << dev.ebs.snapshot_id
|
|
48
|
+
end
|
|
49
|
+
}
|
|
50
|
+
MU.log "Deregistering #{ami.name}, #{r} (#{ami.creation_date})", MU::WARN, details: snaps
|
|
51
|
+
begin
|
|
52
|
+
MU::Cloud::AWS.ec2(region: r, credentials: $opts[:credentials]).deregister_image(image_id: ami.image_id)
|
|
53
|
+
rescue Aws::EC2::Errors::InvalidAMIIDUnavailable
|
|
54
|
+
end
|
|
55
|
+
snaps.each { |snap_id|
|
|
56
|
+
MU::Cloud::AWS.ec2(region: r, credentials: $opts[:credentials]).delete_snapshot(snapshot_id: snap_id)
|
|
57
|
+
}
|
|
58
|
+
end
|
|
53
59
|
}
|
|
54
60
|
}
|
|
@@ -91,6 +91,7 @@ $opts[:clouds].each { |cloud|
|
|
|
91
91
|
end
|
|
92
92
|
next if !needed
|
|
93
93
|
end
|
|
94
|
+
MU.log "Loading "+bok_dir+"/"+cloud+"/"+platform+".yaml"
|
|
94
95
|
conf_engine = MU::Config.new(
|
|
95
96
|
bok_dir+"/"+cloud+"/"+platform+".yaml",
|
|
96
97
|
default_credentials: $opts[(cloud.downcase+"_creds").to_sym]
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
appname: mu
|
|
3
|
+
vpcs:
|
|
4
|
+
- name: windowsbuild
|
|
3
5
|
servers:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
- name: win2k12
|
|
7
|
+
platform: win2k12
|
|
8
|
+
vpc:
|
|
9
|
+
name: windowsbuild
|
|
10
|
+
size: m4.large
|
|
11
|
+
scrub_groomer: true
|
|
12
|
+
groomer: Ansible
|
|
13
|
+
run_list:
|
|
14
|
+
- mu-windows
|
|
15
|
+
ansible_vars:
|
|
16
|
+
mu_build_image: true
|
|
17
|
+
create_image:
|
|
18
|
+
image_then_destroy: true
|
|
19
|
+
public: true
|
|
20
|
+
copy_to_regions:
|
|
21
|
+
- "#ALL"
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
appname: mu
|
|
3
|
+
vpcs:
|
|
4
|
+
- name: windowsbuild
|
|
3
5
|
servers:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
- name: win2k16
|
|
7
|
+
platform: win2k16
|
|
8
|
+
vpc:
|
|
9
|
+
name: windowsbuild
|
|
10
|
+
size: m4.large
|
|
11
|
+
scrub_groomer: true
|
|
12
|
+
groomer: Ansible
|
|
13
|
+
run_list:
|
|
14
|
+
- mu-windows
|
|
15
|
+
ansible_vars:
|
|
16
|
+
mu_build_image: true
|
|
17
|
+
create_image:
|
|
18
|
+
image_then_destroy: true
|
|
19
|
+
public: true
|
|
20
|
+
copy_to_regions:
|
|
21
|
+
- "#ALL"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
appname: mu
|
|
3
|
+
vpcs:
|
|
4
|
+
- name: windowsbuild
|
|
5
|
+
servers:
|
|
6
|
+
- name: win2k19
|
|
7
|
+
platform: windows
|
|
8
|
+
vpc:
|
|
9
|
+
name: windowsbuild
|
|
10
|
+
size: m4.large
|
|
11
|
+
scrub_groomer: true
|
|
12
|
+
groomer: Ansible
|
|
13
|
+
run_list:
|
|
14
|
+
- mu-windows
|
|
15
|
+
ansible_vars:
|
|
16
|
+
mu_build_image: true
|
|
17
|
+
create_image:
|
|
18
|
+
image_then_destroy: true
|
|
19
|
+
public: true
|
|
20
|
+
copy_to_regions:
|
|
21
|
+
- "#ALL"
|
data/modules/mommacat.ru
CHANGED
|
@@ -16,7 +16,7 @@ require 'pp'
|
|
|
16
16
|
require 'base64'
|
|
17
17
|
require 'etc'
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Etc.getpwuid(Process.uid).dir
|
|
20
20
|
|
|
21
21
|
if !ENV.include?('MU_INSTALLDIR')
|
|
22
22
|
ENV['MU_INSTALLDIR'] = "/opt/mu"
|
|
@@ -51,8 +51,8 @@ Signal.trap("URG") do
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
begin
|
|
54
|
-
MU::
|
|
55
|
-
rescue
|
|
54
|
+
MU::Master.syncMonitoringConfig(false)
|
|
55
|
+
rescue StandardError => e
|
|
56
56
|
MU.log e.inspect, MU::ERR, details: e.backtrace
|
|
57
57
|
# ...but don't die!
|
|
58
58
|
end
|
|
@@ -64,14 +64,12 @@ Thread.new {
|
|
|
64
64
|
MU::MommaCat.cleanTerminatedInstances
|
|
65
65
|
MU::Master.cleanExpiredScratchpads if $ENABLE_SCRATCHPAD
|
|
66
66
|
sleep 60
|
|
67
|
-
rescue
|
|
67
|
+
rescue StandardError => e
|
|
68
68
|
MU.log "Error in cleanTerminatedInstances thread: #{e.inspect}", MU::ERR, details: e.backtrace
|
|
69
69
|
retry
|
|
70
70
|
end while true
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
required_vars = ["mu_id", "mu_deploy_secret", "mu_resource_name", "mu_resource_type", "mu_instance_id"]
|
|
74
|
-
|
|
75
73
|
# Use a template to generate a pleasant-looking HTML page for simple messages
|
|
76
74
|
# and errors.
|
|
77
75
|
def genHTMLMessage(title: "", headline: "", msg: "", template: $MU_CFG['html_template'], extra_vars: {})
|
|
@@ -193,7 +191,6 @@ def releaseKitten(mu_id)
|
|
|
193
191
|
end
|
|
194
192
|
|
|
195
193
|
app = proc do |env|
|
|
196
|
-
ok = false
|
|
197
194
|
returnval = [
|
|
198
195
|
200,
|
|
199
196
|
{
|
|
@@ -318,7 +315,7 @@ app = proc do |env|
|
|
|
318
315
|
elsif !filter or !path
|
|
319
316
|
returnval = throw404 env['REQUEST_PATH']
|
|
320
317
|
else
|
|
321
|
-
MU::
|
|
318
|
+
MU::Master.addInstanceToEtcHosts(path, filter)
|
|
322
319
|
returnval = [
|
|
323
320
|
200,
|
|
324
321
|
{
|
|
@@ -356,7 +353,6 @@ app = proc do |env|
|
|
|
356
353
|
|
|
357
354
|
elsif !env["rack.input"].nil?
|
|
358
355
|
req = Rack::Utils.parse_nested_query(env["rack.input"].read)
|
|
359
|
-
ok = true
|
|
360
356
|
|
|
361
357
|
if req["mu_user"].nil?
|
|
362
358
|
req["mu_user"] = "mu"
|
|
@@ -373,7 +369,6 @@ app = proc do |env|
|
|
|
373
369
|
kittenpile = getKittenPile(req)
|
|
374
370
|
if kittenpile.nil? or kittenpile.original_config.nil? or kittenpile.original_config[req["mu_resource_type"]+"s"].nil?
|
|
375
371
|
returnval = throw500 "Couldn't find config data for #{req["mu_resource_type"]} in deploy_id #{req["mu_id"]}"
|
|
376
|
-
ok = false
|
|
377
372
|
next
|
|
378
373
|
end
|
|
379
374
|
server_cfg = nil
|
|
@@ -385,7 +380,6 @@ app = proc do |env|
|
|
|
385
380
|
}
|
|
386
381
|
if server_cfg.nil?
|
|
387
382
|
returnval = throw500 "Couldn't find config data for #{req["mu_resource_type"]} name: #{req["mu_resource_name"]} deploy_id: #{req["mu_id"]}"
|
|
388
|
-
ok = false
|
|
389
383
|
next
|
|
390
384
|
end
|
|
391
385
|
|
|
@@ -426,7 +420,6 @@ MU.log "ADDVOLUME REQUEST", MU::WARN, details: params
|
|
|
426
420
|
instance.addVolume(params["dev"], params["size"], delete_on_termination: params["delete_on_termination"])
|
|
427
421
|
else
|
|
428
422
|
returnval = throw500 "I don't know how to add a volume for #{instance}"
|
|
429
|
-
ok = false
|
|
430
423
|
end
|
|
431
424
|
elsif !instance.nil?
|
|
432
425
|
if !req["mu_bootstrap"].nil?
|
|
@@ -434,16 +427,13 @@ MU.log "ADDVOLUME REQUEST", MU::WARN, details: params
|
|
|
434
427
|
returnval[2] = ["Grooming asynchronously, check Momma Cat logs on the master for details."]
|
|
435
428
|
else
|
|
436
429
|
returnval = throw500 "Didn't get 'mu_bootstrap' parameter from instance id '#{req["mu_instance_id"]}'"
|
|
437
|
-
ok = false
|
|
438
430
|
end
|
|
439
431
|
else
|
|
440
432
|
returnval = throw500 "No such instance id '#{req["mu_instance_id"]}' nor was this an SSL signing request"
|
|
441
|
-
ok = false
|
|
442
433
|
end
|
|
443
434
|
end
|
|
444
|
-
rescue
|
|
435
|
+
rescue StandardError => e
|
|
445
436
|
returnval = throw500 "Invalid request: #{e.inspect} (#{req})", e.backtrace
|
|
446
|
-
ok = false
|
|
447
437
|
ensure
|
|
448
438
|
if !req.nil?
|
|
449
439
|
releaseKitten(req['mu_id'])
|
data/modules/mu.rb
CHANGED
|
@@ -79,38 +79,40 @@ class Hash
|
|
|
79
79
|
}
|
|
80
80
|
return 0 if self == other # that was easy!
|
|
81
81
|
# compare elements and decide who's "bigger" based on their totals?
|
|
82
|
-
|
|
82
|
+
|
|
83
|
+
# fine, try some brute force and just hope everything implements to_s
|
|
84
|
+
self.flatten.map { |e| e.to_s }.join() <=> other.flatten.map { |e| e.to_s }.join()
|
|
83
85
|
end
|
|
84
86
|
|
|
85
|
-
# Recursively compare two hashes
|
|
86
|
-
def diff(with, on = self, level: 0, parents: [])
|
|
87
|
+
# Recursively compare two Mu Basket of Kittens hashes and report the differences
|
|
88
|
+
def diff(with, on = self, level: 0, parents: [], report: {}, habitat: nil)
|
|
87
89
|
return if with.nil? and on.nil?
|
|
88
90
|
if with.nil? or on.nil? or with.class != on.class
|
|
89
91
|
return # XXX ...however we're flagging differences
|
|
90
92
|
end
|
|
91
93
|
return if on == with
|
|
92
94
|
|
|
93
|
-
tree = ""
|
|
94
|
-
indentsize = 0
|
|
95
|
-
parents.each { |p|
|
|
96
|
-
tree += (" " * indentsize) + p + " => \n"
|
|
97
|
-
indentsize += 2
|
|
98
|
-
}
|
|
99
|
-
indent = (" " * indentsize)
|
|
100
|
-
|
|
101
95
|
changes = []
|
|
96
|
+
report ||= {}
|
|
102
97
|
if on.is_a?(Hash)
|
|
103
98
|
on_unique = (on.keys - with.keys)
|
|
104
99
|
with_unique = (with.keys - on.keys)
|
|
105
100
|
shared = (with.keys & on.keys)
|
|
106
101
|
shared.each { |k|
|
|
107
|
-
|
|
102
|
+
|
|
103
|
+
report_data = diff(with[k], on[k], level: level+1, parents: parents + [k], report: report[k], habitat: habitat)
|
|
104
|
+
if report_data and !report_data.empty?
|
|
105
|
+
report ||= {}
|
|
106
|
+
report[k] = report_data
|
|
107
|
+
end
|
|
108
108
|
}
|
|
109
109
|
on_unique.each { |k|
|
|
110
|
-
|
|
110
|
+
report[k] = { :action => :removed, :parents => parents, :value => on[k].clone }
|
|
111
|
+
report[k][:habitat] = habitat if habitat
|
|
111
112
|
}
|
|
112
113
|
with_unique.each { |k|
|
|
113
|
-
|
|
114
|
+
report[k] = { :action => :added, :parents => parents, :value => with[k].clone }
|
|
115
|
+
report[k][:habitat] = habitat if habitat
|
|
114
116
|
}
|
|
115
117
|
elsif on.is_a?(Array)
|
|
116
118
|
return if with == on
|
|
@@ -121,34 +123,28 @@ class Hash
|
|
|
121
123
|
# custom objects which we might find in here so that we can get away with
|
|
122
124
|
# sorting arrays full of weird, non-primitive types.
|
|
123
125
|
done = []
|
|
124
|
-
# before_a = on.dup
|
|
125
|
-
# after_a = on.dup.sort
|
|
126
|
-
# before_b = with.dup
|
|
127
|
-
# after_b = with.dup.sort
|
|
128
126
|
on.sort.each { |elt|
|
|
129
|
-
if elt.is_a?(Hash) and elt
|
|
127
|
+
if elt.is_a?(Hash) and !MU::MommaCat.getChunkName(elt).first.nil?
|
|
128
|
+
elt_namestr, elt_location, elt_location_list = MU::MommaCat.getChunkName(elt)
|
|
129
|
+
|
|
130
130
|
with.sort.each { |other_elt|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
other_elt_namestr, other_elt_location, other_elt_location_list = MU::MommaCat.getChunkName(other_elt)
|
|
132
|
+
|
|
133
|
+
# Case 1: The array element exists in both version of this array
|
|
134
|
+
if elt_namestr and other_elt_namestr and
|
|
135
|
+
elt_namestr == other_elt_namestr and
|
|
136
|
+
(elt_location.nil? or other_elt_location.nil? or
|
|
137
|
+
elt_location == other_elt_location or
|
|
138
|
+
!(elt_location_list & other_elt_location_list).empty?
|
|
139
139
|
)
|
|
140
|
-
break if elt == other_elt
|
|
141
140
|
done << elt
|
|
142
141
|
done << other_elt
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
elt['entity']['id']
|
|
142
|
+
break if elt == other_elt # if they're identical, we're done
|
|
143
|
+
report_data = diff(other_elt, elt, level: level+1, parents: parents + [elt_namestr], habitat: (elt_location || habitat))
|
|
144
|
+
if report_data and !report_data.empty?
|
|
145
|
+
report ||= {}
|
|
146
|
+
report[elt_namestr] = report_data
|
|
149
147
|
end
|
|
150
|
-
|
|
151
|
-
diff(other_elt, elt, level: level+1, parents: parents + [namestr])
|
|
152
148
|
break
|
|
153
149
|
end
|
|
154
150
|
}
|
|
@@ -156,43 +152,34 @@ class Hash
|
|
|
156
152
|
}
|
|
157
153
|
on_unique = (on - with) - done
|
|
158
154
|
with_unique = (with - on) - done
|
|
159
|
-
|
|
160
|
-
#
|
|
161
|
-
# MU.log "A BEFORE", MU::NOTICE, details: before_a
|
|
162
|
-
# MU.log "A AFTER", MU::NOTICE, details: after_a
|
|
163
|
-
# end
|
|
164
|
-
# if before_b != after_b
|
|
165
|
-
# MU.log "B BEFORE", MU::NOTICE, details: before_b
|
|
166
|
-
# MU.log "B AFTER", MU::NOTICE, details: after_b
|
|
167
|
-
# end
|
|
168
|
-
# end
|
|
155
|
+
|
|
156
|
+
# Case 2: This array entry exists in the old version, but not the new one
|
|
169
157
|
on_unique.each { |e|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
158
|
+
namestr, loc = MU::MommaCat.getChunkName(e)
|
|
159
|
+
|
|
160
|
+
report ||= {}
|
|
161
|
+
report[namestr] = { :action => :removed, :parents => parents, :value => e.clone }
|
|
162
|
+
report[namestr][:habitat] = loc if loc
|
|
175
163
|
}
|
|
164
|
+
|
|
165
|
+
# Case 3: This array entry exists in the new version, but not the old one
|
|
176
166
|
with_unique.each { |e|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
167
|
+
namestr, loc = MU::MommaCat.getChunkName(e)
|
|
168
|
+
|
|
169
|
+
report ||= {}
|
|
170
|
+
report[namestr] = { :action => :added, :parents => parents, :value => e.clone }
|
|
171
|
+
report[namestr][:habitat] = loc if loc
|
|
182
172
|
}
|
|
173
|
+
|
|
174
|
+
# A plain old leaf node of data
|
|
183
175
|
else
|
|
184
176
|
if on != with
|
|
185
|
-
|
|
186
|
-
|
|
177
|
+
report = { :action => :changed, :parents => parents, :oldvalue => on, :value => with.clone }
|
|
178
|
+
report[:habitat] = habitat if habitat
|
|
187
179
|
end
|
|
188
180
|
end
|
|
189
181
|
|
|
190
|
-
|
|
191
|
-
puts tree
|
|
192
|
-
changes.each { |c|
|
|
193
|
-
puts indent+c
|
|
194
|
-
}
|
|
195
|
-
end
|
|
182
|
+
report.freeze
|
|
196
183
|
end
|
|
197
184
|
|
|
198
185
|
# Implement a merge! that just updates each hash leaf as needed, not
|
|
@@ -216,8 +203,29 @@ class Hash
|
|
|
216
203
|
end
|
|
217
204
|
|
|
218
205
|
ENV['HOME'] = Etc.getpwuid(Process.uid).dir
|
|
206
|
+
module MU
|
|
207
|
+
|
|
208
|
+
# For log entries that should only be logged when we're in verbose mode
|
|
209
|
+
DEBUG = 0.freeze
|
|
210
|
+
# For ordinary log entries
|
|
211
|
+
INFO = 1.freeze
|
|
212
|
+
# For more interesting log entries which are not errors
|
|
213
|
+
NOTICE = 2.freeze
|
|
214
|
+
# Log entries for non-fatal errors
|
|
215
|
+
WARN = 3.freeze
|
|
216
|
+
# Log entries for non-fatal errors
|
|
217
|
+
WARNING = 3.freeze
|
|
218
|
+
# Log entries for fatal errors
|
|
219
|
+
ERR = 4.freeze
|
|
220
|
+
# Log entries for fatal errors
|
|
221
|
+
ERROR = 4.freeze
|
|
222
|
+
# Log entries that will be held and displayed/emailed at the end of deploy,
|
|
223
|
+
# cleanup, etc.
|
|
224
|
+
SUMMARY = 5.freeze
|
|
225
|
+
end
|
|
219
226
|
|
|
220
227
|
require 'mu/logger'
|
|
228
|
+
|
|
221
229
|
module MU
|
|
222
230
|
|
|
223
231
|
# Subclass core thread so we can gracefully handle it when we hit system
|
|
@@ -267,6 +275,7 @@ module MU
|
|
|
267
275
|
end while newguy.nil?
|
|
268
276
|
|
|
269
277
|
@@mu_global_thread_semaphore.synchronize {
|
|
278
|
+
MU.dupGlobals(Thread.current.object_id, target_thread: newguy)
|
|
270
279
|
@@mu_global_threads << newguy
|
|
271
280
|
}
|
|
272
281
|
|
|
@@ -276,8 +285,9 @@ module MU
|
|
|
276
285
|
# Wrapper class for fatal Exceptions. Gives our internals something to
|
|
277
286
|
# inherit that will log an error message appropriately before bubbling up.
|
|
278
287
|
class MuError < StandardError
|
|
279
|
-
def initialize(message = nil)
|
|
280
|
-
|
|
288
|
+
def initialize(message = nil, silent: false, details: nil)
|
|
289
|
+
details ||= caller[2]
|
|
290
|
+
MU.log message, MU::ERR, details: details if !message.nil? and !silent
|
|
281
291
|
if MU.verbosity == MU::Logger::SILENT
|
|
282
292
|
super ""
|
|
283
293
|
else
|
|
@@ -289,8 +299,8 @@ module MU
|
|
|
289
299
|
# Wrapper class for temporary Exceptions. Gives our internals something to
|
|
290
300
|
# inherit that will log a notice message appropriately before bubbling up.
|
|
291
301
|
class MuNonFatal < StandardError
|
|
292
|
-
def initialize(message = nil)
|
|
293
|
-
MU.log message, MU::NOTICE if !message.nil?
|
|
302
|
+
def initialize(message = nil, silent: false)
|
|
303
|
+
MU.log message, MU::NOTICE if !message.nil? and !silent
|
|
294
304
|
if MU.verbosity == MU::Logger::SILENT
|
|
295
305
|
super ""
|
|
296
306
|
else
|
|
@@ -299,6 +309,68 @@ module MU
|
|
|
299
309
|
end
|
|
300
310
|
end
|
|
301
311
|
|
|
312
|
+
# Boilerplate retry block executor, for making cloud API calls which might
|
|
313
|
+
# fail transiently.
|
|
314
|
+
#
|
|
315
|
+
# @param catchme [Array<Exception>]: Exception classes which should be caught and retried
|
|
316
|
+
# @param wait [Integer]: Number of seconds to wait between retries
|
|
317
|
+
# @param max [Integer]: Maximum number of retries; if less than 1, will retry indefinitely
|
|
318
|
+
# @param ignoreme [Array<Exception>]: Exception classes which can be silently treated as success. This will override any +loop_if+ block and return automatically (after invoking +always+, if the latter was specified).
|
|
319
|
+
# @param on_retry [Proc]: Optional block of code to invoke during retries
|
|
320
|
+
# @param always [Proc]: Optional block of code to invoke before returning or failing, a bit like +ensure+
|
|
321
|
+
# @param loop_if [Proc]: Optional block of code to invoke which will cause our block to be rerun until true
|
|
322
|
+
# @param loop_msg [String]: Message to display every third attempt
|
|
323
|
+
def self.retrier(catchme = nil, wait: 30, max: 0, ignoreme: [], on_retry: nil, always: nil, loop_if: nil, loop_msg: nil)
|
|
324
|
+
|
|
325
|
+
loop_if ||= Proc.new { false }
|
|
326
|
+
|
|
327
|
+
retries = 0
|
|
328
|
+
begin
|
|
329
|
+
retries += 1
|
|
330
|
+
loglevel = ((retries % 3) == 0) ? MU::NOTICE : MU::DEBUG
|
|
331
|
+
log_attempts = retries.to_s
|
|
332
|
+
log_attempts += (max > 0 ? "/"+max.to_s : "")
|
|
333
|
+
yield(retries, wait) if block_given?
|
|
334
|
+
if loop_if.call
|
|
335
|
+
MU.log loop_msg, loglevel, details: log_attempts if loop_msg
|
|
336
|
+
sleep wait
|
|
337
|
+
end
|
|
338
|
+
rescue StandardError => e
|
|
339
|
+
if catchme and catchme.include?(e.class)
|
|
340
|
+
if max > 0 and retries >= max
|
|
341
|
+
always.call if always and always.is_a?(Proc)
|
|
342
|
+
if ignoreme.include?(e.class)
|
|
343
|
+
return
|
|
344
|
+
else
|
|
345
|
+
raise e
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
if on_retry and on_retry.is_a?(Proc)
|
|
350
|
+
on_retry.call(e)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
if retries == max-1
|
|
354
|
+
MU.log e.message, MU::WARN, details: caller
|
|
355
|
+
sleep wait # wait extra on the final attempt
|
|
356
|
+
else
|
|
357
|
+
MU.log e.message, loglevel, details: log_attempts
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
sleep wait
|
|
361
|
+
retry
|
|
362
|
+
elsif ignoreme and ignoreme.include?(e.class)
|
|
363
|
+
always.call if always and always.is_a?(Proc)
|
|
364
|
+
return
|
|
365
|
+
else
|
|
366
|
+
always.call if always and always.is_a?(Proc)
|
|
367
|
+
raise e
|
|
368
|
+
end
|
|
369
|
+
end while loop_if.call and (max < 1 or retries < max)
|
|
370
|
+
|
|
371
|
+
always.call if always and always.is_a?(Proc)
|
|
372
|
+
end
|
|
373
|
+
|
|
302
374
|
if !ENV.has_key?("MU_LIBDIR") and ENV.has_key?("MU_INSTALLDIR")
|
|
303
375
|
ENV['MU_LIBDIR'] = ENV['MU_INSTALLDIR']+"/lib"
|
|
304
376
|
else
|
|
@@ -349,6 +421,13 @@ module MU
|
|
|
349
421
|
|
|
350
422
|
if Gem.paths and Gem.paths.home and File.dirname(__FILE__).match(/^#{Gem.paths.home}/)
|
|
351
423
|
@in_gem = true
|
|
424
|
+
elsif Gem.paths and Gem.paths.path and !Gem.paths.path.empty?
|
|
425
|
+
Gem.paths.path.each { |p|
|
|
426
|
+
if File.dirname(__FILE__).match(/^#{Regexp.quote(p)}/)
|
|
427
|
+
@in_gem = true
|
|
428
|
+
end
|
|
429
|
+
}
|
|
430
|
+
@in_gem = false if !defined? @in_gem
|
|
352
431
|
else
|
|
353
432
|
@in_gem = false
|
|
354
433
|
end
|
|
@@ -391,20 +470,20 @@ module MU
|
|
|
391
470
|
@@global_var_semaphore = Mutex.new
|
|
392
471
|
|
|
393
472
|
# Set one of our global per-thread variables.
|
|
394
|
-
def self.setVar(name, value)
|
|
473
|
+
def self.setVar(name, value, target_thread: Thread.current)
|
|
395
474
|
@@global_var_semaphore.synchronize {
|
|
396
|
-
@@globals[
|
|
397
|
-
@@globals[
|
|
398
|
-
@@globals[
|
|
475
|
+
@@globals[target_thread.object_id] ||= Hash.new
|
|
476
|
+
@@globals[target_thread.object_id][name] ||= Hash.new
|
|
477
|
+
@@globals[target_thread.object_id][name] = value
|
|
399
478
|
}
|
|
400
479
|
end
|
|
401
480
|
|
|
402
481
|
# Copy the set of global variables in use by another thread, typically our
|
|
403
482
|
# parent thread.
|
|
404
|
-
def self.dupGlobals(parent_thread_id)
|
|
483
|
+
def self.dupGlobals(parent_thread_id, target_thread: Thread.current)
|
|
405
484
|
@@globals[parent_thread_id] ||= {}
|
|
406
485
|
@@globals[parent_thread_id].each_pair { |name, value|
|
|
407
|
-
setVar(name, value)
|
|
486
|
+
setVar(name, value, target_thread: target_thread)
|
|
408
487
|
}
|
|
409
488
|
end
|
|
410
489
|
|
|
@@ -532,9 +611,10 @@ module MU
|
|
|
532
611
|
end
|
|
533
612
|
|
|
534
613
|
# Shortcut to invoke {MU::Logger#log}
|
|
535
|
-
def self.log(msg, level = MU::INFO, details: nil, html: false, verbosity: nil, color: true)
|
|
614
|
+
def self.log(msg, level = MU::INFO, shorthand_details = nil, details: nil, html: false, verbosity: nil, color: true)
|
|
536
615
|
return if (level == MU::DEBUG and verbosity and verbosity <= MU::Logger::LOUD)
|
|
537
616
|
return if verbosity and verbosity == MU::Logger::SILENT
|
|
617
|
+
details ||= shorthand_details
|
|
538
618
|
|
|
539
619
|
if (level == MU::ERR or
|
|
540
620
|
level == MU::WARN or
|
|
@@ -553,25 +633,6 @@ module MU
|
|
|
553
633
|
@@logger.log(msg, level, details: details, html: html, verbosity: verbosity, color: color)
|
|
554
634
|
end
|
|
555
635
|
|
|
556
|
-
# For log entries that should only be logged when we're in verbose mode
|
|
557
|
-
DEBUG = 0.freeze
|
|
558
|
-
# For ordinary log entries
|
|
559
|
-
INFO = 1.freeze
|
|
560
|
-
# For more interesting log entries which are not errors
|
|
561
|
-
NOTICE = 2.freeze
|
|
562
|
-
# Log entries for non-fatal errors
|
|
563
|
-
WARN = 3.freeze
|
|
564
|
-
# Log entries for non-fatal errors
|
|
565
|
-
WARNING = 3.freeze
|
|
566
|
-
# Log entries for fatal errors
|
|
567
|
-
ERR = 4.freeze
|
|
568
|
-
# Log entries for fatal errors
|
|
569
|
-
ERROR = 4.freeze
|
|
570
|
-
# Log entries that will be held and displayed/emailed at the end of deploy,
|
|
571
|
-
# cleanup, etc.
|
|
572
|
-
SUMMARY = 5.freeze
|
|
573
|
-
|
|
574
|
-
|
|
575
636
|
autoload :Cleanup, 'mu/cleanup'
|
|
576
637
|
autoload :Deploy, 'mu/deploy'
|
|
577
638
|
autoload :MommaCat, 'mu/mommacat'
|
|
@@ -585,7 +646,7 @@ module MU
|
|
|
585
646
|
new_cfg = $MU_CFG.dup
|
|
586
647
|
examples = {}
|
|
587
648
|
MU::Cloud.supportedClouds.each { |cloud|
|
|
588
|
-
cloudclass =
|
|
649
|
+
cloudclass = MU::Cloud.cloudClass(cloud)
|
|
589
650
|
begin
|
|
590
651
|
if cloudclass.hosted? and !$MU_CFG[cloud.downcase]
|
|
591
652
|
cfg_blob = cloudclass.hosted_config
|
|
@@ -642,7 +703,7 @@ module MU
|
|
|
642
703
|
!$MU_CFG['public_address'].empty? and @@my_public_ip != $MU_CFG['public_address']
|
|
643
704
|
@@mu_public_addr = $MU_CFG['public_address']
|
|
644
705
|
if !@@mu_public_addr.match(/^\d+\.\d+\.\d+\.\d+$/)
|
|
645
|
-
hostname = IO.readlines("/etc/hostname")[0].gsub
|
|
706
|
+
hostname = IO.readlines("/etc/hostname")[0].gsub(/\n/, '')
|
|
646
707
|
|
|
647
708
|
hostlines = File.open('/etc/hosts').grep(/.*#{hostname}.*/)
|
|
648
709
|
if hostlines and !hostlines.empty?
|
|
@@ -741,11 +802,7 @@ module MU
|
|
|
741
802
|
# @param groomer [String]: The grooming agent to load.
|
|
742
803
|
# @return [Class]: The class object implementing this groomer agent
|
|
743
804
|
def self.loadGroomer(groomer)
|
|
744
|
-
|
|
745
|
-
raise MuError, "Requested to use unsupported grooming agent #{groomer}"
|
|
746
|
-
end
|
|
747
|
-
require "mu/groomers/#{groomer.downcase}"
|
|
748
|
-
return Object.const_get("MU").const_get("Groomer").const_get(groomer)
|
|
805
|
+
MU::Groomer.loadGroomer(groomer)
|
|
749
806
|
end
|
|
750
807
|
|
|
751
808
|
@@myRegion_var = nil
|
|
@@ -899,8 +956,7 @@ module MU
|
|
|
899
956
|
|
|
900
957
|
@@myCloudDescriptor = nil
|
|
901
958
|
if MU.myCloud
|
|
902
|
-
|
|
903
|
-
found = svrclass.find(cloud_id: @@myInstanceId, region: MU.myRegion) # XXX need habitat arg for google et al
|
|
959
|
+
found = MU::Cloud.resourceClass(MU.myCloud, "Server").find(cloud_id: @@myInstanceId, region: MU.myRegion) # XXX need habitat arg for google et al
|
|
904
960
|
# found = MU::MommaCat.findStray(MU.myCloud, "server", cloud_id: @@myInstanceId, dummy_ok: true, region: MU.myRegion)
|
|
905
961
|
if !found.nil? and found.size == 1
|
|
906
962
|
@@myCloudDescriptor = found.values.first
|
|
@@ -913,8 +969,7 @@ module MU
|
|
|
913
969
|
def self.myVPCObj
|
|
914
970
|
return nil if MU.myCloud.nil?
|
|
915
971
|
return @@myVPCObj_var if @@myVPCObj_var
|
|
916
|
-
|
|
917
|
-
@@myVPCObj_var ||= cloudclass.myVPCObj
|
|
972
|
+
@@myVPCObj_var ||= MU::Cloud.cloudClass(MU.myCloud).myVPCObj
|
|
918
973
|
@@myVPCObj_var
|
|
919
974
|
end
|
|
920
975
|
|
|
@@ -1012,15 +1067,15 @@ module MU
|
|
|
1012
1067
|
|
|
1013
1068
|
# Generate a random password which will satisfy the complexity requirements of stock Amazon Windows AMIs.
|
|
1014
1069
|
# return [String]: A password string.
|
|
1015
|
-
def self.generateWindowsPassword(safe_pattern: '~!@#%^&*_-+=`|(){}[]:;<>,.?', retries:
|
|
1070
|
+
def self.generateWindowsPassword(safe_pattern: '~!@#%^&*_-+=`|(){}[]:;<>,.?', retries: 50)
|
|
1016
1071
|
# We have dopey complexity requirements, be stringent here.
|
|
1017
1072
|
# I'll be nice and not condense this into one elegant-but-unreadable regular expression
|
|
1018
1073
|
attempts = 0
|
|
1019
1074
|
safe_metachars = Regexp.escape(safe_pattern)
|
|
1020
1075
|
begin
|
|
1021
1076
|
if attempts > retries
|
|
1022
|
-
MU.log "Failed to generate an adequate Windows password after #{attempts}", MU::ERR
|
|
1023
|
-
raise MuError, "Failed to generate an adequate Windows password after #{attempts}"
|
|
1077
|
+
MU.log "Failed to generate an adequate Windows password after #{attempts} attempts", MU::ERR
|
|
1078
|
+
raise MuError, "Failed to generate an adequate Windows password after #{attempts} attempts"
|
|
1024
1079
|
end
|
|
1025
1080
|
winpass = Password.random(14..16)
|
|
1026
1081
|
attempts += 1
|
|
@@ -1039,10 +1094,9 @@ module MU
|
|
|
1039
1094
|
|
|
1040
1095
|
clouds = platform.nil? ? MU::Cloud.supportedClouds : [platform]
|
|
1041
1096
|
clouds.each { |cloud|
|
|
1042
|
-
|
|
1043
|
-
bucketname = cloudclass.adminBucketName(credentials)
|
|
1097
|
+
bucketname = MU::Cloud.cloudClass(cloud).adminBucketName(credentials)
|
|
1044
1098
|
begin
|
|
1045
|
-
if platform or (
|
|
1099
|
+
if platform or (MU::Cloud.cloudClass(cloud).hosted? and platform.nil?) or cloud == MU::Config.defaultCloud
|
|
1046
1100
|
return bucketname
|
|
1047
1101
|
end
|
|
1048
1102
|
end
|