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
data/modules/mu/adoption.rb
CHANGED
|
@@ -30,7 +30,8 @@ module MU
|
|
|
30
30
|
:omnibus => "Jam everything into one monolothic configuration"
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
def initialize(clouds: MU::Cloud.supportedClouds, types: MU::Cloud.resource_types.keys, parent: nil, billing: nil, sources: nil, credentials: nil, group_by: :logical, savedeploys: false, diff: false, habitats: [], scrub_mu_isms: false, regions: [], merge: false)
|
|
34
35
|
@scraped = {}
|
|
35
36
|
@clouds = clouds
|
|
36
37
|
@types = types
|
|
@@ -44,7 +45,10 @@ module MU
|
|
|
44
45
|
@savedeploys = savedeploys
|
|
45
46
|
@diff = diff
|
|
46
47
|
@habitats = habitats
|
|
48
|
+
@regions = regions
|
|
47
49
|
@habitats ||= []
|
|
50
|
+
@scrub_mu_isms = scrub_mu_isms
|
|
51
|
+
@merge = merge
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
# Walk cloud providers with available credentials to discover resources
|
|
@@ -52,7 +56,7 @@ module MU
|
|
|
52
56
|
@default_parent = nil
|
|
53
57
|
|
|
54
58
|
@clouds.each { |cloud|
|
|
55
|
-
cloudclass =
|
|
59
|
+
cloudclass = MU::Cloud.cloudClass(cloud)
|
|
56
60
|
next if cloudclass.listCredentials.nil?
|
|
57
61
|
|
|
58
62
|
if cloud == "Google" and !@parent and @target_creds
|
|
@@ -64,6 +68,10 @@ module MU
|
|
|
64
68
|
|
|
65
69
|
cloudclass.listCredentials.each { |credset|
|
|
66
70
|
next if @sources and !@sources.include?(credset)
|
|
71
|
+
cfg = cloudclass.credConfig(credset)
|
|
72
|
+
if cfg and cfg['restrict_to_habitats']
|
|
73
|
+
cfg['restrict_to_habitats'] << cfg['project'] if cfg['project']
|
|
74
|
+
end
|
|
67
75
|
|
|
68
76
|
if @parent
|
|
69
77
|
# TODO handle different inputs (cloud_id, etc)
|
|
@@ -84,7 +92,7 @@ module MU
|
|
|
84
92
|
|
|
85
93
|
@types.each { |type|
|
|
86
94
|
begin
|
|
87
|
-
resclass =
|
|
95
|
+
resclass = MU::Cloud.resourceClass(cloud, type)
|
|
88
96
|
rescue ::MU::Cloud::MuCloudResourceNotImplemented
|
|
89
97
|
next
|
|
90
98
|
end
|
|
@@ -100,17 +108,30 @@ module MU
|
|
|
100
108
|
credentials: credset,
|
|
101
109
|
allow_multi: true,
|
|
102
110
|
habitats: @habitats.dup,
|
|
111
|
+
region: @regions,
|
|
103
112
|
dummy_ok: true,
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
skip_provider_owned: true,
|
|
114
|
+
# debug: false#,
|
|
106
115
|
)
|
|
107
116
|
|
|
108
117
|
|
|
109
118
|
if found and found.size > 0
|
|
119
|
+
if resclass.cfg_plural == "habitats"
|
|
120
|
+
found.reject! { |h|
|
|
121
|
+
!cloudclass.listHabitats(credset).include?(h.cloud_id)
|
|
122
|
+
}
|
|
123
|
+
end
|
|
110
124
|
MU.log "Found #{found.size.to_s} raw #{resclass.cfg_plural} in #{cloud}"
|
|
111
125
|
@scraped[type] ||= {}
|
|
112
126
|
found.each { |obj|
|
|
127
|
+
if obj.habitat and !cloudclass.listHabitats(credset).include?(obj.habitat)
|
|
128
|
+
next
|
|
129
|
+
end
|
|
113
130
|
# XXX apply any filters (e.g. MU-ID tags)
|
|
131
|
+
if obj.cloud_id.nil?
|
|
132
|
+
MU.log "This damn thing gave me no cloud id, what do I even do with that", MU::ERR, details: obj
|
|
133
|
+
exit
|
|
134
|
+
end
|
|
114
135
|
@scraped[type][obj.cloud_id] = obj
|
|
115
136
|
}
|
|
116
137
|
end
|
|
@@ -123,6 +144,8 @@ module MU
|
|
|
123
144
|
MU.log "Failed to locate a folder that resembles #{@parent}", MU::ERR
|
|
124
145
|
end
|
|
125
146
|
MU.log "Scraping complete"
|
|
147
|
+
|
|
148
|
+
@scraped
|
|
126
149
|
end
|
|
127
150
|
|
|
128
151
|
# Given a list of BoK style tags, try to reverse-engineer the correct
|
|
@@ -130,8 +153,9 @@ module MU
|
|
|
130
153
|
# this infers from Mu-style tagging, but we'll add a couple cases for
|
|
131
154
|
# special cloud provider cases.
|
|
132
155
|
# @param tags [Array<Hash>]
|
|
156
|
+
# @param basename [String]
|
|
133
157
|
# return [String]
|
|
134
|
-
def self.tagsToName(tags = [])
|
|
158
|
+
def self.tagsToName(tags = [], basename: nil)
|
|
135
159
|
tags.each { |tag|
|
|
136
160
|
if tag['key'] == "aws:cloudformation:logical-id"
|
|
137
161
|
return tag['value']
|
|
@@ -144,6 +168,7 @@ module MU
|
|
|
144
168
|
break
|
|
145
169
|
end
|
|
146
170
|
}
|
|
171
|
+
|
|
147
172
|
tags.each { |tag|
|
|
148
173
|
if tag['key'] == "Name"
|
|
149
174
|
if muid and tag['value'].match(/^#{Regexp.quote(muid)}-(.*)/)
|
|
@@ -153,6 +178,11 @@ module MU
|
|
|
153
178
|
end
|
|
154
179
|
end
|
|
155
180
|
}
|
|
181
|
+
|
|
182
|
+
if basename and muid and basename.match(/^#{Regexp.quote(muid)}-(.*)/)
|
|
183
|
+
return Regexp.last_match[1].downcase
|
|
184
|
+
end
|
|
185
|
+
|
|
156
186
|
nil
|
|
157
187
|
end
|
|
158
188
|
|
|
@@ -179,53 +209,98 @@ module MU
|
|
|
179
209
|
prefix = "mu" if prefix.empty? # so that appnames aren't ever empty
|
|
180
210
|
end
|
|
181
211
|
|
|
212
|
+
# Find any previous deploys with this particular profile, which we'll use
|
|
213
|
+
# later for --diff.
|
|
214
|
+
@existing_deploys = {}
|
|
215
|
+
@existing_deploys_by_id = {}
|
|
216
|
+
@origins = {}
|
|
217
|
+
@types_found_in = {}
|
|
182
218
|
groupings.each_pair { |appname, types|
|
|
183
|
-
bok = { "appname" => prefix+appname }
|
|
184
|
-
if @target_creds
|
|
185
|
-
bok["credentials"] = @target_creds
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
count = 0
|
|
189
219
|
allowed_types = @types.map { |t| MU::Cloud.resource_types[t][:cfg_plural] }
|
|
190
220
|
next if (types & allowed_types).size == 0
|
|
191
221
|
origin = {
|
|
192
|
-
"appname" =>
|
|
222
|
+
"appname" => prefix+appname,
|
|
193
223
|
"types" => (types & allowed_types).sort,
|
|
194
224
|
"habitats" => @habitats.sort,
|
|
195
225
|
"group_by" => @group_by.to_s
|
|
196
226
|
}
|
|
197
227
|
|
|
198
|
-
|
|
199
|
-
if @
|
|
200
|
-
|
|
201
|
-
|
|
228
|
+
@existing_deploys[appname] = MU::MommaCat.findMatchingDeploy(origin)
|
|
229
|
+
if @existing_deploys[appname]
|
|
230
|
+
@existing_deploys_by_id[@existing_deploys[appname].deploy_id] = @existing_deploys[appname]
|
|
231
|
+
@origins[appname] = origin
|
|
232
|
+
origin['types'].each { |t|
|
|
233
|
+
@types_found_in[t] = @existing_deploys[appname]
|
|
234
|
+
}
|
|
235
|
+
end
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
groupings.each_pair { |appname, types|
|
|
239
|
+
allowed_types = @types.map { |t| MU::Cloud.resource_types[t][:cfg_plural] }
|
|
240
|
+
next if (types & allowed_types).size == 0
|
|
241
|
+
|
|
242
|
+
bok = { "appname" => prefix+appname }
|
|
243
|
+
if @scrub_mu_isms
|
|
244
|
+
bok["scrub_mu_isms"] = true
|
|
245
|
+
end
|
|
246
|
+
if @target_creds
|
|
247
|
+
bok["credentials"] = @target_creds
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
count = 0
|
|
251
|
+
if @diff
|
|
252
|
+
if !@existing_deploys[appname]
|
|
253
|
+
MU.log "--diff was set but I failed to find a deploy like '#{appname}' to compare to (have #{@existing_deploys.keys.join(", ")})", MU::ERR, details: @origins[appname]
|
|
254
|
+
exit 1
|
|
255
|
+
else
|
|
256
|
+
MU.log "Will diff current live resources against #{@existing_deploys[appname].deploy_id}", MU::NOTICE, details: @origins[appname]
|
|
257
|
+
end
|
|
202
258
|
end
|
|
203
259
|
|
|
204
260
|
threads = []
|
|
261
|
+
timers = {}
|
|
262
|
+
walltimers = {}
|
|
205
263
|
@clouds.each { |cloud|
|
|
206
264
|
@scraped.each_pair { |type, resources|
|
|
265
|
+
typestart = Time.now
|
|
207
266
|
res_class = begin
|
|
208
|
-
MU::Cloud.
|
|
209
|
-
rescue MU::Cloud::MuCloudResourceNotImplemented
|
|
267
|
+
MU::Cloud.resourceClass(cloud, type)
|
|
268
|
+
rescue MU::Cloud::MuCloudResourceNotImplemented
|
|
210
269
|
# XXX I don't think this can actually happen
|
|
211
270
|
next
|
|
212
271
|
end
|
|
213
272
|
next if !types.include?(res_class.cfg_plural)
|
|
214
273
|
|
|
215
274
|
bok[res_class.cfg_plural] ||= []
|
|
275
|
+
timers[type] ||= {}
|
|
216
276
|
|
|
217
277
|
class_semaphore = Mutex.new
|
|
218
278
|
|
|
219
279
|
Thread.abort_on_exception = true
|
|
220
|
-
resources.
|
|
221
|
-
|
|
280
|
+
resources.values.each { |obj_thr|
|
|
281
|
+
obj_desc = nil
|
|
282
|
+
begin
|
|
283
|
+
obj_desc = obj_thr.cloud_desc
|
|
284
|
+
rescue StandardError
|
|
285
|
+
ensure
|
|
286
|
+
if !obj_desc
|
|
287
|
+
MU.log cloud+" "+type.to_s+" "+obj_thr.cloud_id+" did not return a cloud descriptor, skipping", MU::WARN
|
|
288
|
+
next
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
threads << Thread.new(obj_thr) { |obj|
|
|
292
|
+
start = Time.now
|
|
222
293
|
|
|
223
|
-
kitten_cfg = obj.toKitten(rootparent: @default_parent, billing: @billing, habitats: @habitats)
|
|
294
|
+
kitten_cfg = obj.toKitten(rootparent: @default_parent, billing: @billing, habitats: @habitats, types: @types)
|
|
224
295
|
if kitten_cfg
|
|
225
296
|
print "."
|
|
226
297
|
kitten_cfg.delete("credentials") if @target_creds
|
|
227
298
|
class_semaphore.synchronize {
|
|
228
299
|
bok[res_class.cfg_plural] << kitten_cfg
|
|
300
|
+
if !kitten_cfg['cloud_id']
|
|
301
|
+
MU.log "No cloud id in this #{res_class.cfg_name} kitten!", MU::ERR, details: kitten_cfg
|
|
302
|
+
end
|
|
303
|
+
timers[type][kitten_cfg['cloud_id']] = (Time.now - start)
|
|
229
304
|
}
|
|
230
305
|
count += 1
|
|
231
306
|
end
|
|
@@ -236,6 +311,7 @@ module MU
|
|
|
236
311
|
threads.each { |t|
|
|
237
312
|
t.join
|
|
238
313
|
}
|
|
314
|
+
|
|
239
315
|
puts ""
|
|
240
316
|
bok[res_class.cfg_plural].sort! { |a, b|
|
|
241
317
|
strs = [a, b].map { |x|
|
|
@@ -257,49 +333,68 @@ module MU
|
|
|
257
333
|
bok[res_class.cfg_plural].each { |sibling|
|
|
258
334
|
next if kitten_cfg == sibling
|
|
259
335
|
if sibling['name'] == kitten_cfg['name']
|
|
260
|
-
MU.
|
|
261
|
-
if kitten_cfg['parent'] and kitten_cfg['parent'].respond_to?(:id) and kitten_cfg['parent'].id
|
|
262
|
-
kitten_cfg['name'] = kitten_cfg['name']+kitten_cfg['parent'].id
|
|
263
|
-
elsif kitten_cfg['project']
|
|
264
|
-
kitten_cfg['name'] = kitten_cfg['name']+kitten_cfg['project']
|
|
265
|
-
elsif kitten_cfg['region']
|
|
266
|
-
kitten_cfg['name'] = kitten_cfg['name']+kitten_cfg['region']
|
|
267
|
-
elsif kitten_cfg['cloud_id']
|
|
268
|
-
kitten_cfg['name'] = kitten_cfg['name']+kitten_cfg['cloud_id'].gsub(/[^a-z0-9]/i, "-")
|
|
269
|
-
else
|
|
270
|
-
raise MU::Config::DuplicateNameError, "Saw duplicate #{res_class.cfg_name} name #{sibling['name']} and couldn't come up with a good way to differentiate them"
|
|
271
|
-
end
|
|
336
|
+
MU::Adoption.deDuplicateName(kitten_cfg, res_class)
|
|
272
337
|
MU.log "De-duplication: Renamed #{res_class.cfg_name} name '#{sibling['name']}' => '#{kitten_cfg['name']}'", MU::NOTICE
|
|
273
338
|
break
|
|
274
339
|
end
|
|
275
340
|
}
|
|
276
341
|
}
|
|
342
|
+
walltimers[type] ||= 0
|
|
343
|
+
walltimers[type] += (Time.now - typestart)
|
|
277
344
|
}
|
|
278
345
|
}
|
|
279
346
|
|
|
347
|
+
timers.each_pair { |type, resources|
|
|
348
|
+
next if resources.empty?
|
|
349
|
+
total = resources.values.sum
|
|
350
|
+
top_5 = resources.keys.sort { |a, b|
|
|
351
|
+
resources[b] <=> resources[a]
|
|
352
|
+
}.slice(0, 5).map { |k|
|
|
353
|
+
k.to_s+": "+sprintf("%.2fs", resources[k])
|
|
354
|
+
}
|
|
355
|
+
if walltimers[type] < 45
|
|
356
|
+
MU.log "Kittened #{resources.size.to_s} eligible #{type}s in #{sprintf("%.2fs", walltimers[type])}"
|
|
357
|
+
else
|
|
358
|
+
MU.log "Kittened #{resources.size.to_s} eligible #{type}s in #{sprintf("%.2fs", walltimers[type])} (CPU time #{sprintf("%.2fs", total)}, avg #{sprintf("%.2fs", total/resources.size)}). Top 5:", MU::NOTICE, details: top_5
|
|
359
|
+
end
|
|
360
|
+
}
|
|
361
|
+
|
|
280
362
|
# No matching resources isn't necessarily an error
|
|
281
363
|
next if count == 0 or bok.nil?
|
|
282
364
|
|
|
283
365
|
# Now walk through all of the Refs in these objects, resolve them, and minimize
|
|
284
366
|
# their config footprint
|
|
285
367
|
MU.log "Minimizing footprint of #{count.to_s} found resources", MU::DEBUG
|
|
286
|
-
@boks[bok['appname']] = vacuum(bok, origin: origin, save: @savedeploys)
|
|
287
368
|
|
|
288
|
-
|
|
369
|
+
generated_deploy = generateStubDeploy(bok)
|
|
370
|
+
@boks[bok['appname']] = vacuum(bok, origin: @origins[appname], deploy: generated_deploy, save: @savedeploys)
|
|
371
|
+
|
|
372
|
+
if @diff and !@existing_deploys[appname]
|
|
289
373
|
MU.log "diff flag set, but no comparable deploy provided for #{bok['appname']}", MU::ERR
|
|
290
374
|
exit 1
|
|
291
375
|
end
|
|
292
376
|
|
|
293
|
-
if
|
|
294
|
-
|
|
377
|
+
if @diff
|
|
378
|
+
prev_vacuumed = vacuum(@existing_deploys[appname].original_config, deploy: @existing_deploys[appname], keep_missing: true, copy_from: generated_deploy)
|
|
379
|
+
prevcfg = MU::Config.manxify(prev_vacuumed)
|
|
295
380
|
if !prevcfg
|
|
296
|
-
MU.log "#{
|
|
381
|
+
MU.log "#{@existing_deploys[appname].deploy_id} didn't have a working original config for me to compare", MU::ERR
|
|
297
382
|
exit 1
|
|
298
383
|
end
|
|
299
384
|
newcfg = MU::Config.manxify(@boks[bok['appname']])
|
|
385
|
+
report = prevcfg.diff(newcfg)
|
|
386
|
+
|
|
387
|
+
if report
|
|
388
|
+
|
|
389
|
+
if MU.muCfg['adopt_change_notify']
|
|
390
|
+
notifyChanges(@existing_deploys[appname], report.freeze)
|
|
391
|
+
end
|
|
392
|
+
if @merge
|
|
393
|
+
MU.log "Saving changes to #{@existing_deploys[appname].deploy_id}"
|
|
394
|
+
@existing_deploys[appname].updateBasketofKittens(newcfg, save_now: true)
|
|
395
|
+
end
|
|
396
|
+
end
|
|
300
397
|
|
|
301
|
-
prevcfg.diff(newcfg)
|
|
302
|
-
exit
|
|
303
398
|
end
|
|
304
399
|
}
|
|
305
400
|
@boks
|
|
@@ -307,14 +402,191 @@ module MU
|
|
|
307
402
|
|
|
308
403
|
private
|
|
309
404
|
|
|
310
|
-
|
|
405
|
+
# @param tier [Hash]
|
|
406
|
+
# @param parent_key [String]
|
|
407
|
+
def crawlChangeReport(tier, parent_key = nil, indent: "")
|
|
408
|
+
report = []
|
|
409
|
+
if tier.is_a?(Array)
|
|
410
|
+
tier.each { |a|
|
|
411
|
+
sub_report = crawlChangeReport(a, parent_key)
|
|
412
|
+
report.concat(sub_report) if sub_report and !sub_report.empty?
|
|
413
|
+
}
|
|
414
|
+
elsif tier.is_a?(Hash)
|
|
415
|
+
if tier[:action]
|
|
416
|
+
preposition = if tier[:action] == :added
|
|
417
|
+
"to"
|
|
418
|
+
elsif tier[:action] == :removed
|
|
419
|
+
"from"
|
|
420
|
+
else
|
|
421
|
+
"in"
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
name = ""
|
|
425
|
+
type_of = parent_key.sub(/s$|\[.*/, '') if parent_key
|
|
426
|
+
loc = tier[:habitat]
|
|
427
|
+
|
|
428
|
+
if tier[:value] and tier[:value].is_a?(Hash)
|
|
429
|
+
name, loc = MU::MommaCat.getChunkName(tier[:value], type_of)
|
|
430
|
+
elsif parent_key
|
|
431
|
+
name = parent_key
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
path_str = []
|
|
435
|
+
slack_path_str = ""
|
|
436
|
+
if tier[:parents] and tier[:parents].size > 2
|
|
437
|
+
path = tier[:parents].clone
|
|
438
|
+
slack_path_str += "#{preposition} \*"+path.join(" ⇨ ")+"\*" if path.size > 0
|
|
439
|
+
path.shift
|
|
440
|
+
path.shift
|
|
441
|
+
path.pop if path.last == name
|
|
442
|
+
for c in (0..(path.size-1)) do
|
|
443
|
+
path_str << (" " * (c+2)) + (path[c] || "<nil>")
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
path_str << "" if !path_str.empty?
|
|
447
|
+
|
|
448
|
+
plain = (name ? name : type_of) if name or type_of
|
|
449
|
+
plain ||= "" # XXX but this is a problem
|
|
450
|
+
slack = "`"+plain+"`"
|
|
451
|
+
|
|
452
|
+
plain += " ("+loc+")" if loc and !loc.empty?
|
|
453
|
+
color = plain
|
|
454
|
+
|
|
455
|
+
if tier[:action] == :added
|
|
456
|
+
color = "+ ".green + plain
|
|
457
|
+
plain = "+ " + plain
|
|
458
|
+
slack += " added"
|
|
459
|
+
elsif tier[:action] == :removed
|
|
460
|
+
color = "- ".red + plain
|
|
461
|
+
plain = "- " + plain
|
|
462
|
+
slack += " removed"
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
slack += " #{tier[:action]} #{preposition} \*#{loc}\*" if loc and !loc.empty? and [Array, Hash].include?(tier[:value].class)
|
|
466
|
+
|
|
467
|
+
plain = path_str.join(" => \n") + indent + plain
|
|
468
|
+
color = path_str.join(" => \n") + indent + color
|
|
469
|
+
|
|
470
|
+
slack += " "+slack_path_str if !slack_path_str.empty?
|
|
471
|
+
myreport = {
|
|
472
|
+
"slack" => slack,
|
|
473
|
+
"plain" => plain,
|
|
474
|
+
"color" => color
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
append = ""
|
|
478
|
+
if tier[:value] and (tier[:value].is_a?(Array) or tier[:value].is_a?(Hash))
|
|
479
|
+
if tier[:value].is_a?(Hash)
|
|
480
|
+
if name
|
|
481
|
+
tier[:value].delete("entity")
|
|
482
|
+
tier[:value].delete(name.sub(/\[.*/, '')) if name
|
|
483
|
+
end
|
|
484
|
+
if (tier[:value].keys - ["id", "name", "type"]).size > 0
|
|
485
|
+
myreport["details"] = tier[:value].clone
|
|
486
|
+
append = PP.pp(tier[:value], '').gsub(/(^|\n)/, '\1'+indent)
|
|
487
|
+
end
|
|
488
|
+
else
|
|
489
|
+
append = indent+"["+tier[:value].map { |v| MU::MommaCat.getChunkName(v, type_of).reverse.join("/") || v.to_s.light_blue }.join(", ")+"]"
|
|
490
|
+
slack += " #{tier[:action].to_s}: "+tier[:value].map { |v| MU::MommaCat.getChunkName(v, type_of).reverse.join("/") || v.to_s }.join(", ")
|
|
491
|
+
end
|
|
492
|
+
else
|
|
493
|
+
tier[:value] ||= "<nil>"
|
|
494
|
+
if ![:removed].include?(tier[:action])
|
|
495
|
+
myreport["slack"] += ". New #{tier[:field] ? "`"+tier[:field]+"`" : :value}: \*#{tier[:value]}\*"
|
|
496
|
+
else
|
|
497
|
+
myreport["slack"] += " (was \*#{tier[:value]}\*)"
|
|
498
|
+
end
|
|
499
|
+
append = tier[:value].to_s.bold
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
if append and !append.empty?
|
|
503
|
+
myreport["plain"] += " =>\n "+indent+append
|
|
504
|
+
myreport["color"] += " =>\n "+indent+append
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
report << myreport if tier[:action]
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
# Just because we've got changes at this level doesn't mean there aren't
|
|
511
|
+
# more further down.
|
|
512
|
+
tier.each_pair { |k, v|
|
|
513
|
+
next if !(v.is_a?(Hash) or v.is_a?(Array))
|
|
514
|
+
sub_report = crawlChangeReport(v, k, indent: indent+" ")
|
|
515
|
+
report.concat(sub_report) if sub_report and !sub_report.empty?
|
|
516
|
+
}
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
report
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
def notifyChanges(deploy, report)
|
|
524
|
+
snippet_threshold = (MU.muCfg['adopt_change_notify'] && MU.muCfg['adopt_change_notify']['slack_snippet_threshold']) || 5
|
|
525
|
+
|
|
526
|
+
report.each_pair { |res_type, resources|
|
|
527
|
+
shortclass, _cfg_name, _cfg_plural, _classname = MU::Cloud.getResourceNames(res_type, false)
|
|
528
|
+
next if !shortclass # we don't really care about Mu metadata changes
|
|
529
|
+
resources.each_pair { |name, data|
|
|
530
|
+
if MU::MommaCat.getChunkName(data[:value], res_type).first.nil?
|
|
531
|
+
symbol = if data[:action] == :added
|
|
532
|
+
"+".green
|
|
533
|
+
elsif data[:action] == :removed
|
|
534
|
+
"-".red
|
|
535
|
+
else
|
|
536
|
+
"~".yellow
|
|
537
|
+
end
|
|
538
|
+
puts (symbol+" "+res_type+"["+name+"]")
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
noun = shortclass ? shortclass.to_s : res_type.capitalize
|
|
542
|
+
verb = if data[:action]
|
|
543
|
+
data[:action].to_s
|
|
544
|
+
else
|
|
545
|
+
"modified"
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
changes = crawlChangeReport(data.freeze, res_type)
|
|
549
|
+
|
|
550
|
+
slacktext = "#{noun} \*#{name}\* was #{verb}"
|
|
551
|
+
if data[:habitat]
|
|
552
|
+
slacktext += " in \*#{data[:habitat]}\*"
|
|
553
|
+
end
|
|
554
|
+
snippets = []
|
|
555
|
+
|
|
556
|
+
if [:added, :removed].include?(data[:action]) and data[:value]
|
|
557
|
+
snippets << { text: "```"+JSON.pretty_generate(data[:value])+"```" }
|
|
558
|
+
else
|
|
559
|
+
changes.each { |c|
|
|
560
|
+
slacktext += "\n • "+c["slack"]
|
|
561
|
+
if c["details"]
|
|
562
|
+
details = JSON.pretty_generate(c["details"])
|
|
563
|
+
snippets << { text: "```"+JSON.pretty_generate(c["details"])+"```" }
|
|
564
|
+
end
|
|
565
|
+
}
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
changes.each { |c|
|
|
569
|
+
puts c["color"]
|
|
570
|
+
}
|
|
571
|
+
puts ""
|
|
572
|
+
|
|
573
|
+
if MU.muCfg['adopt_change_notify'] and MU.muCfg['adopt_change_notify']['slack']
|
|
574
|
+
deploy.sendAdminSlack(slacktext, scrub_mu_isms: MU.muCfg['adopt_scrub_mu_isms'], snippets: snippets, noop: false)
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
def scrubSchemaDefaults(conf_chunk, schema_chunk, depth = 0, type: nil)
|
|
311
583
|
return if schema_chunk.nil?
|
|
312
584
|
|
|
313
585
|
if !conf_chunk.nil? and schema_chunk["properties"].kind_of?(Hash) and conf_chunk.is_a?(Hash)
|
|
314
586
|
deletia = []
|
|
315
587
|
schema_chunk["properties"].each_pair { |key, subschema|
|
|
316
588
|
next if !conf_chunk[key]
|
|
317
|
-
shortclass,
|
|
589
|
+
shortclass, _cfg_name, _cfg_plural, _classname = MU::Cloud.getResourceNames(key, false)
|
|
318
590
|
|
|
319
591
|
if subschema["default_if"]
|
|
320
592
|
subschema["default_if"].each { |cond|
|
|
@@ -328,7 +600,7 @@ module MU
|
|
|
328
600
|
if subschema["default"] and conf_chunk[key] == subschema["default"]
|
|
329
601
|
deletia << key
|
|
330
602
|
elsif ["array", "object"].include?(subschema["type"])
|
|
331
|
-
scrubSchemaDefaults(conf_chunk[key], subschema, depth+1,
|
|
603
|
+
scrubSchemaDefaults(conf_chunk[key], subschema, depth+1, type: shortclass)
|
|
332
604
|
end
|
|
333
605
|
}
|
|
334
606
|
deletia.each { |key| conf_chunk.delete(key) }
|
|
@@ -338,8 +610,7 @@ module MU
|
|
|
338
610
|
# theory
|
|
339
611
|
realschema = if type and schema_chunk["items"] and schema_chunk["items"]["properties"] and item["cloud"] and MU::Cloud.supportedClouds.include?(item['cloud'])
|
|
340
612
|
|
|
341
|
-
|
|
342
|
-
toplevel_required, cloudschema = cloudclass.schema(self)
|
|
613
|
+
_toplevel_required, cloudschema = MU::Cloud.resourceClass(item['cloud'], type).schema(self)
|
|
343
614
|
|
|
344
615
|
newschema = schema_chunk["items"].dup
|
|
345
616
|
newschema["properties"].merge!(cloudschema)
|
|
@@ -349,7 +620,7 @@ module MU
|
|
|
349
620
|
end
|
|
350
621
|
next if ["array", "object"].include?(realschema["type"])
|
|
351
622
|
|
|
352
|
-
scrubSchemaDefaults(item, realschema, depth+1,
|
|
623
|
+
scrubSchemaDefaults(item, realschema, depth+1, type: type)
|
|
353
624
|
}
|
|
354
625
|
end
|
|
355
626
|
|
|
@@ -363,8 +634,7 @@ module MU
|
|
|
363
634
|
# Do the same for our main objects: if they all use the same credentials,
|
|
364
635
|
# for example, remove the explicit +credentials+ attributes and set that
|
|
365
636
|
# value globally, once.
|
|
366
|
-
def vacuum(bok, origin: nil, save: false, deploy: nil)
|
|
367
|
-
deploy ||= generateStubDeploy(bok)
|
|
637
|
+
def vacuum(bok, origin: nil, save: false, deploy: nil, copy_from: nil, keep_missing: false)
|
|
368
638
|
|
|
369
639
|
globals = {
|
|
370
640
|
'cloud' => {},
|
|
@@ -373,10 +643,7 @@ module MU
|
|
|
373
643
|
'billing_acct' => {},
|
|
374
644
|
'us_only' => {},
|
|
375
645
|
}
|
|
376
|
-
|
|
377
|
-
credentials = {}
|
|
378
|
-
regions = {}
|
|
379
|
-
MU::Cloud.resource_types.each_pair { |typename, attrs|
|
|
646
|
+
MU::Cloud.resource_types.values.each { |attrs|
|
|
380
647
|
if bok[attrs[:cfg_plural]]
|
|
381
648
|
processed = []
|
|
382
649
|
bok[attrs[:cfg_plural]].each { |resource|
|
|
@@ -387,11 +654,24 @@ module MU
|
|
|
387
654
|
end
|
|
388
655
|
}
|
|
389
656
|
obj = deploy.findLitterMate(type: attrs[:cfg_plural], name: resource['name'])
|
|
657
|
+
inject_metadata = save
|
|
658
|
+
if obj.nil? and copy_from
|
|
659
|
+
obj = copy_from.findLitterMate(type: attrs[:cfg_plural], name: resource['name'])
|
|
660
|
+
if obj
|
|
661
|
+
inject_metadata = true
|
|
662
|
+
obj.intoDeploy(deploy, force: true)
|
|
663
|
+
end
|
|
664
|
+
end
|
|
665
|
+
|
|
390
666
|
begin
|
|
391
667
|
raise Incomplete if obj.nil?
|
|
668
|
+
if inject_metadata
|
|
669
|
+
deploydata = obj.notify
|
|
670
|
+
deploy.notify(attrs[:cfg_plural], resource['name'], deploydata, triggering_node: obj)
|
|
671
|
+
end
|
|
392
672
|
new_cfg = resolveReferences(resource, deploy, obj)
|
|
393
673
|
new_cfg.delete("cloud_id")
|
|
394
|
-
cred_cfg = MU::Cloud.
|
|
674
|
+
cred_cfg = MU::Cloud.cloudClass(obj.cloud).credConfig(obj.credentials)
|
|
395
675
|
if cred_cfg['region'] == new_cfg['region']
|
|
396
676
|
new_cfg.delete('region')
|
|
397
677
|
end
|
|
@@ -401,6 +681,11 @@ module MU
|
|
|
401
681
|
end
|
|
402
682
|
processed << new_cfg
|
|
403
683
|
rescue Incomplete
|
|
684
|
+
if keep_missing
|
|
685
|
+
processed << resource
|
|
686
|
+
else
|
|
687
|
+
MU.log "#{attrs[:cfg_name]} #{resource['name']} didn't show up from findLitterMate", MU::WARN, details: deploy.original_config[attrs[:cfg_plural]].reject { |r| r['name'] != "" }
|
|
688
|
+
end
|
|
404
689
|
end
|
|
405
690
|
}
|
|
406
691
|
|
|
@@ -411,34 +696,33 @@ module MU
|
|
|
411
696
|
|
|
412
697
|
# Pare out global values like +cloud+ or +region+ that appear to be
|
|
413
698
|
# universal in the deploy we're creating.
|
|
414
|
-
|
|
699
|
+
scrub_globals = Proc.new { |h, field|
|
|
415
700
|
if h.is_a?(Hash)
|
|
416
701
|
newhash = {}
|
|
417
702
|
h.each_pair { |k, v|
|
|
418
703
|
next if k == field
|
|
419
|
-
newhash[k] = scrub_globals(v, field)
|
|
704
|
+
newhash[k] = scrub_globals.call(v, field)
|
|
420
705
|
}
|
|
421
706
|
h = newhash
|
|
422
707
|
elsif h.is_a?(Array)
|
|
423
708
|
newarr = []
|
|
424
709
|
h.each { |v|
|
|
425
|
-
newarr << scrub_globals(v, field)
|
|
710
|
+
newarr << scrub_globals.call(v, field)
|
|
426
711
|
}
|
|
427
|
-
h = newarr
|
|
712
|
+
h = newarr.uniq
|
|
428
713
|
end
|
|
429
|
-
|
|
430
714
|
h
|
|
431
|
-
|
|
715
|
+
}
|
|
432
716
|
|
|
433
717
|
globals.each_pair { |field, counts|
|
|
434
718
|
next if counts.size != 1
|
|
435
719
|
bok[field] = counts.keys.first
|
|
436
720
|
MU.log "Setting global default #{field} to #{bok[field]} (#{deploy.deploy_id})", MU::DEBUG
|
|
437
|
-
MU::Cloud.resource_types.
|
|
721
|
+
MU::Cloud.resource_types.values.each { |attrs|
|
|
438
722
|
if bok[attrs[:cfg_plural]]
|
|
439
723
|
new_resources = []
|
|
440
724
|
bok[attrs[:cfg_plural]].each { |resource|
|
|
441
|
-
new_resources << scrub_globals(resource, field)
|
|
725
|
+
new_resources << scrub_globals.call(resource, field)
|
|
442
726
|
}
|
|
443
727
|
bok[attrs[:cfg_plural]] = new_resources
|
|
444
728
|
end
|
|
@@ -456,9 +740,33 @@ module MU
|
|
|
456
740
|
end
|
|
457
741
|
|
|
458
742
|
def resolveReferences(cfg, deploy, parent)
|
|
743
|
+
mask_deploy_id = false
|
|
744
|
+
|
|
745
|
+
check_deploy_id = Proc.new { |cfgblob|
|
|
746
|
+
(deploy and
|
|
747
|
+
(cfgblob.is_a?(MU::Config::Ref) or cfgblob.is_a?(Hash)) and
|
|
748
|
+
cfgblob['deploy_id'] and
|
|
749
|
+
cfgblob['deploy_id'] != deploy.deploy_id and
|
|
750
|
+
@diff and
|
|
751
|
+
@types_found_in[cfgblob['type']] and
|
|
752
|
+
@types_found_in[cfgblob['type']].deploy_id == cfgblob['deploy_id']
|
|
753
|
+
)
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
mask_deploy_id = check_deploy_id.call(cfg)
|
|
757
|
+
|
|
459
758
|
if cfg.is_a?(MU::Config::Ref)
|
|
759
|
+
if mask_deploy_id
|
|
760
|
+
cfg.delete("deploy_id")
|
|
761
|
+
cfg.delete("mommacat")
|
|
762
|
+
cfg.kitten(deploy)
|
|
763
|
+
else
|
|
764
|
+
cfg.kitten(deploy) || cfg.kitten
|
|
765
|
+
end
|
|
766
|
+
|
|
460
767
|
hashcfg = cfg.to_h
|
|
461
|
-
|
|
768
|
+
|
|
769
|
+
if cfg.kitten
|
|
462
770
|
littermate = deploy.findLitterMate(type: cfg.type, name: cfg.name, cloud_id: cfg.id, habitat: cfg.habitat)
|
|
463
771
|
|
|
464
772
|
if littermate and littermate.config['name']
|
|
@@ -480,16 +788,16 @@ module MU
|
|
|
480
788
|
hashcfg.delete("name") if cfg.id and !cfg.deploy_id
|
|
481
789
|
end
|
|
482
790
|
end
|
|
483
|
-
elsif hashcfg["id"]
|
|
791
|
+
elsif hashcfg["id"] and !hashcfg["name"]
|
|
484
792
|
hashcfg.delete("deploy_id")
|
|
485
|
-
hashcfg.delete("name")
|
|
486
793
|
else
|
|
487
794
|
pp parent.cloud_desc
|
|
488
795
|
raise Incomplete, "Failed to resolve reference on behalf of #{parent}"
|
|
489
796
|
end
|
|
490
797
|
hashcfg.delete("deploy_id") if hashcfg['deploy_id'] == deploy.deploy_id
|
|
798
|
+
|
|
491
799
|
if parent and parent.config
|
|
492
|
-
cred_cfg = MU::Cloud.
|
|
800
|
+
cred_cfg = MU::Cloud.cloudClass(parent.cloud).credConfig(parent.credentials)
|
|
493
801
|
|
|
494
802
|
if parent.config['region'] == hashcfg['region'] or
|
|
495
803
|
cred_cfg['region'] == hashcfg['region']
|
|
@@ -548,7 +856,12 @@ module MU
|
|
|
548
856
|
MU.log "Dropping unresolved value", MU::WARN, details: value
|
|
549
857
|
end
|
|
550
858
|
}
|
|
551
|
-
cfg = new_array
|
|
859
|
+
cfg = new_array.uniq
|
|
860
|
+
end
|
|
861
|
+
|
|
862
|
+
if mask_deploy_id or check_deploy_id.call(cfg)
|
|
863
|
+
cfg.delete("deploy_id")
|
|
864
|
+
MU.log "#{parent} in #{deploy.deploy_id} references something in #{@types_found_in[cfg['type']].deploy_id}, ditching extraneous deploy_id", MU::DEBUG, details: cfg.to_h
|
|
552
865
|
end
|
|
553
866
|
|
|
554
867
|
cfg
|
|
@@ -598,6 +911,10 @@ module MU
|
|
|
598
911
|
|
|
599
912
|
if !@scraped[typename][kitten['cloud_id']]
|
|
600
913
|
MU.log "No object in scraped tree for #{attrs[:cfg_name]} #{kitten['cloud_id']} (#{kitten['name']})", MU::ERR, details: kitten
|
|
914
|
+
if kitten['cloud_id'].nil?
|
|
915
|
+
pp caller
|
|
916
|
+
exit
|
|
917
|
+
end
|
|
601
918
|
next
|
|
602
919
|
end
|
|
603
920
|
|
|
@@ -608,7 +925,8 @@ module MU
|
|
|
608
925
|
deploy.addKitten(
|
|
609
926
|
attrs[:cfg_plural],
|
|
610
927
|
kitten['name'],
|
|
611
|
-
@scraped[typename][kitten['cloud_id']]
|
|
928
|
+
@scraped[typename][kitten['cloud_id']],
|
|
929
|
+
do_notify: true
|
|
612
930
|
)
|
|
613
931
|
}
|
|
614
932
|
end
|
|
@@ -617,6 +935,21 @@ module MU
|
|
|
617
935
|
deploy
|
|
618
936
|
end
|
|
619
937
|
|
|
938
|
+
def self.deDuplicateName(kitten_cfg, res_class)
|
|
939
|
+
orig_name = kitten_cfg['name'].dup
|
|
940
|
+
if kitten_cfg['parent'] and kitten_cfg['parent'].respond_to?(:id) and kitten_cfg['parent'].id
|
|
941
|
+
kitten_cfg['name'] = kitten_cfg['name']+"-"+kitten_cfg['parent'].id
|
|
942
|
+
elsif kitten_cfg['project']
|
|
943
|
+
kitten_cfg['name'] = kitten_cfg['name']+"-"+kitten_cfg['project']
|
|
944
|
+
elsif kitten_cfg['region']
|
|
945
|
+
kitten_cfg['name'] = kitten_cfg['name']+"-"+kitten_cfg['region']
|
|
946
|
+
elsif kitten_cfg['cloud_id']
|
|
947
|
+
kitten_cfg['name'] = kitten_cfg['name']+"-"+kitten_cfg['cloud_id'].gsub(/[^a-z0-9]/i, "-")
|
|
948
|
+
else
|
|
949
|
+
raise MU::Config::DuplicateNameError, "Saw duplicate #{res_class.cfg_name} name #{orig_name} and couldn't come up with a good way to differentiate them"
|
|
950
|
+
end
|
|
951
|
+
end
|
|
952
|
+
|
|
620
953
|
# Go through everything we've scraped and update our mappings of cloud ids
|
|
621
954
|
# and bare name fields, so that resources can reference one another
|
|
622
955
|
# portably by name.
|