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.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/bin/mu-adopt +15 -12
  4. data/bin/mu-azure-tests +57 -0
  5. data/bin/mu-cleanup +2 -4
  6. data/bin/mu-configure +37 -1
  7. data/bin/mu-deploy +3 -3
  8. data/bin/mu-findstray-tests +25 -0
  9. data/bin/mu-gen-docs +2 -4
  10. data/bin/mu-load-config.rb +2 -1
  11. data/bin/mu-run-tests +37 -12
  12. data/cloud-mu.gemspec +4 -4
  13. data/cookbooks/mu-tools/attributes/default.rb +7 -0
  14. data/cookbooks/mu-tools/libraries/helper.rb +87 -3
  15. data/cookbooks/mu-tools/recipes/apply_security.rb +39 -23
  16. data/cookbooks/mu-tools/recipes/aws_api.rb +13 -0
  17. data/cookbooks/mu-tools/recipes/google_api.rb +4 -0
  18. data/cookbooks/mu-tools/recipes/rsyslog.rb +8 -1
  19. data/cookbooks/mu-tools/resources/disk.rb +33 -12
  20. data/cookbooks/mu-tools/resources/mommacat_request.rb +1 -2
  21. data/cookbooks/mu-tools/templates/centos-8/sshd_config.erb +215 -0
  22. data/extras/clean-stock-amis +10 -2
  23. data/extras/generate-stock-images +7 -3
  24. data/extras/image-generators/AWS/centos7.yaml +19 -16
  25. data/extras/image-generators/AWS/{rhel7.yaml → rhel71.yaml} +0 -0
  26. data/extras/image-generators/AWS/{win2k12.yaml → win2k12r2.yaml} +0 -0
  27. data/modules/mommacat.ru +2 -2
  28. data/modules/mu.rb +84 -97
  29. data/modules/mu/adoption.rb +359 -59
  30. data/modules/mu/cleanup.rb +67 -44
  31. data/modules/mu/cloud.rb +108 -1754
  32. data/modules/mu/cloud/database.rb +49 -0
  33. data/modules/mu/cloud/dnszone.rb +44 -0
  34. data/modules/mu/cloud/machine_images.rb +212 -0
  35. data/modules/mu/cloud/providers.rb +81 -0
  36. data/modules/mu/cloud/resource_base.rb +929 -0
  37. data/modules/mu/cloud/server.rb +40 -0
  38. data/modules/mu/cloud/server_pool.rb +1 -0
  39. data/modules/mu/cloud/ssh_sessions.rb +228 -0
  40. data/modules/mu/cloud/winrm_sessions.rb +237 -0
  41. data/modules/mu/cloud/wrappers.rb +178 -0
  42. data/modules/mu/config.rb +122 -80
  43. data/modules/mu/config/alarm.rb +2 -6
  44. data/modules/mu/config/bucket.rb +32 -3
  45. data/modules/mu/config/cache_cluster.rb +2 -2
  46. data/modules/mu/config/cdn.rb +100 -0
  47. data/modules/mu/config/collection.rb +1 -1
  48. data/modules/mu/config/container_cluster.rb +2 -2
  49. data/modules/mu/config/database.rb +84 -105
  50. data/modules/mu/config/database.yml +1 -2
  51. data/modules/mu/config/dnszone.rb +5 -4
  52. data/modules/mu/config/doc_helpers.rb +4 -5
  53. data/modules/mu/config/endpoint.rb +2 -1
  54. data/modules/mu/config/firewall_rule.rb +3 -19
  55. data/modules/mu/config/folder.rb +1 -1
  56. data/modules/mu/config/function.rb +17 -8
  57. data/modules/mu/config/group.rb +1 -1
  58. data/modules/mu/config/habitat.rb +1 -1
  59. data/modules/mu/config/job.rb +89 -0
  60. data/modules/mu/config/loadbalancer.rb +57 -11
  61. data/modules/mu/config/log.rb +1 -1
  62. data/modules/mu/config/msg_queue.rb +1 -1
  63. data/modules/mu/config/nosqldb.rb +1 -1
  64. data/modules/mu/config/notifier.rb +8 -19
  65. data/modules/mu/config/ref.rb +81 -9
  66. data/modules/mu/config/role.rb +1 -1
  67. data/modules/mu/config/schema_helpers.rb +30 -34
  68. data/modules/mu/config/search_domain.rb +1 -1
  69. data/modules/mu/config/server.rb +5 -13
  70. data/modules/mu/config/server_pool.rb +3 -7
  71. data/modules/mu/config/storage_pool.rb +1 -1
  72. data/modules/mu/config/tail.rb +10 -0
  73. data/modules/mu/config/user.rb +1 -1
  74. data/modules/mu/config/vpc.rb +13 -17
  75. data/modules/mu/defaults/AWS.yaml +106 -106
  76. data/modules/mu/defaults/Azure.yaml +1 -0
  77. data/modules/mu/defaults/Google.yaml +1 -0
  78. data/modules/mu/deploy.rb +33 -19
  79. data/modules/mu/groomer.rb +15 -0
  80. data/modules/mu/groomers/chef.rb +3 -0
  81. data/modules/mu/logger.rb +120 -144
  82. data/modules/mu/master.rb +22 -1
  83. data/modules/mu/mommacat.rb +71 -26
  84. data/modules/mu/mommacat/daemon.rb +23 -14
  85. data/modules/mu/mommacat/naming.rb +82 -3
  86. data/modules/mu/mommacat/search.rb +59 -16
  87. data/modules/mu/mommacat/storage.rb +119 -48
  88. data/modules/mu/{clouds → providers}/README.md +1 -1
  89. data/modules/mu/{clouds → providers}/aws.rb +248 -62
  90. data/modules/mu/{clouds → providers}/aws/alarm.rb +3 -3
  91. data/modules/mu/{clouds → providers}/aws/bucket.rb +275 -41
  92. data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +14 -50
  93. data/modules/mu/providers/aws/cdn.rb +782 -0
  94. data/modules/mu/{clouds → providers}/aws/collection.rb +5 -5
  95. data/modules/mu/{clouds → providers}/aws/container_cluster.rb +65 -63
  96. data/modules/mu/providers/aws/database.rb +1747 -0
  97. data/modules/mu/{clouds → providers}/aws/dnszone.rb +26 -12
  98. data/modules/mu/providers/aws/endpoint.rb +1072 -0
  99. data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +39 -32
  100. data/modules/mu/{clouds → providers}/aws/folder.rb +1 -1
  101. data/modules/mu/{clouds → providers}/aws/function.rb +291 -133
  102. data/modules/mu/{clouds → providers}/aws/group.rb +18 -20
  103. data/modules/mu/{clouds → providers}/aws/habitat.rb +3 -3
  104. data/modules/mu/providers/aws/job.rb +469 -0
  105. data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +77 -47
  106. data/modules/mu/{clouds → providers}/aws/log.rb +5 -5
  107. data/modules/mu/{clouds → providers}/aws/msg_queue.rb +14 -11
  108. data/modules/mu/{clouds → providers}/aws/nosqldb.rb +96 -5
  109. data/modules/mu/{clouds → providers}/aws/notifier.rb +135 -63
  110. data/modules/mu/{clouds → providers}/aws/role.rb +112 -78
  111. data/modules/mu/{clouds → providers}/aws/search_domain.rb +172 -41
  112. data/modules/mu/{clouds → providers}/aws/server.rb +120 -145
  113. data/modules/mu/{clouds → providers}/aws/server_pool.rb +42 -60
  114. data/modules/mu/{clouds → providers}/aws/storage_pool.rb +21 -38
  115. data/modules/mu/{clouds → providers}/aws/user.rb +12 -16
  116. data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
  117. data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +5 -4
  118. data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +0 -0
  119. data/modules/mu/{clouds → providers}/aws/vpc.rb +141 -73
  120. data/modules/mu/{clouds → providers}/aws/vpc_subnet.rb +0 -0
  121. data/modules/mu/{clouds → providers}/azure.rb +4 -1
  122. data/modules/mu/{clouds → providers}/azure/container_cluster.rb +1 -5
  123. data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +8 -1
  124. data/modules/mu/{clouds → providers}/azure/habitat.rb +0 -0
  125. data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +0 -0
  126. data/modules/mu/{clouds → providers}/azure/role.rb +0 -0
  127. data/modules/mu/{clouds → providers}/azure/server.rb +32 -24
  128. data/modules/mu/{clouds → providers}/azure/user.rb +1 -1
  129. data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
  130. data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
  131. data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
  132. data/modules/mu/{clouds → providers}/azure/vpc.rb +4 -6
  133. data/modules/mu/{clouds → providers}/cloudformation.rb +1 -1
  134. data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
  135. data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
  136. data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
  137. data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
  138. data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
  139. data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
  140. data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
  141. data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
  142. data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
  143. data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
  144. data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +3 -3
  145. data/modules/mu/{clouds → providers}/docker.rb +0 -0
  146. data/modules/mu/{clouds → providers}/google.rb +15 -6
  147. data/modules/mu/{clouds → providers}/google/bucket.rb +2 -2
  148. data/modules/mu/{clouds → providers}/google/container_cluster.rb +29 -14
  149. data/modules/mu/{clouds → providers}/google/database.rb +2 -9
  150. data/modules/mu/{clouds → providers}/google/firewall_rule.rb +3 -3
  151. data/modules/mu/{clouds → providers}/google/folder.rb +5 -9
  152. data/modules/mu/{clouds → providers}/google/function.rb +4 -4
  153. data/modules/mu/{clouds → providers}/google/group.rb +9 -17
  154. data/modules/mu/{clouds → providers}/google/habitat.rb +4 -8
  155. data/modules/mu/{clouds → providers}/google/loadbalancer.rb +2 -2
  156. data/modules/mu/{clouds → providers}/google/role.rb +46 -35
  157. data/modules/mu/{clouds → providers}/google/server.rb +26 -11
  158. data/modules/mu/{clouds → providers}/google/server_pool.rb +11 -11
  159. data/modules/mu/{clouds → providers}/google/user.rb +32 -22
  160. data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
  161. data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
  162. data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
  163. data/modules/mu/{clouds → providers}/google/vpc.rb +38 -3
  164. data/modules/tests/aws-jobs-functions.yaml +46 -0
  165. data/modules/tests/centos6.yaml +15 -0
  166. data/modules/tests/centos7.yaml +15 -0
  167. data/modules/tests/centos8.yaml +12 -0
  168. data/modules/tests/ecs.yaml +2 -2
  169. data/modules/tests/eks.yaml +1 -1
  170. data/modules/tests/functions/node-function/lambda_function.js +10 -0
  171. data/modules/tests/functions/python-function/lambda_function.py +12 -0
  172. data/modules/tests/microservice_app.yaml +288 -0
  173. data/modules/tests/rds.yaml +108 -0
  174. data/modules/tests/regrooms/rds.yaml +123 -0
  175. data/modules/tests/server-with-scrub-muisms.yaml +1 -1
  176. data/modules/tests/super_complex_bok.yml +2 -2
  177. data/modules/tests/super_simple_bok.yml +2 -2
  178. data/spec/mu/clouds/azure_spec.rb +2 -2
  179. metadata +126 -98
  180. data/modules/mu/clouds/aws/database.rb +0 -1974
  181. data/modules/mu/clouds/aws/endpoint.rb +0 -596
