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