cloud-mu 3.1.3 → 3.3.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 +21 -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 +4 -4
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +147 -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 +158 -111
- data/modules/mu/adoption.rb +404 -71
- data/modules/mu/cleanup.rb +221 -306
- data/modules/mu/cloud.rb +129 -1633
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +44 -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 +926 -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 +169 -0
- data/modules/mu/config.rb +171 -1767
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +32 -3
- data/modules/mu/config/cache_cluster.rb +2 -2
- data/modules/mu/config/cdn.rb +100 -0
- data/modules/mu/config/collection.rb +4 -4
- data/modules/mu/config/container_cluster.rb +9 -4
- data/modules/mu/config/database.rb +84 -105
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +10 -9
- data/modules/mu/config/doc_helpers.rb +516 -0
- data/modules/mu/config/endpoint.rb +5 -4
- data/modules/mu/config/firewall_rule.rb +103 -4
- data/modules/mu/config/folder.rb +4 -4
- data/modules/mu/config/function.rb +19 -10
- data/modules/mu/config/group.rb +4 -4
- data/modules/mu/config/habitat.rb +4 -4
- data/modules/mu/config/job.rb +89 -0
- 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 +10 -21
- data/modules/mu/config/ref.rb +411 -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 +98 -71
- 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 +71 -27
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +91 -68
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +3 -2
- data/modules/mu/deploy.rb +43 -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 +410 -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 +218 -2612
- data/modules/mu/mommacat/daemon.rb +403 -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 +380 -122
- data/modules/mu/{clouds → providers}/aws/alarm.rb +7 -5
- data/modules/mu/{clouds → providers}/aws/bucket.rb +297 -59
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +37 -71
- data/modules/mu/providers/aws/cdn.rb +782 -0
- data/modules/mu/{clouds → providers}/aws/collection.rb +26 -25
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +724 -744
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +88 -70
- data/modules/mu/providers/aws/endpoint.rb +1072 -0
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +220 -247
- data/modules/mu/{clouds → providers}/aws/folder.rb +8 -8
- data/modules/mu/{clouds → providers}/aws/function.rb +300 -142
- data/modules/mu/{clouds → providers}/aws/group.rb +31 -29
- data/modules/mu/{clouds → providers}/aws/habitat.rb +18 -15
- data/modules/mu/providers/aws/job.rb +466 -0
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +66 -56
- data/modules/mu/{clouds → providers}/aws/log.rb +17 -14
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +29 -19
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +114 -16
- data/modules/mu/{clouds → providers}/aws/notifier.rb +142 -65
- data/modules/mu/{clouds → providers}/aws/role.rb +158 -118
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +201 -59
- data/modules/mu/{clouds → providers}/aws/server.rb +844 -1139
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +74 -65
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +26 -44
- data/modules/mu/{clouds → providers}/aws/user.rb +24 -25
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +5 -4
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +525 -931
- 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 +97 -49
- 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 +68 -30
- data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +85 -78
- data/modules/mu/{clouds → providers}/google/database.rb +11 -21
- 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 +140 -168
- 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 +19 -21
- data/modules/mu/{clouds → providers}/google/role.rb +94 -58
- data/modules/mu/{clouds → providers}/google/server.rb +243 -156
- data/modules/mu/{clouds → providers}/google/server_pool.rb +26 -45
- 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/aws-jobs-functions.yaml +46 -0
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/centos6.yaml +15 -0
- data/modules/tests/centos7.yaml +15 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +23 -0
- data/modules/tests/eks.yaml +1 -1
- data/modules/tests/functions/node-function/lambda_function.js +10 -0
- data/modules/tests/functions/python-function/lambda_function.py +12 -0
- data/modules/tests/includes-and-params.yaml +2 -1
- data/modules/tests/microservice_app.yaml +288 -0
- 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 +2 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +3 -5
- 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 +240 -154
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1985
- data/modules/mu/clouds/aws/endpoint.rb +0 -592
|
@@ -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, details: nil)
|
|
303
|
+
MU.log message, MU::NOTICE, details: details 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
|
|
@@ -398,20 +470,20 @@ module MU
|
|
|
398
470
|
@@global_var_semaphore = Mutex.new
|
|
399
471
|
|
|
400
472
|
# Set one of our global per-thread variables.
|
|
401
|
-
def self.setVar(name, value)
|
|
473
|
+
def self.setVar(name, value, target_thread: Thread.current)
|
|
402
474
|
@@global_var_semaphore.synchronize {
|
|
403
|
-
@@globals[
|
|
404
|
-
@@globals[
|
|
405
|
-
@@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
|
|
406
478
|
}
|
|
407
479
|
end
|
|
408
480
|
|
|
409
481
|
# Copy the set of global variables in use by another thread, typically our
|
|
410
482
|
# parent thread.
|
|
411
|
-
def self.dupGlobals(parent_thread_id)
|
|
483
|
+
def self.dupGlobals(parent_thread_id, target_thread: Thread.current)
|
|
412
484
|
@@globals[parent_thread_id] ||= {}
|
|
413
485
|
@@globals[parent_thread_id].each_pair { |name, value|
|
|
414
|
-
setVar(name, value)
|
|
486
|
+
setVar(name, value, target_thread: target_thread)
|
|
415
487
|
}
|
|
416
488
|
end
|
|
417
489
|
|
|
@@ -539,9 +611,10 @@ module MU
|
|
|
539
611
|
end
|
|
540
612
|
|
|
541
613
|
# Shortcut to invoke {MU::Logger#log}
|
|
542
|
-
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)
|
|
543
615
|
return if (level == MU::DEBUG and verbosity and verbosity <= MU::Logger::LOUD)
|
|
544
616
|
return if verbosity and verbosity == MU::Logger::SILENT
|
|
617
|
+
details ||= shorthand_details
|
|
545
618
|
|
|
546
619
|
if (level == MU::ERR or
|
|
547
620
|
level == MU::WARN or
|
|
@@ -560,25 +633,6 @@ module MU
|
|
|
560
633
|
@@logger.log(msg, level, details: details, html: html, verbosity: verbosity, color: color)
|
|
561
634
|
end
|
|
562
635
|
|
|
563
|
-
# For log entries that should only be logged when we're in verbose mode
|
|
564
|
-
DEBUG = 0.freeze
|
|
565
|
-
# For ordinary log entries
|
|
566
|
-
INFO = 1.freeze
|
|
567
|
-
# For more interesting log entries which are not errors
|
|
568
|
-
NOTICE = 2.freeze
|
|
569
|
-
# Log entries for non-fatal errors
|
|
570
|
-
WARN = 3.freeze
|
|
571
|
-
# Log entries for non-fatal errors
|
|
572
|
-
WARNING = 3.freeze
|
|
573
|
-
# Log entries for fatal errors
|
|
574
|
-
ERR = 4.freeze
|
|
575
|
-
# Log entries for fatal errors
|
|
576
|
-
ERROR = 4.freeze
|
|
577
|
-
# Log entries that will be held and displayed/emailed at the end of deploy,
|
|
578
|
-
# cleanup, etc.
|
|
579
|
-
SUMMARY = 5.freeze
|
|
580
|
-
|
|
581
|
-
|
|
582
636
|
autoload :Cleanup, 'mu/cleanup'
|
|
583
637
|
autoload :Deploy, 'mu/deploy'
|
|
584
638
|
autoload :MommaCat, 'mu/mommacat'
|
|
@@ -592,7 +646,7 @@ module MU
|
|
|
592
646
|
new_cfg = $MU_CFG.dup
|
|
593
647
|
examples = {}
|
|
594
648
|
MU::Cloud.supportedClouds.each { |cloud|
|
|
595
|
-
cloudclass =
|
|
649
|
+
cloudclass = MU::Cloud.cloudClass(cloud)
|
|
596
650
|
begin
|
|
597
651
|
if cloudclass.hosted? and !$MU_CFG[cloud.downcase]
|
|
598
652
|
cfg_blob = cloudclass.hosted_config
|
|
@@ -649,7 +703,7 @@ module MU
|
|
|
649
703
|
!$MU_CFG['public_address'].empty? and @@my_public_ip != $MU_CFG['public_address']
|
|
650
704
|
@@mu_public_addr = $MU_CFG['public_address']
|
|
651
705
|
if !@@mu_public_addr.match(/^\d+\.\d+\.\d+\.\d+$/)
|
|
652
|
-
hostname = IO.readlines("/etc/hostname")[0].gsub
|
|
706
|
+
hostname = IO.readlines("/etc/hostname")[0].gsub(/\n/, '')
|
|
653
707
|
|
|
654
708
|
hostlines = File.open('/etc/hosts').grep(/.*#{hostname}.*/)
|
|
655
709
|
if hostlines and !hostlines.empty?
|
|
@@ -748,11 +802,7 @@ module MU
|
|
|
748
802
|
# @param groomer [String]: The grooming agent to load.
|
|
749
803
|
# @return [Class]: The class object implementing this groomer agent
|
|
750
804
|
def self.loadGroomer(groomer)
|
|
751
|
-
|
|
752
|
-
raise MuError, "Requested to use unsupported grooming agent #{groomer}"
|
|
753
|
-
end
|
|
754
|
-
require "mu/groomers/#{groomer.downcase}"
|
|
755
|
-
return Object.const_get("MU").const_get("Groomer").const_get(groomer)
|
|
805
|
+
MU::Groomer.loadGroomer(groomer)
|
|
756
806
|
end
|
|
757
807
|
|
|
758
808
|
@@myRegion_var = nil
|
|
@@ -906,8 +956,7 @@ module MU
|
|
|
906
956
|
|
|
907
957
|
@@myCloudDescriptor = nil
|
|
908
958
|
if MU.myCloud
|
|
909
|
-
|
|
910
|
-
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
|
|
911
960
|
# found = MU::MommaCat.findStray(MU.myCloud, "server", cloud_id: @@myInstanceId, dummy_ok: true, region: MU.myRegion)
|
|
912
961
|
if !found.nil? and found.size == 1
|
|
913
962
|
@@myCloudDescriptor = found.values.first
|
|
@@ -920,8 +969,7 @@ module MU
|
|
|
920
969
|
def self.myVPCObj
|
|
921
970
|
return nil if MU.myCloud.nil?
|
|
922
971
|
return @@myVPCObj_var if @@myVPCObj_var
|
|
923
|
-
|
|
924
|
-
@@myVPCObj_var ||= cloudclass.myVPCObj
|
|
972
|
+
@@myVPCObj_var ||= MU::Cloud.cloudClass(MU.myCloud).myVPCObj
|
|
925
973
|
@@myVPCObj_var
|
|
926
974
|
end
|
|
927
975
|
|
|
@@ -1019,15 +1067,15 @@ module MU
|
|
|
1019
1067
|
|
|
1020
1068
|
# Generate a random password which will satisfy the complexity requirements of stock Amazon Windows AMIs.
|
|
1021
1069
|
# return [String]: A password string.
|
|
1022
|
-
def self.generateWindowsPassword(safe_pattern: '~!@#%^&*_-+=`|(){}[]:;<>,.?', retries:
|
|
1070
|
+
def self.generateWindowsPassword(safe_pattern: '~!@#%^&*_-+=`|(){}[]:;<>,.?', retries: 50)
|
|
1023
1071
|
# We have dopey complexity requirements, be stringent here.
|
|
1024
1072
|
# I'll be nice and not condense this into one elegant-but-unreadable regular expression
|
|
1025
1073
|
attempts = 0
|
|
1026
1074
|
safe_metachars = Regexp.escape(safe_pattern)
|
|
1027
1075
|
begin
|
|
1028
1076
|
if attempts > retries
|
|
1029
|
-
MU.log "Failed to generate an adequate Windows password after #{attempts}", MU::ERR
|
|
1030
|
-
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"
|
|
1031
1079
|
end
|
|
1032
1080
|
winpass = Password.random(14..16)
|
|
1033
1081
|
attempts += 1
|
|
@@ -1046,10 +1094,9 @@ module MU
|
|
|
1046
1094
|
|
|
1047
1095
|
clouds = platform.nil? ? MU::Cloud.supportedClouds : [platform]
|
|
1048
1096
|
clouds.each { |cloud|
|
|
1049
|
-
|
|
1050
|
-
bucketname = cloudclass.adminBucketName(credentials)
|
|
1097
|
+
bucketname = MU::Cloud.cloudClass(cloud).adminBucketName(credentials)
|
|
1051
1098
|
begin
|
|
1052
|
-
if platform or (
|
|
1099
|
+
if platform or (MU::Cloud.cloudClass(cloud).hosted? and platform.nil?) or cloud == MU::Config.defaultCloud
|
|
1053
1100
|
return bucketname
|
|
1054
1101
|
end
|
|
1055
1102
|
end
|