@@ -14,7 +14,7 @@
14
14
 
15
15
  module MU
16
16
  class Config
17
- # Basket of Kittens config schema and parser logic. See modules/mu/clouds/*/nosqldb.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/nosqldb.rb
18
18
  class NoSQLDB
19
19
 
20
20
  # Base configuration schema for a Bucket
@@ -14,7 +14,7 @@
14
14
 
15
15
  module MU
16
16
  class Config
17
- # Basket of Kittens config schema and parser logic. See modules/mu/clouds/*/notifier.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/notifier.rb
18
18
  class Notifier
19
19
 
20
20
  # Base configuration schema for a Notifier
@@ -36,12 +36,12 @@ module MU
36
36
  "items" => {
37
37
  "type" => "object",
38
38
  "description" => "A list of people or resources which should receive notifications",
39
- "required" => ["endpoint"],
40
39
  "properties" => {
41
40
  "endpoint" => {
42
41
  "type" => "string",
43
- "description" => "The endpoint which should be subscribed to this notifier, typically an email address or SMS-enabled phone number."
44
- }
42
+ "description" => "Shorthand for an endpoint which should be subscribed to this notifier, typically an email address or SMS-enabled phone number. For complex cases, such as referencing an AWS Lambda function defined elsewhere in your Mu stack, use +resource+ instead."
43
+ },
44
+ "resource" => MU::Config::Ref.schema(desc: "A cloud resource that is a valid notification target for this notifier. For simple use cases, such as external email addresses or SMS, use +endpoint+ instead.")
45
45
  }
