cloud-mu 3.1.6 → 3.4.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 +1 -1
- data/bin/mu-adopt +15 -12
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +37 -1
- 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 -1
- data/bin/mu-run-tests +37 -12
- data/cloud-mu.gemspec +4 -4
- data/cookbooks/mu-tools/attributes/default.rb +7 -0
- data/cookbooks/mu-tools/libraries/helper.rb +87 -3
- data/cookbooks/mu-tools/recipes/apply_security.rb +39 -23
- data/cookbooks/mu-tools/recipes/aws_api.rb +13 -0
- data/cookbooks/mu-tools/recipes/google_api.rb +4 -0
- data/cookbooks/mu-tools/recipes/rsyslog.rb +8 -1
- data/cookbooks/mu-tools/resources/disk.rb +33 -12
- data/cookbooks/mu-tools/resources/mommacat_request.rb +1 -2
- data/cookbooks/mu-tools/templates/centos-8/sshd_config.erb +215 -0
- data/extras/clean-stock-amis +10 -2
- data/extras/generate-stock-images +7 -3
- data/extras/image-generators/AWS/centos7.yaml +19 -16
- data/extras/image-generators/AWS/{rhel7.yaml → rhel71.yaml} +0 -0
- data/extras/image-generators/AWS/{win2k12.yaml → win2k12r2.yaml} +0 -0
- data/modules/mommacat.ru +2 -2
- data/modules/mu.rb +84 -97
- data/modules/mu/adoption.rb +359 -59
- data/modules/mu/cleanup.rb +67 -44
- data/modules/mu/cloud.rb +108 -1754
- 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 +929 -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 +178 -0
- data/modules/mu/config.rb +122 -80
- 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 +1 -1
- data/modules/mu/config/container_cluster.rb +2 -2
- data/modules/mu/config/database.rb +84 -105
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +5 -4
- data/modules/mu/config/doc_helpers.rb +4 -5
- data/modules/mu/config/endpoint.rb +2 -1
- data/modules/mu/config/firewall_rule.rb +3 -19
- data/modules/mu/config/folder.rb +1 -1
- data/modules/mu/config/function.rb +17 -8
- data/modules/mu/config/group.rb +1 -1
- data/modules/mu/config/habitat.rb +1 -1
- data/modules/mu/config/job.rb +89 -0
- data/modules/mu/config/loadbalancer.rb +57 -11
- data/modules/mu/config/log.rb +1 -1
- data/modules/mu/config/msg_queue.rb +1 -1
- data/modules/mu/config/nosqldb.rb +1 -1
- data/modules/mu/config/notifier.rb +8 -19
- data/modules/mu/config/ref.rb +81 -9
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/schema_helpers.rb +30 -34
- data/modules/mu/config/search_domain.rb +1 -1
- data/modules/mu/config/server.rb +5 -13
- data/modules/mu/config/server_pool.rb +3 -7
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +10 -0
- data/modules/mu/config/user.rb +1 -1
- data/modules/mu/config/vpc.rb +13 -17
- data/modules/mu/defaults/AWS.yaml +106 -106
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +1 -0
- data/modules/mu/deploy.rb +33 -19
- data/modules/mu/groomer.rb +15 -0
- data/modules/mu/groomers/chef.rb +3 -0
- data/modules/mu/logger.rb +120 -144
- data/modules/mu/master.rb +22 -1
- data/modules/mu/mommacat.rb +71 -26
- data/modules/mu/mommacat/daemon.rb +23 -14
- data/modules/mu/mommacat/naming.rb +82 -3
- data/modules/mu/mommacat/search.rb +59 -16
- data/modules/mu/mommacat/storage.rb +119 -48
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +248 -62
- data/modules/mu/{clouds → providers}/aws/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +275 -41
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +14 -50
- data/modules/mu/providers/aws/cdn.rb +782 -0
- data/modules/mu/{clouds → providers}/aws/collection.rb +5 -5
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +65 -63
- data/modules/mu/providers/aws/database.rb +1747 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +26 -12
- data/modules/mu/providers/aws/endpoint.rb +1072 -0
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +39 -32
- data/modules/mu/{clouds → providers}/aws/folder.rb +1 -1
- data/modules/mu/{clouds → providers}/aws/function.rb +291 -133
- data/modules/mu/{clouds → providers}/aws/group.rb +18 -20
- data/modules/mu/{clouds → providers}/aws/habitat.rb +3 -3
- data/modules/mu/providers/aws/job.rb +469 -0
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +77 -47
- data/modules/mu/{clouds → providers}/aws/log.rb +5 -5
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +14 -11
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +96 -5
- data/modules/mu/{clouds → providers}/aws/notifier.rb +135 -63
- data/modules/mu/{clouds → providers}/aws/role.rb +112 -78
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +172 -41
- data/modules/mu/{clouds → providers}/aws/server.rb +120 -145
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +42 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +21 -38
- data/modules/mu/{clouds → providers}/aws/user.rb +12 -16
- 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 +0 -0
- data/modules/mu/{clouds → providers}/aws/vpc.rb +141 -73
- data/modules/mu/{clouds → providers}/aws/vpc_subnet.rb +0 -0
- data/modules/mu/{clouds → providers}/azure.rb +4 -1
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +1 -5
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +8 -1
- data/modules/mu/{clouds → providers}/azure/habitat.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/role.rb +0 -0
- data/modules/mu/{clouds → providers}/azure/server.rb +32 -24
- data/modules/mu/{clouds → providers}/azure/user.rb +1 -1
- 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 +4 -6
- data/modules/mu/{clouds → providers}/cloudformation.rb +1 -1
- 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 +3 -3
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +15 -6
- data/modules/mu/{clouds → providers}/google/bucket.rb +2 -2
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +29 -14
- data/modules/mu/{clouds → providers}/google/database.rb +2 -9
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/google/folder.rb +5 -9
- data/modules/mu/{clouds → providers}/google/function.rb +4 -4
- data/modules/mu/{clouds → providers}/google/group.rb +9 -17
- data/modules/mu/{clouds → providers}/google/habitat.rb +4 -8
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +2 -2
- data/modules/mu/{clouds → providers}/google/role.rb +46 -35
- data/modules/mu/{clouds → providers}/google/server.rb +26 -11
- data/modules/mu/{clouds → providers}/google/server_pool.rb +11 -11
- data/modules/mu/{clouds → providers}/google/user.rb +32 -22
- 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 +38 -3
- data/modules/tests/aws-jobs-functions.yaml +46 -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 +2 -2
- 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/microservice_app.yaml +288 -0
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +1 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +2 -2
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +126 -98
- data/modules/mu/clouds/aws/database.rb +0 -1974
- data/modules/mu/clouds/aws/endpoint.rb +0 -596
|
@@ -33,7 +33,7 @@ module MU
|
|
|
33
33
|
my_key = OpenSSL::PKey::RSA.new(@private_key)
|
|
34
34
|
|
|
35
35
|
begin
|
|
36
|
-
if my_key.private_decrypt(ciphertext).force_encoding("UTF-8") == @deploy_secret.force_encoding("UTF-8")
|
|
36
|
+
if my_key.private_decrypt(ciphertext).force_encoding("UTF-8").chomp == @deploy_secret.force_encoding("UTF-8").chomp
|
|
37
37
|
MU.log "Matched ciphertext for #{MU.deploy_id}", MU::INFO
|
|
38
38
|
return true
|
|
39
39
|
else
|
|
@@ -165,11 +165,11 @@ module MU
|
|
|
165
165
|
if e.class.name != "MU::Cloud::AWS::Server::BootstrapTempFail" and !File.exist?(deploy_dir+"/.cleanup."+cloud_id) and !File.exist?(deploy_dir+"/.cleanup")
|
|
166
166
|
MU.log "Grooming FAILED for #{kitten.mu_name} (#{e.inspect})", MU::ERR, details: e.backtrace
|
|
167
167
|
sendAdminSlack("Grooming FAILED for `#{kitten.mu_name}` with `#{e.message}` :crying_cat_face:", msg: e.backtrace.join("\n"))
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
sendAdminMail("Grooming FAILED for #{kitten.mu_name} on #{MU.appname} \"#{MU.handle}\" (#{MU.deploy_id})",
|
|
169
|
+
msg: e.inspect,
|
|
170
|
+
data: e.backtrace,
|
|
171
|
+
debug: true
|
|
172
|
+
)
|
|
173
173
|
raise e if reraise_fail
|
|
174
174
|
else
|
|
175
175
|
MU.log "Grooming of #{kitten.mu_name} interrupted by cleanup or planned reboot"
|
|
@@ -288,8 +288,8 @@ module MU
|
|
|
288
288
|
|
|
289
289
|
# Path to the PID file used by the Momma Cat daemon
|
|
290
290
|
# @return [String]
|
|
291
|
-
def self.daemonPidFile
|
|
292
|
-
base = (Process.uid == 0 and !MU.localOnly) ? "/var" : MU.dataDir
|
|
291
|
+
def self.daemonPidFile(root = false)
|
|
292
|
+
base = ((Process.uid == 0 or root) and !MU.localOnly) ? "/var" : MU.dataDir
|
|
293
293
|
"#{base}/run/mommacat.pid"
|
|
294
294
|
end
|
|
295
295
|
|
|
@@ -306,8 +306,14 @@ module MU
|
|
|
306
306
|
Dir.mkdir(dir)
|
|
307
307
|
end
|
|
308
308
|
}
|
|
309
|
-
|
|
309
|
+
if (Process.uid != 0 and
|
|
310
|
+
(!$MU_CFG['overridden_keys'] or !$MU_CFG['overridden_keys'].include?("mommacat_port")) and
|
|
311
|
+
status(true)
|
|
312
|
+
) or status
|
|
313
|
+
return 0
|
|
314
|
+
end
|
|
310
315
|
|
|
316
|
+
File.unlink(daemonPidFile) if File.exists?(daemonPidFile)
|
|
311
317
|
MU.log "Starting Momma Cat on port #{MU.mommaCatPort}, logging to #{daemonLogFile}, PID file #{daemonPidFile}"
|
|
312
318
|
origdir = Dir.getwd
|
|
313
319
|
Dir.chdir(MU.myRoot+"/modules")
|
|
@@ -342,22 +348,25 @@ module MU
|
|
|
342
348
|
return $?.exitstatus
|
|
343
349
|
end
|
|
344
350
|
|
|
351
|
+
@@notified_on_pid = {}
|
|
352
|
+
|
|
345
353
|
# Return true if the Momma Cat daemon appears to be running
|
|
346
354
|
# @return [Boolean]
|
|
347
|
-
def self.status
|
|
355
|
+
def self.status(root = false)
|
|
348
356
|
if MU.inGem? and MU.muCfg['disable_mommacat']
|
|
349
357
|
return true
|
|
350
358
|
end
|
|
351
|
-
if File.exist?(daemonPidFile)
|
|
352
|
-
pid = File.read(daemonPidFile).chomp.to_i
|
|
359
|
+
if File.exist?(daemonPidFile(root))
|
|
360
|
+
pid = File.read(daemonPidFile(root)).chomp.to_i
|
|
353
361
|
begin
|
|
354
362
|
Process.getpgid(pid)
|
|
355
|
-
MU.log "Momma Cat running with pid #{pid.to_s}"
|
|
363
|
+
MU.log "Momma Cat running with pid #{pid.to_s}", (@@notified_on_pid[pid] ? MU::DEBUG : MU::INFO) # shush
|
|
364
|
+
@@notified_on_pid[pid] = true
|
|
356
365
|
return true
|
|
357
366
|
rescue Errno::ESRCH
|
|
358
367
|
end
|
|
359
368
|
end
|
|
360
|
-
MU.log "Momma Cat daemon not running", MU::NOTICE, details: daemonPidFile
|
|
369
|
+
MU.log "Momma Cat daemon not running", MU::NOTICE, details: daemonPidFile(root)
|
|
361
370
|
false
|
|
362
371
|
end
|
|
363
372
|
|
|
@@ -19,6 +19,16 @@ module MU
|
|
|
19
19
|
# the normal synchronous deploy sequence invoked by *mu-deploy*.
|
|
20
20
|
class MommaCat
|
|
21
21
|
|
|
22
|
+
# Lookup table to translate the word "habitat" back to its
|
|
23
|
+
# provider-specific jargon
|
|
24
|
+
HABITAT_SYNONYMS = {
|
|
25
|
+
"AWS" => "account",
|
|
26
|
+
"CloudFormation" => "account",
|
|
27
|
+
"Google" => "project",
|
|
28
|
+
"Azure" => "subscription",
|
|
29
|
+
"VMWare" => "sddc"
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
# Given a cloud provider's native descriptor for a resource, make some
|
|
23
33
|
# reasonable guesses about what the thing's name should be.
|
|
24
34
|
def self.guessName(desc, resourceclass, cloud_id: nil, tag_value: nil)
|
|
@@ -47,6 +57,74 @@ module MU
|
|
|
47
57
|
|
|
48
58
|
end
|
|
49
59
|
|
|
60
|
+
# Given a piece of a BoK resource descriptor Hash, come up with shorthand
|
|
61
|
+
# strings to give it a name for human readers. If nothing reasonable can be
|
|
62
|
+
# extracted, returns nil.
|
|
63
|
+
# @param obj [Hash]
|
|
64
|
+
# @param array_of [String]
|
|
65
|
+
# @param habitat_translate [String]
|
|
66
|
+
# @return [Array<String,nil>]
|
|
67
|
+
def self.getChunkName(obj, array_of = nil, habitat_translate: nil)
|
|
68
|
+
return [nil, nil] if obj.nil?
|
|
69
|
+
if [String, Integer, Boolean].include?(obj.class)
|
|
70
|
+
return [obj, nil]
|
|
71
|
+
end
|
|
72
|
+
obj_type = array_of || obj['type']
|
|
73
|
+
obj_name = obj['name'] || obj['id'] || obj['mu_name'] || obj['cloud_id']
|
|
74
|
+
|
|
75
|
+
name_string = if obj_name
|
|
76
|
+
if obj_type
|
|
77
|
+
"#{obj_type}[#{obj_name}]"
|
|
78
|
+
else
|
|
79
|
+
obj_name.dup
|
|
80
|
+
end
|
|
81
|
+
else
|
|
82
|
+
found_it = nil
|
|
83
|
+
using = nil
|
|
84
|
+
["entity", "role"].each { |subtype|
|
|
85
|
+
if obj[subtype] and obj[subtype].is_a?(Hash)
|
|
86
|
+
found_it = if obj[subtype]["id"]
|
|
87
|
+
obj[subtype]['id'].dup
|
|
88
|
+
elsif obj[subtype]["type"] and obj[subtype]["name"]
|
|
89
|
+
"#{obj[subtype]['type']}[#{obj[subtype]['name']}]"
|
|
90
|
+
end
|
|
91
|
+
break
|
|
92
|
+
end
|
|
93
|
+
}
|
|
94
|
+
found_it
|
|
95
|
+
end
|
|
96
|
+
if name_string
|
|
97
|
+
name_string.gsub!(/\[.+?\](\[.+?\]$)/, '\1')
|
|
98
|
+
if habitat_translate and HABITAT_SYNONYMS[habitat_translate]
|
|
99
|
+
name_string.sub!(/^habitats?\[(.+?)\]/i, HABITAT_SYNONYMS[habitat_translate]+'[\1]')
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
location_list = []
|
|
104
|
+
|
|
105
|
+
location = if obj['project']
|
|
106
|
+
obj['project']
|
|
107
|
+
elsif obj['habitat'] and (obj['habitat']['id'] or obj['habitat']['name'])
|
|
108
|
+
obj['habitat']['name'] || obj['habitat']['id']
|
|
109
|
+
else
|
|
110
|
+
hab_str = nil
|
|
111
|
+
['projects', 'habitats'].each { |key|
|
|
112
|
+
|
|
113
|
+
if obj[key] and obj[key].is_a?(Array)
|
|
114
|
+
location_list = obj[key].sort.map { |p|
|
|
115
|
+
(p["name"] || p["id"]).gsub(/^.*?[^\/]+\/([^\/]+)$/, '\1')
|
|
116
|
+
}
|
|
117
|
+
hab_str = location_list.join(", ")
|
|
118
|
+
name_string.gsub!(/^.*?[^\/]+\/([^\/]+)$/, '\1') if name_string
|
|
119
|
+
break
|
|
120
|
+
end
|
|
121
|
+
}
|
|
122
|
+
hab_str
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
[name_string, location, location_list]
|
|
126
|
+
end
|
|
127
|
+
|
|
50
128
|
# Generate a three-character string which can be used to unique-ify the
|
|
51
129
|
# names of resources which might potentially collide, e.g. Windows local
|
|
52
130
|
# hostnames, Amazon Elastic Load Balancers, or server pool instances.
|
|
@@ -218,17 +296,18 @@ module MU
|
|
|
218
296
|
# SSH config entries, etc.
|
|
219
297
|
# @param server [MU::Cloud::Server]: The {MU::Cloud::Server} we'll be setting up.
|
|
220
298
|
# @param sync_wait [Boolean]: Whether to wait for DNS to fully synchronize before returning.
|
|
221
|
-
def self.nameKitten(server, sync_wait: false)
|
|
299
|
+
def self.nameKitten(server, sync_wait: false, no_dns: false)
|
|
222
300
|
node, config, _deploydata = server.describe
|
|
223
301
|
|
|
224
302
|
mu_zone = nil
|
|
225
303
|
# XXX GCP!
|
|
226
|
-
if MU::Cloud::AWS.hosted? and !MU::Cloud::AWS.isGovCloud?
|
|
304
|
+
if !no_dns and MU::Cloud::AWS.hosted? and !MU::Cloud::AWS.isGovCloud?
|
|
227
305
|
zones = MU::Cloud::DNSZone.find(cloud_id: "platform-mu")
|
|
228
306
|
mu_zone = zones.values.first if !zones.nil?
|
|
229
307
|
end
|
|
308
|
+
|
|
230
309
|
if !mu_zone.nil?
|
|
231
|
-
MU::Cloud::DNSZone.genericMuDNSEntry(name: node, target: server.canonicalIP, cloudclass: MU::Cloud::Server, sync_wait: sync_wait)
|
|
310
|
+
MU::Cloud::DNSZone.genericMuDNSEntry(name: node.gsub(/[^a-z0-9!"\#$%&'\(\)\*\+,\-\/:;<=>\?@\[\]\^_`{\|}~\.]/, '-').gsub(/--|^-/, ''), target: server.canonicalIP, cloudclass: MU::Cloud::Server, sync_wait: sync_wait)
|
|
232
311
|
else
|
|
233
312
|
MU::Master.addInstanceToEtcHosts(server.canonicalIP, node)
|
|
234
313
|
end
|
|
@@ -60,7 +60,7 @@ module MU
|
|
|
60
60
|
)
|
|
61
61
|
_shortclass, _cfg_name, type, _classname, _attrs = MU::Cloud.getResourceNames(type, true)
|
|
62
62
|
|
|
63
|
-
cloudclass = MU::Cloud.
|
|
63
|
+
cloudclass = MU::Cloud.cloudClass(cloud)
|
|
64
64
|
return nil if cloudclass.virtual?
|
|
65
65
|
|
|
66
66
|
if (tag_key and !tag_value) or (!tag_key and tag_value)
|
|
@@ -107,7 +107,17 @@ module MU
|
|
|
107
107
|
matches = []
|
|
108
108
|
|
|
109
109
|
credlist.each { |creds|
|
|
110
|
-
|
|
110
|
+
cur_habitats = []
|
|
111
|
+
|
|
112
|
+
if habitats and !habitats.empty? and habitats != [nil]
|
|
113
|
+
valid_habitats = cloudclass.listHabitats(creds)
|
|
114
|
+
cur_habitats = (habitats & valid_habitats)
|
|
115
|
+
next if cur_habitats.empty?
|
|
116
|
+
else
|
|
117
|
+
cur_habitats = cloudclass.listHabitats(creds)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
cloud_descs = search_cloud_provider(type, cloud, cur_habitats, region, cloud_id: cloud_id, tag_key: tag_key, tag_value: tag_value, credentials: creds, flags: flags)
|
|
111
121
|
|
|
112
122
|
cloud_descs.each_pair.each { |p, regions|
|
|
113
123
|
regions.each_pair.each { |r, results|
|
|
@@ -127,6 +137,8 @@ module MU
|
|
|
127
137
|
matches
|
|
128
138
|
end
|
|
129
139
|
|
|
140
|
+
@object_load_fails = false
|
|
141
|
+
|
|
130
142
|
# Return the resource object of another member of this deployment
|
|
131
143
|
# @param type [String,Symbol]: The type of resource
|
|
132
144
|
# @param name [String]: The name of the resource as defined in its 'name' Basket of Kittens field
|
|
@@ -135,7 +147,7 @@ module MU
|
|
|
135
147
|
# @param created_only [Boolean]: Only return the littermate if its cloud_id method returns a value
|
|
136
148
|
# @param return_all [Boolean]: Return a Hash of matching objects indexed by their mu_name, instead of a single match. Only valid for resource types where has_multiples is true.
|
|
137
149
|
# @return [MU::Cloud]
|
|
138
|
-
def findLitterMate(type: nil, name: nil, mu_name: nil, cloud_id: nil, created_only: false, return_all: false, credentials: nil, habitat: nil, **flags)
|
|
150
|
+
def findLitterMate(type: nil, name: nil, mu_name: nil, cloud_id: nil, created_only: false, return_all: false, credentials: nil, habitat: nil, ignore_missing: false, debug: false, **flags)
|
|
139
151
|
_shortclass, _cfg_name, type, _classname, attrs = MU::Cloud.getResourceNames(type)
|
|
140
152
|
|
|
141
153
|
# If we specified a habitat, which we may also have done by its shorthand
|
|
@@ -159,17 +171,35 @@ module MU
|
|
|
159
171
|
}
|
|
160
172
|
|
|
161
173
|
@kitten_semaphore.synchronize {
|
|
162
|
-
return nil if !@kittens.has_key?(type)
|
|
163
|
-
matches = []
|
|
164
174
|
|
|
175
|
+
if !@kittens.has_key?(type)
|
|
176
|
+
return nil if !@original_config or @original_config[type].nil? or @original_config[type].empty?
|
|
177
|
+
begin
|
|
178
|
+
loadObjects(false)
|
|
179
|
+
rescue ThreadError => e
|
|
180
|
+
if e.message !~ /deadlock/
|
|
181
|
+
raise e
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
if @object_load_fails or !@kittens[type]
|
|
185
|
+
if !ignore_missing
|
|
186
|
+
MU.log "#{@deploy_id}'s original config has #{@original_config[type].size == 1 ? "a" : @original_config[type].size.to_s} #{type}, but loadObjects could not populate anything from deployment metadata", MU::ERR if !@object_load_fails
|
|
187
|
+
@object_load_fails = true
|
|
188
|
+
end
|
|
189
|
+
return nil
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
matches = {}
|
|
165
193
|
@kittens[type].each { |habitat_group, sib_classes|
|
|
166
194
|
next if habitat and habitat_group and habitat_group != habitat
|
|
167
195
|
sib_classes.each_pair { |sib_class, cloud_objs|
|
|
196
|
+
|
|
168
197
|
if attrs[:has_multiples]
|
|
169
198
|
next if !name.nil? and name != sib_class or cloud_objs.empty?
|
|
170
199
|
if !name.nil?
|
|
171
200
|
if return_all
|
|
172
|
-
|
|
201
|
+
matches.merge!(cloud_objs.clone)
|
|
202
|
+
next
|
|
173
203
|
elsif cloud_objs.size == 1 and does_match.call(cloud_objs.values.first)
|
|
174
204
|
return cloud_objs.values.first
|
|
175
205
|
end
|
|
@@ -177,19 +207,24 @@ module MU
|
|
|
177
207
|
|
|
178
208
|
cloud_objs.each_value { |obj|
|
|
179
209
|
if does_match.call(obj)
|
|
180
|
-
|
|
210
|
+
if return_all
|
|
211
|
+
matches.merge!(cloud_objs.clone)
|
|
212
|
+
else
|
|
213
|
+
return obj.clone
|
|
214
|
+
end
|
|
181
215
|
end
|
|
182
216
|
}
|
|
183
|
-
# has_multiples is false
|
|
217
|
+
# has_multiples is false, "cloud_objs" is actually a singular object
|
|
184
218
|
elsif (name.nil? and does_match.call(cloud_objs)) or [sib_class, cloud_objs.virtual_name(name)].include?(name.to_s)
|
|
185
|
-
matches
|
|
219
|
+
matches[cloud_objs.config['name']] = cloud_objs.clone
|
|
186
220
|
end
|
|
187
221
|
}
|
|
188
222
|
}
|
|
189
223
|
|
|
190
|
-
return matches
|
|
224
|
+
return matches if return_all and matches.size >= 1
|
|
225
|
+
|
|
226
|
+
return matches.values.first if matches.size == 1
|
|
191
227
|
|
|
192
|
-
return matches if return_all and matches.size > 1
|
|
193
228
|
}
|
|
194
229
|
|
|
195
230
|
return nil
|
|
@@ -213,7 +248,7 @@ module MU
|
|
|
213
248
|
end
|
|
214
249
|
|
|
215
250
|
def self.generate_dummy_object(type, cloud, name, mu_name, cloud_id, desc, region, habitat, tag_value, calling_deploy, credentials)
|
|
216
|
-
resourceclass = MU::Cloud.
|
|
251
|
+
resourceclass = MU::Cloud.resourceClass(cloud, type)
|
|
217
252
|
|
|
218
253
|
use_name = if (name.nil? or name.empty?)
|
|
219
254
|
if !mu_name.nil?
|
|
@@ -269,15 +304,23 @@ module MU
|
|
|
269
304
|
private_class_method :generate_dummy_object
|
|
270
305
|
|
|
271
306
|
def self.search_cloud_provider(type, cloud, habitats, region, cloud_id: nil, tag_key: nil, tag_value: nil, credentials: nil, flags: nil)
|
|
272
|
-
cloudclass = MU::Cloud.
|
|
273
|
-
resourceclass = MU::Cloud.
|
|
307
|
+
cloudclass = MU::Cloud.cloudClass(cloud)
|
|
308
|
+
resourceclass = MU::Cloud.resourceClass(cloud, type)
|
|
274
309
|
|
|
275
310
|
# Decide what regions we'll search, if applicable for this resource
|
|
276
311
|
# type.
|
|
277
312
|
regions = if resourceclass.isGlobal?
|
|
278
313
|
[nil]
|
|
279
314
|
else
|
|
280
|
-
|
|
315
|
+
if region
|
|
316
|
+
if region.is_a?(Array) and !region.empty?
|
|
317
|
+
region
|
|
318
|
+
else
|
|
319
|
+
[region]
|
|
320
|
+
end
|
|
321
|
+
else
|
|
322
|
+
cloudclass.listRegions(credentials: credentials)
|
|
323
|
+
end
|
|
281
324
|
end
|
|
282
325
|
|
|
283
326
|
# Decide what habitats (accounts/projects/subscriptions) we'll
|
|
@@ -288,7 +331,7 @@ module MU
|
|
|
288
331
|
habitats << nil
|
|
289
332
|
end
|
|
290
333
|
if resourceclass.canLiveIn.include?(:Habitat)
|
|
291
|
-
habitats.concat(cloudclass.listHabitats(credentials))
|
|
334
|
+
habitats.concat(cloudclass.listHabitats(credentials, use_cache: false))
|
|
292
335
|
end
|
|
293
336
|
end
|
|
294
337
|
habitats << nil if habitats.empty?
|
|
@@ -88,16 +88,28 @@ module MU
|
|
|
88
88
|
}
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
+
|
|
91
92
|
# Overwrite this deployment's configuration with a new version. Save the
|
|
92
93
|
# previous version as well.
|
|
93
94
|
# @param new_conf [Hash]: A new configuration, fully resolved by {MU::Config}
|
|
94
|
-
def updateBasketofKittens(new_conf)
|
|
95
|
+
def updateBasketofKittens(new_conf, skip_validation: false, new_metadata: nil, save_now: false)
|
|
95
96
|
loadDeploy
|
|
96
97
|
if new_conf == @original_config
|
|
97
|
-
MU.log "#{@deploy_id}", MU::WARN
|
|
98
98
|
return
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
scrub_with = nil
|
|
102
|
+
|
|
103
|
+
# Make sure the new config that we were just handed resolves and makes
|
|
104
|
+
# sense
|
|
105
|
+
if !skip_validation
|
|
106
|
+
f = Tempfile.new(@deploy_id)
|
|
107
|
+
f.write JSON.parse(JSON.generate(new_conf)).to_yaml
|
|
108
|
+
conf_engine = MU::Config.new(f.path) # will throw an exception if it's bad, adoption should catch this and cope reasonably
|
|
109
|
+
scrub_with = conf_engine.config
|
|
110
|
+
f.close
|
|
111
|
+
end
|
|
112
|
+
|
|
101
113
|
backup = "#{deploy_dir}/basket_of_kittens.json.#{Time.now.to_i.to_s}"
|
|
102
114
|
MU.log "Saving previous config of #{@deploy_id} to #{backup}"
|
|
103
115
|
config = File.new(backup, File::CREAT|File::TRUNC|File::RDWR, 0600)
|
|
@@ -106,9 +118,27 @@ module MU
|
|
|
106
118
|
config.flock(File::LOCK_UN)
|
|
107
119
|
config.close
|
|
108
120
|
|
|
109
|
-
@original_config = new_conf
|
|
110
|
-
|
|
111
|
-
MU.
|
|
121
|
+
@original_config = new_conf.clone
|
|
122
|
+
|
|
123
|
+
MU::Cloud.resource_types.each_pair { |res_type, attrs|
|
|
124
|
+
next if !@deployment.has_key?(attrs[:cfg_plural])
|
|
125
|
+
deletia = []
|
|
126
|
+
# existing_deploys
|
|
127
|
+
@deployment[attrs[:cfg_plural]].each_pair { |res_name, data|
|
|
128
|
+
orig_cfg = findResourceConfig(attrs[:cfg_plural], res_name, (scrub_with || @original_config))
|
|
129
|
+
|
|
130
|
+
if orig_cfg.nil? and (!data['mu_name'] or data['mu_name'] =~ /^#{Regexp.quote(@deploy_id)}/)
|
|
131
|
+
MU.log "#{res_type} #{res_name} no longer configured, will remove deployment metadata", MU::NOTICE, details: data
|
|
132
|
+
deletia << res_name
|
|
133
|
+
end
|
|
134
|
+
}
|
|
135
|
+
@deployment[attrs[:cfg_plural]].reject! { |k, v| deletia.include?(k) }
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if save_now
|
|
139
|
+
save!
|
|
140
|
+
MU.log "New config saved to #{deploy_dir}/basket_of_kittens.json"
|
|
141
|
+
end
|
|
112
142
|
end
|
|
113
143
|
|
|
114
144
|
@lock_semaphore = Mutex.new
|
|
@@ -147,11 +177,11 @@ module MU
|
|
|
147
177
|
# @param id [String]: The lock identifier to release.
|
|
148
178
|
# @param nonblock [Boolean]: Whether to block while waiting for the lock. In non-blocking mode, we simply return false if the lock is not available.
|
|
149
179
|
# return [false, nil]
|
|
150
|
-
def self.lock(id, nonblock = false, global = false)
|
|
180
|
+
def self.lock(id, nonblock = false, global = false, retries: 0, deploy_id: MU.deploy_id)
|
|
151
181
|
raise MuError, "Can't pass a nil id to MU::MommaCat.lock" if id.nil?
|
|
152
182
|
|
|
153
183
|
if !global
|
|
154
|
-
lockdir = "#{deploy_dir(
|
|
184
|
+
lockdir = "#{deploy_dir(deploy_id)}/locks"
|
|
155
185
|
else
|
|
156
186
|
lockdir = File.expand_path(MU.dataDir+"/locks")
|
|
157
187
|
end
|
|
@@ -160,6 +190,7 @@ module MU
|
|
|
160
190
|
MU.log "Creating #{lockdir}", MU::DEBUG
|
|
161
191
|
Dir.mkdir(lockdir, 0700)
|
|
162
192
|
end
|
|
193
|
+
nonblock = true if retries > 0
|
|
163
194
|
|
|
164
195
|
@lock_semaphore.synchronize {
|
|
165
196
|
if @locks[Thread.current.object_id].nil?
|
|
@@ -168,11 +199,38 @@ module MU
|
|
|
168
199
|
|
|
169
200
|
@locks[Thread.current.object_id][id] = File.open("#{lockdir}/#{id}.lock", File::CREAT|File::RDWR, 0600)
|
|
170
201
|
}
|
|
171
|
-
|
|
202
|
+
|
|
203
|
+
MU.log "Getting a lock on #{lockdir}/#{id}.lock (thread #{Thread.current.object_id})...", MU::DEBUG, details: caller
|
|
204
|
+
show_relevant = Proc.new {
|
|
205
|
+
@lock_semaphore.synchronize {
|
|
206
|
+
@locks.each_pair { |thread_id, lock|
|
|
207
|
+
lock.each_pair { |lockid, lockpath|
|
|
208
|
+
if lockid == id
|
|
209
|
+
thread = Thread.list.select { |t| t.object_id == thread_id }.first
|
|
210
|
+
if thread.object_id != Thread.current.object_id
|
|
211
|
+
MU.log "#{thread_id} sitting on #{id}", MU::WARN, thread.backtrace
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
172
218
|
begin
|
|
173
219
|
if nonblock
|
|
174
220
|
if !@locks[Thread.current.object_id][id].flock(File::LOCK_EX|File::LOCK_NB)
|
|
175
|
-
|
|
221
|
+
if retries > 0
|
|
222
|
+
success = false
|
|
223
|
+
MU.retrier([], loop_if: Proc.new { !success }, loop_msg: "Waiting for lock on #{lockdir}/#{id}.lock...", max: retries) { |cur_retries, _wait|
|
|
224
|
+
success = @locks[Thread.current.object_id][id].flock(File::LOCK_EX|File::LOCK_NB)
|
|
225
|
+
if !success and cur_retries > 0 and (cur_retries % 3) == 0
|
|
226
|
+
show_relevant.call(cur_retries)
|
|
227
|
+
end
|
|
228
|
+
}
|
|
229
|
+
show_relevant.call(cur_retries) if !success
|
|
230
|
+
return success
|
|
231
|
+
else
|
|
232
|
+
return false
|
|
233
|
+
end
|
|
176
234
|
end
|
|
177
235
|
else
|
|
178
236
|
@locks[Thread.current.object_id][id].flock(File::LOCK_EX)
|
|
@@ -186,11 +244,11 @@ module MU
|
|
|
186
244
|
|
|
187
245
|
# Release a flock() lock.
|
|
188
246
|
# @param id [String]: The lock identifier to release.
|
|
189
|
-
def self.unlock(id, global = false)
|
|
247
|
+
def self.unlock(id, global = false, deploy_id: MU.deploy_id)
|
|
190
248
|
raise MuError, "Can't pass a nil id to MU::MommaCat.unlock" if id.nil?
|
|
191
249
|
lockdir = nil
|
|
192
250
|
if !global
|
|
193
|
-
lockdir = "#{deploy_dir(
|
|
251
|
+
lockdir = "#{deploy_dir(deploy_id)}/locks"
|
|
194
252
|
else
|
|
195
253
|
lockdir = File.expand_path(MU.dataDir+"/locks")
|
|
196
254
|
end
|
|
@@ -361,6 +419,7 @@ module MU
|
|
|
361
419
|
deploy.flock(File::LOCK_UN)
|
|
362
420
|
deploy.close
|
|
363
421
|
@need_deploy_flush = false
|
|
422
|
+
@last_modified = nil
|
|
364
423
|
MU::MommaCat.updateLitter(@deploy_id, self)
|
|
365
424
|
end
|
|
366
425
|
|
|
@@ -512,48 +571,30 @@ module MU
|
|
|
512
571
|
if !@original_config['scrub_mu_isms'] and !@no_artifacts
|
|
513
572
|
credsets.each_pair { |cloud, creds|
|
|
514
573
|
creds.uniq!
|
|
515
|
-
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
|
|
516
574
|
creds.each { |credentials|
|
|
517
|
-
|
|
575
|
+
MU::Cloud.cloudClass(cloud).writeDeploySecret(@deploy_id, @deploy_secret, credentials: credentials)
|
|
518
576
|
}
|
|
519
577
|
}
|
|
520
578
|
end
|
|
521
579
|
end
|
|
522
580
|
|
|
523
581
|
def loadObjects(delay_descriptor_load)
|
|
582
|
+
# Load up MU::Cloud objects for all our kittens in this deploy
|
|
583
|
+
|
|
524
584
|
MU::Cloud.resource_types.each_pair { |res_type, attrs|
|
|
525
585
|
type = attrs[:cfg_plural]
|
|
526
586
|
next if !@deployment.has_key?(type)
|
|
527
587
|
|
|
588
|
+
deletia = {}
|
|
528
589
|
@deployment[type].each_pair { |res_name, data|
|
|
529
|
-
orig_cfg =
|
|
530
|
-
if @original_config.has_key?(type)
|
|
531
|
-
@original_config[type].each { |resource|
|
|
532
|
-
if resource["name"] == res_name
|
|
533
|
-
orig_cfg = resource
|
|
534
|
-
break
|
|
535
|
-
end
|
|
536
|
-
}
|
|
537
|
-
end
|
|
538
|
-
|
|
539
|
-
# Some Server objects originated from ServerPools, get their
|
|
540
|
-
# configs from there
|
|
541
|
-
if type == "servers" and orig_cfg.nil? and
|
|
542
|
-
@original_config.has_key?("server_pools")
|
|
543
|
-
@original_config["server_pools"].each { |resource|
|
|
544
|
-
if resource["name"] == res_name
|
|
545
|
-
orig_cfg = resource
|
|
546
|
-
break
|
|
547
|
-
end
|
|
548
|
-
}
|
|
549
|
-
end
|
|
590
|
+
orig_cfg = findResourceConfig(type, res_name)
|
|
550
591
|
|
|
551
592
|
if orig_cfg.nil?
|
|
552
593
|
MU.log "Failed to locate original config for #{attrs[:cfg_name]} #{res_name} in #{@deploy_id}", MU::WARN if !["firewall_rules", "databases", "storage_pools", "cache_clusters", "alarms"].include?(type) # XXX shaddap
|
|
553
594
|
next
|
|
554
595
|
end
|
|
555
596
|
|
|
556
|
-
if orig_cfg['vpc']
|
|
597
|
+
if orig_cfg['vpc']
|
|
557
598
|
ref = if orig_cfg['vpc']['id'] and orig_cfg['vpc']['id'].is_a?(Hash)
|
|
558
599
|
orig_cfg['vpc']['id']['mommacat'] = self
|
|
559
600
|
MU::Config::Ref.get(orig_cfg['vpc']['id'])
|
|
@@ -566,18 +607,12 @@ module MU
|
|
|
566
607
|
end
|
|
567
608
|
|
|
568
609
|
begin
|
|
569
|
-
# Load up MU::Cloud objects for all our kittens in this deploy
|
|
570
|
-
orig_cfg['environment'] = @environment # not always set in old deploys
|
|
571
610
|
if attrs[:has_multiples]
|
|
572
611
|
data.keys.each { |mu_name|
|
|
573
|
-
attrs[:interface].new(mommacat: self, kitten_cfg: orig_cfg, mu_name: mu_name, delay_descriptor_load: delay_descriptor_load)
|
|
612
|
+
addKitten(type, res_name, attrs[:interface].new(mommacat: self, kitten_cfg: orig_cfg, mu_name: mu_name, delay_descriptor_load: delay_descriptor_load))
|
|
574
613
|
}
|
|
575
614
|
else
|
|
576
|
-
|
|
577
|
-
if data['mu_name'].nil?
|
|
578
|
-
raise MuError, "Unable to find or guess a Mu name for #{res_type}: #{res_name} in #{@deploy_id}"
|
|
579
|
-
end
|
|
580
|
-
attrs[:interface].new(mommacat: self, kitten_cfg: orig_cfg, mu_name: data['mu_name'], cloud_id: data['cloud_id'])
|
|
615
|
+
addKitten(type, res_name, attrs[:interface].new(mommacat: self, kitten_cfg: orig_cfg, mu_name: data['mu_name'], cloud_id: data['cloud_id']))
|
|
581
616
|
end
|
|
582
617
|
rescue StandardError => e
|
|
583
618
|
if e.class != MU::Cloud::MuCloudResourceNotImplemented
|
|
@@ -585,6 +620,7 @@ module MU
|
|
|
585
620
|
end
|
|
586
621
|
end
|
|
587
622
|
}
|
|
623
|
+
|
|
588
624
|
}
|
|
589
625
|
end
|
|
590
626
|
|
|
@@ -612,6 +648,14 @@ module MU
|
|
|
612
648
|
def loadDeployFromCache(set_context_to_me = true)
|
|
613
649
|
return false if !File.size?(deploy_dir+"/deployment.json")
|
|
614
650
|
|
|
651
|
+
lastmod = File.mtime("#{deploy_dir}/deployment.json")
|
|
652
|
+
if @last_modified and lastmod < @last_modified
|
|
653
|
+
MU.log "#{deploy_dir}/deployment.json last written at #{lastmod}, live meta at #{@last_modified}, not loading", MU::WARN if @last_modified
|
|
654
|
+
# this is a weird place for this
|
|
655
|
+
setThreadContextToMe if set_context_to_me
|
|
656
|
+
return true
|
|
657
|
+
end
|
|
658
|
+
|
|
615
659
|
deploy = File.open("#{deploy_dir}/deployment.json", File::RDONLY)
|
|
616
660
|
MU.log "Getting lock to read #{deploy_dir}/deployment.json", MU::DEBUG
|
|
617
661
|
# deploy.flock(File::LOCK_EX)
|
|
@@ -623,6 +667,7 @@ module MU
|
|
|
623
667
|
|
|
624
668
|
begin
|
|
625
669
|
@deployment = JSON.parse(File.read("#{deploy_dir}/deployment.json"))
|
|
670
|
+
# XXX is it worthwhile to merge fuckery?
|
|
626
671
|
rescue JSON::ParserError => e
|
|
627
672
|
MU.log "JSON parse failed on #{deploy_dir}/deployment.json", MU::ERR, details: e.message
|
|
628
673
|
end
|
|
@@ -632,20 +677,21 @@ module MU
|
|
|
632
677
|
|
|
633
678
|
setThreadContextToMe if set_context_to_me
|
|
634
679
|
|
|
635
|
-
@timestamp = @deployment['timestamp']
|
|
636
|
-
@seed = @deployment['seed']
|
|
637
|
-
@appname = @deployment['appname']
|
|
638
|
-
@handle = @deployment['handle']
|
|
639
|
-
|
|
640
680
|
true
|
|
641
681
|
end
|
|
642
682
|
|
|
683
|
+
|
|
643
684
|
###########################################################################
|
|
644
685
|
###########################################################################
|
|
645
686
|
def loadDeploy(deployment_json_only = false, set_context_to_me: true)
|
|
646
687
|
MU::MommaCat.deploy_struct_semaphore.synchronize {
|
|
647
688
|
success = loadDeployFromCache(set_context_to_me)
|
|
648
689
|
|
|
690
|
+
@timestamp ||= @deployment['timestamp']
|
|
691
|
+
@seed ||= @deployment['seed']
|
|
692
|
+
@appname ||= @deployment['appname']
|
|
693
|
+
@handle ||= @deployment['handle']
|
|
694
|
+
|
|
649
695
|
return if deployment_json_only and success
|
|
650
696
|
|
|
651
697
|
if File.exist?(deploy_dir+"/private_key")
|
|
@@ -687,5 +733,30 @@ module MU
|
|
|
687
733
|
}
|
|
688
734
|
end
|
|
689
735
|
|
|
736
|
+
def findResourceConfig(type, name, config = @original_config)
|
|
737
|
+
orig_cfg = nil
|
|
738
|
+
if config.has_key?(type)
|
|
739
|
+
config[type].each { |resource|
|
|
740
|
+
if resource["name"] == name
|
|
741
|
+
orig_cfg = resource
|
|
742
|
+
break
|
|
743
|
+
end
|
|
744
|
+
}
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
# Some Server objects originated from ServerPools, get their
|
|
748
|
+
# configs from there
|
|
749
|
+
if type == "servers" and orig_cfg.nil? and config.has_key?("server_pools")
|
|
750
|
+
config["server_pools"].each { |resource|
|
|
751
|
+
if resource["name"] == name
|
|
752
|
+
orig_cfg = resource
|
|
753
|
+
break
|
|
754
|
+
end
|
|
755
|
+
}
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
orig_cfg
|
|
759
|
+
end
|
|
760
|
+
|
|
690
761
|
end #class
|
|
691
762
|
end #module
|