46
46
  }
47
47
  }
@@ -56,23 +56,12 @@ module MU
56
56
  def self.validate(notifier, _configurator)
57
57
  ok = true
58
58
 
59
+
59
60
  if notifier['subscriptions']
60
61
  notifier['subscriptions'].each { |sub|
61
- if !sub["type"]
62
- if sub["endpoint"].match(/^http:/i)
63
- sub["type"] = "http"
64
- elsif sub["endpoint"].match(/^https:/i)
65
- sub["type"] = "https"
66
- elsif sub["endpoint"].match(/^sqs:/i)
67
- sub["type"] = "sqs"
68
- elsif sub["endpoint"].match(/^\+?[\d\-]+$/)
69
- sub["type"] = "sms"
70
- elsif sub["endpoint"].match(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i)
71
- sub["type"] = "email"
72
- else
73
- MU.log "Notifier #{notifier['name']} subscription #{sub['endpoint']} did not specify a type, and I'm unable to guess one", MU::ERR
74
- ok = false
75
- end
62
+ if !sub['endpoint'] and !sub['resource']
63
+ MU.log "Notifier '#{notifier['name']}' must specify either resource or endpoint in subscription", MU::ERR, details: sub
64
+ ok = false
76
65
  end
77
66
  }
78
67
  end
@@ -121,6 +121,10 @@ module MU
121
121
  @deploy_id = @mommacat.deploy_id
122
122
  end
123
123
 
124
+ # canonicalize the 'type' argument
125
+ _shortclass, _cfg_name, cfg_plural, _classname, _attrs = MU::Cloud.getResourceNames(@type, false)
126
+ @type = cfg_plural if cfg_plural
127
+
124
128
  kitten(shallow: true) if @mommacat # try to populate the actual cloud object for this
125
129
  end
126
130
 
@@ -130,10 +134,34 @@ module MU
130
134
  self.to_s <=> other.to_s
131
135
  end
132
136
 
137
+ # Lets callers access us like a {Hash}
138
+ # @param attribute [String,Symbol]
139
+ def [](attribute)
140
+ if respond_to?(attribute.to_sym)
141
+ send(attribute.to_sym)
142
+ else
143
+ nil
144
+ end
145
+ end
146
+
147
+ # Lets callers set attributes like a {Hash}
148
+ # @param attribute [String,Symbol]
149
+ def []=(attribute, value)
150
+ instance_variable_set("@#{attribute.to_s}".to_sym, value)
151
+ self.class.define_reader(attribute)
152
+ end
153
+
154
+ # Unset an attribute. Sort of. We can't actually do that, so nil it out
155
+ # and we get the behavior we want.
156
+ def delete(attribute)
157
+ attribute = ("@"+attribute).to_sym if attribute.to_s !~ /^@/
158
+ instance_variable_set(attribute.to_sym, nil)
159
+ end
160
+
133
161
  # Base configuration schema for declared kittens referencing other cloud objects. This is essentially a set of filters that we're going to pass to {MU::MommaCat.findStray}.
134
162
  # @param aliases [Array<Hash>]: Key => value mappings to set backwards-compatibility aliases for attributes, such as the ubiquitous +vpc_id+ (+vpc_id+ => +id+).
135
163
  # @return [Hash]
136
- def self.schema(aliases = [], type: nil, parent_obj: nil, desc: nil, omit_fields: [])
164
+ def self.schema(aliases = [], type: nil, parent_obj: nil, desc: nil, omit_fields: [], any_type: false)
137
165
  parent_obj ||= caller[1].gsub(/.*?\/([^\.\/]+)\.rb:.*/, '\1')
138
166
  desc ||= "Reference a #{type ? "'#{type}' resource" : "resource" } from this #{parent_obj ? "'#{parent_obj}'" : "" } resource"
139
167
  schema = {
@@ -188,7 +216,9 @@ module MU
188
216
  }
189
217
  end
190
218
 
191
- if !type.nil?
219
+ if any_type
220
+ schema["properties"]["type"].delete("enum")
221
+ elsif !type.nil?
192
222
  schema["required"] = ["type"]
193
223
  schema["properties"]["type"]["default"] = type
194
224
  schema["properties"]["type"]["enum"] = [type]
@@ -208,6 +238,13 @@ module MU
208
238
  schema
209
239
  end
210
240
 
241
+ # Is our +@type+ attribute a Mu-supported type, or some rando string?
242
+ # @return [Boolean]
243
+ def is_mu_type?
244
+ _shortclass, _cfg_name, type, _classname, _attrs = MU::Cloud.getResourceNames(@type, false)
245
+ !type.nil?
246
+ end
247
+
211
248
  # Decompose into a plain-jane {MU::Config::BasketOfKittens} hash fragment,
212
249
  # of the sort that would have been used to declare this reference in the
213
250
  # first place.
@@ -249,8 +286,22 @@ module MU
249
286
  # called in a live deploy, which is to say that if called during initial
250
287
  # configuration parsing, results may be incorrect.
251
288
  # @param mommacat [MU::MommaCat]: A deploy object which will be searched for the referenced resource if provided, before restoring to broader, less efficient searches.
252
- def kitten(mommacat = @mommacat, shallow: false)
253
- return nil if !@cloud or !@type
289
+ def kitten(mommacat = @mommacat, shallow: false, debug: false, cloud: nil)
290
+ cloud ||= @cloud
291
+ return nil if !cloud or !@type
292
+
293
+ _shortclass, _cfg_name, cfg_plural, _classname, _attrs = MU::Cloud.getResourceNames(@type, false)
294
+ if cfg_plural
295
+ @type = cfg_plural # make sure this is the thing we expect
296
+ else
297
+ return nil # we don't do non-muish resources
298
+ end
299
+
300
+ loglevel = debug ? MU::NOTICE : MU::DEBUG
301
+
302
+ if debug
303
+ MU.log "this mf kitten", MU::WARN, details: caller
304
+ end
254
305
 
255
306
  if @obj
256
307
  @deploy_id ||= @obj.deploy_id
@@ -259,8 +310,16 @@ module MU
259
310
  return @obj
260
311
  end
261
312
 
262
- if mommacat
263
- @obj = mommacat.findLitterMate(type: @type, name: @name, cloud_id: @id, credentials: @credentials, debug: false)
313
+ if mommacat and caller.grep(/`findLitterMate'/).empty? # XXX the dumbest
314
+ MU.log "Looking for #{@type} #{@name} #{@id} in deploy #{mommacat.deploy_id}", loglevel
315
+ begin
316
+ @obj = mommacat.findLitterMate(type: @type, name: @name, cloud_id: @id, credentials: @credentials, debug: debug)
317
+ rescue StandardError => e
318
+ if e.message =~ /deadlock/
319
+ MU.log "Saw a recursive deadlock trying to fetch kitten for Ref object in deploy #{mmommacat.deploy_id}", MU::ERR, details: to_h
320
+ end
321
+ raise e
322
+ end
264
323
  if @obj # initialize missing attributes, if we can
265
324
  @id ||= @obj.cloud_id
266
325
  @mommacat ||= mommacat
@@ -283,7 +342,7 @@ end
283
342
  end
284
343
  end
285
344
 
286
- if !@obj and !(@cloud == "Google" and @id and @type == "users" and MU::Cloud::Google::User.cannedServiceAcctName?(@id)) and !shallow
345
+ if !@obj and !(cloud == "Google" and @id and @type == "users" and MU::Cloud.resourceClass("Google", "User").cannedServiceAcctName?(@id)) and !shallow
287
346
  try_deploy_id = @deploy_id
288
347
 
289
348
  begin
@@ -297,8 +356,20 @@ end
297
356
  [@habitat.to_s]
298
357
  end
299
358
 
359
+ MU.log "Ref#kitten calling findStray", loglevel, details: {
360
+ cloud: cloud,
361
+ type: @type,
362
+ name: @name,
363
+ cloud_id: @id,
364
+ deploy_id: try_deploy_id,
365
+ region: @region,
366
+ habitats: hab_arg,
367
+ credentials: @credentials,
368
+ dummy_ok: (["habitats", "folders", "users", "groups", "vpcs"].include?(@type))
369
+ }
370
+
300
371
  found = MU::MommaCat.findStray(
301
- @cloud,
372
+ cloud,
302
373
  @type,
303
374
  name: @name,
304
375
  cloud_id: @id,
@@ -308,10 +379,11 @@ end
308
379
  credentials: @credentials,
309
380
  dummy_ok: (["habitats", "folders", "users", "groups", "vpcs"].include?(@type))
310
381
  )
382
+ MU.log "Ref#kitten results from findStray", loglevel, details: found
311
383
  @obj ||= found.first if found
312
384
  rescue MU::MommaCat::MultipleMatches => e
313
385
  if try_deploy_id.nil? and MU.deploy_id
314
- MU.log "Attempting to narrow down #{@cloud} #{@type} to #{MU.deploy_id}", MU::NOTICE
386
+ MU.log "Attempting to narrow down #{cloud} #{@type} to #{MU.deploy_id}", MU::NOTICE
315
387
  try_deploy_id = MU.deploy_id
316
388
  retry
317
389
  else
@@ -14,7 +14,7 @@
14
14
 
15
15
  module MU
16
16
  class Config
17
- # Basket of Kittens config schema and parser logic. See modules/mu/clouds/*/role.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/role.rb
18
18
  class Role
19
19
 
20
20
  # Base configuration schema for a Group
@@ -22,10 +22,9 @@ module MU
22
22
  def self.defaultCloud
23
23
  configured = {}
24
24
  MU::Cloud.supportedClouds.each { |cloud|
25
- cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
26
25
  if $MU_CFG[cloud.downcase] and !$MU_CFG[cloud.downcase].empty?
27
26
  configured[cloud] = $MU_CFG[cloud.downcase].size
28
- configured[cloud] += 0.5 if cloudclass.hosted? # tiebreaker
27
+ configured[cloud] += 0.5 if MU::Cloud.cloudClass(cloud).hosted? # tiebreaker
29
28
  end
30
29
  }
31
30
  if configured.size > 0
@@ -34,8 +33,7 @@ module MU
34
33
  }.first
35
34
  else
36
35
  MU::Cloud.supportedClouds.each { |cloud|
37
- cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
38
- return cloud if cloudclass.hosted?
36
+ return cloud if MU::Cloud.cloudClass(cloud).hosted?
39
37
  }
40
38
  return MU::Cloud.supportedClouds.first
41
39
  end
@@ -83,9 +81,8 @@ module MU
83
81
  @@loadfails = []
84
82
  MU::Cloud.availableClouds.each { |cloud|
85
83
  next if @@loadfails.include?(cloud)
86
- cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
87
84
  begin
88
- regions = cloudclass.listRegions()
85
+ regions = MU::Cloud.cloudClass(cloud).listRegions()
89
86
  @@allregions.concat(regions) if regions
90
87
  rescue MU::MuError => e
91
88
  @@loadfails << cloud
@@ -100,7 +97,7 @@ module MU
100
97
  @@allregions = []
101
98
  MU::Cloud.availableClouds.each { |cloud|
102
99
  next if @@loadfails.include?(cloud)
103
- cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
100
+ cloudclass = MU::Cloud.cloudClass(cloud)
104
101
  begin
105
102
  return @@allregions if !cloudclass.listRegions()
106
103
  @@allregions.concat(cloudclass.listRegions())
@@ -178,27 +175,27 @@ module MU
178
175
  {
179
176
  "type" => "array",
180
177
  "items" => {
181
- "type" => "object",
182
- "description" => "Declare other objects which this resource requires. This resource will wait until the others are available to create itself.",
183
- "required" => ["name", "type"],
184
- "additionalProperties" => false,
185
- "properties" => {
186
- "name" => {"type" => "string"},
187
- "type" => {
188
- "type" => "string",
189
- "enum" => MU::Cloud.resource_types.values.map { |v| v[:cfg_name] }
190
- },
191
- "phase" => {
192
- "type" => "string",
193
- "description" => "Which part of the creation process of the resource we depend on should we wait for before starting our own creation? Defaults are usually sensible, but sometimes you want, say, a Server to wait on another Server to be completely ready (through its groom phase) before starting up.",
194
- "enum" => ["create", "groom"]
195
- },
196
- "no_create_wait" => {
197
- "type" => "boolean",
198
- "default" => false,
199
- "description" => "By default, it's assumed that we want to wait on our parents' creation phase, in addition to whatever is declared in this stanza. Setting this flag will bypass waiting on our parent resource's creation, so that our create or groom phase can instead depend only on the parent's groom phase. "
200
- }
178
+ "type" => "object",
179
+ "description" => "Declare other objects which this resource requires. This resource will wait until the others are available to create itself.",
180
+ "required" => ["name", "type"],
181
+ "additionalProperties" => false,
182
+ "properties" => {
183
+ "name" => {"type" => "string"},
184
+ "type" => {
185
+ "type" => "string",
186
+ "enum" => MU::Cloud.resource_types.values.map { |v| v[:cfg_name] }
187
+ },
188
+ "phase" => {
189
+ "type" => "string",
190
+ "description" => "Which part of the creation process of the resource we depend on should we wait for before starting our own creation? Defaults are usually sensible, but sometimes you want, say, a Server to wait on another Server to be completely ready (through its groom phase) before starting up.",
191
+ "enum" => ["create", "groom"]
192
+ },
193
+ "no_create_wait" => {
194
+ "type" => "boolean",
195
+ "default" => false,
196
+ "description" => "By default, it's assumed that we want to wait on our parents' creation phase, in addition to whatever is declared in this stanza. Setting this flag will bypass waiting on our parent resource's creation, so that our create or groom phase can instead depend only on the parent's groom phase. "
201
197
  }
198
+ }
202
199
  }
203
200
  }
204
201
  end
@@ -244,7 +241,7 @@ module MU
244
241
  schema["title"] = type.to_s
245
242
 
246
243
  if cloud
247
- cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud).const_get(shortclass)
244
+ cloudclass = MU::Cloud.resourceClass(cloud, type)
248
245
 
249
246
  if cloudclass.respond_to?(:schema)
250
247
  _reqd, cloudschema = cloudclass.schema
@@ -298,11 +295,10 @@ module MU
298
295
  # schema information so that we set those defaults correctly.
299
296
  realschema = if type and schema_chunk["items"] and schema_chunk["items"]["properties"] and item["cloud"] and MU::Cloud.supportedClouds.include?(item['cloud'])
300
297
 
301
- cloudclass = Object.const_get("MU").const_get("Cloud").const_get(item["cloud"]).const_get(type)
302
- _toplevel_required, cloudschema = cloudclass.schema(self)
298
+ _toplevel_required, cloudschema = MU::Cloud.resourceClass(item["cloud"], type).schema(self)
303
299
 
304
300
  newschema = schema_chunk["items"].dup
305
- newschema["properties"].merge!(cloudschema)
301
+ MU::Config.schemaMerge(newschema["properties"], cloudschema, item["cloud"])
306
302
  newschema
307
303
  else
308
304
  schema_chunk["items"].dup
@@ -339,9 +335,9 @@ module MU
339
335
  return
340
336
  end
341
337
 
342
- cloudclass = Object.const_get("MU").const_get("Cloud").const_get(kitten['cloud'])
343
- shortclass, _cfg_name, _cfg_plural, _classname = MU::Cloud.getResourceNames(type)
344
- resclass = Object.const_get("MU").const_get("Cloud").const_get(kitten['cloud']).const_get(shortclass)
338
+ cloudclass = MU::Cloud.cloudClass(kitten['cloud'])
339
+
340
+ resclass = MU::Cloud.resourceClass(kitten['cloud'], type)
345
341
 
346
342
  schema_fields = ["us_only", "scrub_mu_isms", "credentials", "billing_acct"]
347
343
  if !resclass.isGlobal?
@@ -14,7 +14,7 @@
14
14
 
15
15
  module MU
16
16
  class Config
17
- # Basket of Kittens config schema and parser logic. See modules/mu/clouds/*/search_domain.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/search_domain.rb
18
18
  class SearchDomain
19
19
 
20
20
  # Base configuration schema for a SearchDomain
@@ -14,7 +14,7 @@
14
14
 
15
15
  module MU
16
16
  class Config
17
- # Basket of Kittens config schema and parser logic. See modules/mu/clouds/*/server.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/server.rb
18
18
  class Server
19
19
 
20
20
  # Verify that a server or server_pool has a valid LDAP config referencing
@@ -546,7 +546,7 @@ module MU
546
546
  "additionalProperties" => false,
547
547
  "description" => "Create individual server instances.",
548
548
  "properties" => {
549
- "dns_records" => MU::Config::DNSZone.records_primitive(need_target: false, default_type: "A", need_zone: true),
549
+ "dns_records" => MU::Config::DNSZone.records_primitive(need_target: false, default_type: "A", need_zone: true, embedded_type: "server"),
550
550
  "bastion" => {
551
551
  "type" => "boolean",
552
552
  "default" => false,
@@ -650,20 +650,12 @@ module MU
650
650
  end
651
651
 
652
652
  if !server["vpc"]["subnet_name"].nil? and configurator.nat_routes.has_key?(server["vpc"]["subnet_name"]) and !configurator.nat_routes[server["vpc"]["subnet_name"]].empty?
653
- server["dependencies"] << {
654
- "type" => "server",
655
- "name" => configurator.nat_routes[server["vpc"]["subnet_name"]],
656
- "phase" => "groom"
657
- }
653
+ MU::Config.addDependency(server, configurator.nat_routes[server["vpc"]["subnet_name"]], "server", phase: "groom", no_create_wait: true)
658
654
  elsif !server["vpc"]["name"].nil?
659
655
  siblingvpc = configurator.haveLitterMate?(server["vpc"]["name"], "vpcs")
660
656
  if siblingvpc and siblingvpc['bastion'] and
661
- server['name'] != siblingvpc['bastion'].to_h['name']
662
- server["dependencies"] << {
663
- "type" => "server",
664
- "name" => siblingvpc['bastion'].to_h['name'],
665
- "phase" => "groom"
666
- }
657
+ server['name'] != siblingvpc['bastion']['name']
658
+ MU::Config.addDependency(server, siblingvpc['bastion']['name'], "server", phase: "groom", no_create_wait: true)
667
659
  end
668
660
  end
669
661
  end
@@ -14,7 +14,7 @@
14
14
 
15
15
  module MU
16
16
  class Config
17
- # Basket of Kittens config schema and parser logic. See modules/mu/clouds/*/server_pool.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/server_pool.rb
18
18
  class ServerPool
19
19
 
20
20
  # Base configuration schema for a ServerPool
@@ -186,11 +186,7 @@ module MU
186
186
 
187
187
  if !pool["vpc"].nil?
188
188
  if !pool["vpc"]["subnet_name"].nil? and configurator.nat_routes.has_key?(pool["vpc"]["subnet_name"])
189
- pool["dependencies"] << {
190
- "type" => "pool",
191
- "name" => configurator.nat_routes[pool["vpc"]["subnet_name"]],
192
- "phase" => "groom"
193
- }
189
+ MU::Config.addDependency(pool, configurator.nat_routes[pool["vpc"]["subnet_name"]], "server", phase: "groom", no_create_wait: true)
194
190
  end
195
191
  end
196
192
  # TODO make sure this is handled... somewhere
@@ -203,7 +199,7 @@ module MU
203
199
  # }
204
200
  # end
205
201
  if pool["basis"] and pool["basis"]["server"]
206
- pool["dependencies"] << {"type" => "server", "name" => pool["basis"]["server"]}
202
+ MU::Config.addDependency(pool, pool["basis"]["server"], "server", phase: "groom")
207
203
  end
208
204
  if !pool['static_ip'].nil? and !pool['ip'].nil?
209
205
  ok = false
@@ -14,7 +14,7 @@
14
14
 
15
15
  module MU
16
16
  class Config
17
- # Basket of Kittens config schema and parser logic. See modules/mu/clouds/*/storage_pool.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/storage_pool.rb
18
18
  class StoragePool
19
19
 
20
20
  # Base configuration schema for a StoragePool
@@ -117,6 +117,16 @@ module MU
117
117
  def gsub(*args)
118
118
  to_s.gsub(*args)
119
119
  end
120
+
121
+ # Lets callers access us like a {Hash}
122
+ # @param attribute [String,Symbol]
123
+ def [](attribute)
124
+ if respond_to?(attribute.to_sym)
125
+ send(attribute.to_sym)
126
+ else
127
+ nil
128
+ end
129
+ end
120
130
  end
121
131
 
122
132
  # Wrapper method for creating a {MU::Config::Tail} object as a reference to