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.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +15 -3
  3. data/ansible/roles/mu-windows/README.md +33 -0
  4. data/ansible/roles/mu-windows/defaults/main.yml +2 -0
  5. data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
  6. data/ansible/roles/mu-windows/files/config.xml +76 -0
  7. data/ansible/roles/mu-windows/handlers/main.yml +2 -0
  8. data/ansible/roles/mu-windows/meta/main.yml +53 -0
  9. data/ansible/roles/mu-windows/tasks/main.yml +36 -0
  10. data/ansible/roles/mu-windows/tests/inventory +2 -0
  11. data/ansible/roles/mu-windows/tests/test.yml +5 -0
  12. data/ansible/roles/mu-windows/vars/main.yml +2 -0
  13. data/bin/mu-adopt +21 -13
  14. data/bin/mu-azure-tests +57 -0
  15. data/bin/mu-cleanup +2 -4
  16. data/bin/mu-configure +52 -0
  17. data/bin/mu-deploy +3 -3
  18. data/bin/mu-findstray-tests +25 -0
  19. data/bin/mu-gen-docs +2 -4
  20. data/bin/mu-load-config.rb +4 -4
  21. data/bin/mu-node-manage +15 -16
  22. data/bin/mu-run-tests +147 -37
  23. data/cloud-mu.gemspec +22 -20
  24. data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
  25. data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
  26. data/cookbooks/mu-tools/libraries/helper.rb +3 -2
  27. data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
  28. data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
  29. data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
  30. data/cookbooks/mu-tools/recipes/eks.rb +2 -2
  31. data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
  32. data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
  33. data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
  34. data/cookbooks/mu-tools/resources/disk.rb +1 -1
  35. data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
  36. data/extras/clean-stock-amis +25 -19
  37. data/extras/generate-stock-images +1 -0
  38. data/extras/image-generators/AWS/win2k12.yaml +18 -13
  39. data/extras/image-generators/AWS/win2k16.yaml +18 -13
  40. data/extras/image-generators/AWS/win2k19.yaml +21 -0
  41. data/extras/image-generators/Google/centos6.yaml +1 -0
  42. data/extras/image-generators/Google/centos7.yaml +1 -1
  43. data/modules/mommacat.ru +6 -16
  44. data/modules/mu.rb +158 -111
  45. data/modules/mu/adoption.rb +404 -71
  46. data/modules/mu/cleanup.rb +221 -306
  47. data/modules/mu/cloud.rb +129 -1633
  48. data/modules/mu/cloud/database.rb +49 -0
  49. data/modules/mu/cloud/dnszone.rb +44 -0
  50. data/modules/mu/cloud/machine_images.rb +212 -0
  51. data/modules/mu/cloud/providers.rb +81 -0
  52. data/modules/mu/cloud/resource_base.rb +926 -0
  53. data/modules/mu/cloud/server.rb +40 -0
  54. data/modules/mu/cloud/server_pool.rb +1 -0
  55. data/modules/mu/cloud/ssh_sessions.rb +228 -0
  56. data/modules/mu/cloud/winrm_sessions.rb +237 -0
  57. data/modules/mu/cloud/wrappers.rb +169 -0
  58. data/modules/mu/config.rb +171 -1767
  59. data/modules/mu/config/alarm.rb +2 -6
  60. data/modules/mu/config/bucket.rb +32 -3
  61. data/modules/mu/config/cache_cluster.rb +2 -2
  62. data/modules/mu/config/cdn.rb +100 -0
  63. data/modules/mu/config/collection.rb +4 -4
  64. data/modules/mu/config/container_cluster.rb +9 -4
  65. data/modules/mu/config/database.rb +84 -105
  66. data/modules/mu/config/database.yml +1 -2
  67. data/modules/mu/config/dnszone.rb +10 -9
  68. data/modules/mu/config/doc_helpers.rb +516 -0
  69. data/modules/mu/config/endpoint.rb +5 -4
  70. data/modules/mu/config/firewall_rule.rb +103 -4
  71. data/modules/mu/config/folder.rb +4 -4
  72. data/modules/mu/config/function.rb +19 -10
  73. data/modules/mu/config/group.rb +4 -4
  74. data/modules/mu/config/habitat.rb +4 -4
  75. data/modules/mu/config/job.rb +89 -0
  76. data/modules/mu/config/loadbalancer.rb +60 -14
  77. data/modules/mu/config/log.rb +4 -4
  78. data/modules/mu/config/msg_queue.rb +4 -4
  79. data/modules/mu/config/nosqldb.rb +4 -4
  80. data/modules/mu/config/notifier.rb +10 -21
  81. data/modules/mu/config/ref.rb +411 -0
  82. data/modules/mu/config/role.rb +4 -4
  83. data/modules/mu/config/schema_helpers.rb +509 -0
  84. data/modules/mu/config/search_domain.rb +4 -4
  85. data/modules/mu/config/server.rb +98 -71
  86. data/modules/mu/config/server.yml +1 -0
  87. data/modules/mu/config/server_pool.rb +5 -9
  88. data/modules/mu/config/storage_pool.rb +1 -1
  89. data/modules/mu/config/tail.rb +200 -0
  90. data/modules/mu/config/user.rb +4 -4
  91. data/modules/mu/config/vpc.rb +71 -27
  92. data/modules/mu/config/vpc.yml +0 -1
  93. data/modules/mu/defaults/AWS.yaml +91 -68
  94. data/modules/mu/defaults/Azure.yaml +1 -0
  95. data/modules/mu/defaults/Google.yaml +3 -2
  96. data/modules/mu/deploy.rb +43 -26
  97. data/modules/mu/groomer.rb +17 -2
  98. data/modules/mu/groomers/ansible.rb +188 -41
  99. data/modules/mu/groomers/chef.rb +116 -55
  100. data/modules/mu/logger.rb +127 -148
  101. data/modules/mu/master.rb +410 -2
  102. data/modules/mu/master/chef.rb +3 -4
  103. data/modules/mu/master/ldap.rb +3 -3
  104. data/modules/mu/master/ssl.rb +12 -3
  105. data/modules/mu/mommacat.rb +218 -2612
  106. data/modules/mu/mommacat/daemon.rb +403 -0
  107. data/modules/mu/mommacat/naming.rb +473 -0
  108. data/modules/mu/mommacat/search.rb +495 -0
  109. data/modules/mu/mommacat/storage.rb +722 -0
  110. data/modules/mu/{clouds → providers}/README.md +1 -1
  111. data/modules/mu/{clouds → providers}/aws.rb +380 -122
  112. data/modules/mu/{clouds → providers}/aws/alarm.rb +7 -5
  113. data/modules/mu/{clouds → providers}/aws/bucket.rb +297 -59
  114. data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +37 -71
  115. data/modules/mu/providers/aws/cdn.rb +782 -0
  116. data/modules/mu/{clouds → providers}/aws/collection.rb +26 -25
  117. data/modules/mu/{clouds → providers}/aws/container_cluster.rb +724 -744
  118. data/modules/mu/providers/aws/database.rb +1744 -0
  119. data/modules/mu/{clouds → providers}/aws/dnszone.rb +88 -70
  120. data/modules/mu/providers/aws/endpoint.rb +1072 -0
  121. data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +220 -247
  122. data/modules/mu/{clouds → providers}/aws/folder.rb +8 -8
  123. data/modules/mu/{clouds → providers}/aws/function.rb +300 -142
  124. data/modules/mu/{clouds → providers}/aws/group.rb +31 -29
  125. data/modules/mu/{clouds → providers}/aws/habitat.rb +18 -15
  126. data/modules/mu/providers/aws/job.rb +466 -0
  127. data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +66 -56
  128. data/modules/mu/{clouds → providers}/aws/log.rb +17 -14
  129. data/modules/mu/{clouds → providers}/aws/msg_queue.rb +29 -19
  130. data/modules/mu/{clouds → providers}/aws/nosqldb.rb +114 -16
  131. data/modules/mu/{clouds → providers}/aws/notifier.rb +142 -65
  132. data/modules/mu/{clouds → providers}/aws/role.rb +158 -118
  133. data/modules/mu/{clouds → providers}/aws/search_domain.rb +201 -59
  134. data/modules/mu/{clouds → providers}/aws/server.rb +844 -1139
  135. data/modules/mu/{clouds → providers}/aws/server_pool.rb +74 -65
  136. data/modules/mu/{clouds → providers}/aws/storage_pool.rb +26 -44
  137. data/modules/mu/{clouds → providers}/aws/user.rb +24 -25
  138. data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
  139. data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +5 -4
  140. data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
  141. data/modules/mu/{clouds → providers}/aws/vpc.rb +525 -931
  142. data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
  143. data/modules/mu/{clouds → providers}/azure.rb +29 -9
  144. data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
  145. data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
  146. data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
  147. data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
  148. data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
  149. data/modules/mu/{clouds → providers}/azure/server.rb +97 -49
  150. data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
  151. data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
  152. data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
  153. data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
  154. data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
  155. data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
  156. data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
  157. data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
  158. data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
  159. data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
  160. data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
  161. data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
  162. data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
  163. data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
  164. data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
  165. data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
  166. data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
  167. data/modules/mu/{clouds → providers}/docker.rb +0 -0
  168. data/modules/mu/{clouds → providers}/google.rb +68 -30
  169. data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
  170. data/modules/mu/{clouds → providers}/google/container_cluster.rb +85 -78
  171. data/modules/mu/{clouds → providers}/google/database.rb +11 -21
  172. data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
  173. data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
  174. data/modules/mu/{clouds → providers}/google/function.rb +140 -168
  175. data/modules/mu/{clouds → providers}/google/group.rb +29 -34
  176. data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
  177. data/modules/mu/{clouds → providers}/google/loadbalancer.rb +19 -21
  178. data/modules/mu/{clouds → providers}/google/role.rb +94 -58
  179. data/modules/mu/{clouds → providers}/google/server.rb +243 -156
  180. data/modules/mu/{clouds → providers}/google/server_pool.rb +26 -45
  181. data/modules/mu/{clouds → providers}/google/user.rb +95 -31
  182. data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
  183. data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
  184. data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
  185. data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
  186. data/modules/tests/aws-jobs-functions.yaml +46 -0
  187. data/modules/tests/bucket.yml +4 -0
  188. data/modules/tests/centos6.yaml +15 -0
  189. data/modules/tests/centos7.yaml +15 -0
  190. data/modules/tests/centos8.yaml +12 -0
  191. data/modules/tests/ecs.yaml +23 -0
  192. data/modules/tests/eks.yaml +1 -1
  193. data/modules/tests/functions/node-function/lambda_function.js +10 -0
  194. data/modules/tests/functions/python-function/lambda_function.py +12 -0
  195. data/modules/tests/includes-and-params.yaml +2 -1
  196. data/modules/tests/microservice_app.yaml +288 -0
  197. data/modules/tests/rds.yaml +108 -0
  198. data/modules/tests/regrooms/aws-iam.yaml +201 -0
  199. data/modules/tests/regrooms/bucket.yml +19 -0
  200. data/modules/tests/regrooms/rds.yaml +123 -0
  201. data/modules/tests/server-with-scrub-muisms.yaml +2 -1
  202. data/modules/tests/super_complex_bok.yml +2 -2
  203. data/modules/tests/super_simple_bok.yml +3 -5
  204. data/modules/tests/win2k12.yaml +17 -5
  205. data/modules/tests/win2k16.yaml +25 -0
  206. data/modules/tests/win2k19.yaml +25 -0
  207. data/requirements.txt +1 -0
  208. data/spec/mu/clouds/azure_spec.rb +2 -2
  209. metadata +240 -154
  210. data/extras/image-generators/AWS/windows.yaml +0 -18
  211. data/modules/mu/clouds/aws/database.rb +0 -1985
  212. data/modules/mu/clouds/aws/endpoint.rb +0 -592
@@ -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
@@ -47,10 +47,10 @@ module MU
47
47
  end
48
48
 
49
49
  # Generic pre-processing of {MU::Config::BasketofKittens::search_domains}, bare and unvalidated.
50
- # @param dom [Hash]: The resource to process and validate
51
- # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
50
+ # @param _dom [Hash]: The resource to process and validate
51
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
52
52
  # @return [Boolean]: True if validation succeeded, False otherwise
53
- def self.validate(dom, configurator)
53
+ def self.validate(_dom, _configurator)
54
54
  ok = true
55
55
  # This resource basically only exists in AWS, so the validation lives
56
56
  # there. If some other provider comes up with it we can factor
@@ -14,9 +14,68 @@
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
+ # Verify that a server or server_pool has a valid LDAP config referencing
21
+ # valid Vaults for credentials.
22
+ # @param server [Hash]
23
+ def self.checkVaultRefs(server)
24
+ ok = true
25
+ server['vault_access'] = [] if server['vault_access'].nil?
26
+ server['groomer'] ||= self.defaultGroomer
27
+ groomclass = MU::Groomer.loadGroomer(server['groomer'])
28
+
29
+ begin
30
+ if !server['active_directory'].nil?
31
+ ["domain_admin_vault", "domain_join_vault"].each { |vault_class|
32
+ server['vault_access'] << {
33
+ "vault" => server['active_directory'][vault_class]['vault'],
34
+ "item" => server['active_directory'][vault_class]['item']
35
+ }
36
+ item = groomclass.getSecret(
37
+ vault: server['active_directory'][vault_class]['vault'],
38
+ item: server['active_directory'][vault_class]['item'],
39
+ )
40
+ ["username_field", "password_field"].each { |field|
41
+ if !item.has_key?(server['active_directory'][vault_class][field])
42
+ ok = false
43
+ MU.log "I don't see a value named #{field} in Chef Vault #{server['active_directory'][vault_class]['vault']}:#{server['active_directory'][vault_class]['item']}", MU::ERR
44
+ end
45
+ }
46
+ }
47
+ end
48
+
49
+ if !server['windows_auth_vault'].nil?
50
+ server['use_cloud_provider_windows_password'] = false
51
+
52
+ server['vault_access'] << {
53
+ "vault" => server['windows_auth_vault']['vault'],
54
+ "item" => server['windows_auth_vault']['item']
55
+ }
56
+ item = groomclass.getSecret(
57
+ vault: server['windows_auth_vault']['vault'],
58
+ item: server['windows_auth_vault']['item']
59
+ )
60
+ ["password_field", "ec2config_password_field", "sshd_password_field"].each { |field|
61
+ if !item.has_key?(server['windows_auth_vault'][field])
62
+ MU.log "No value named #{field} in Chef Vault #{server['windows_auth_vault']['vault']}:#{server['windows_auth_vault']['item']}, will use a generated password.", MU::NOTICE
63
+ server['windows_auth_vault'].delete(field)
64
+ end
65
+ }
66
+ end
67
+ # Check all of the non-special ones while we're at it
68
+ server['vault_access'].each { |v|
69
+ next if v['vault'] == "splunk" and v['item'] == "admin_user"
70
+ item = groomclass.getSecret(vault: v['vault'], item: v['item'])
71
+ }
72
+ rescue MuError
73
+ MU.log "Can't load a Chef Vault I was configured to use. Does it exist?", MU::ERR
74
+ ok = false
75
+ end
76
+ return ok
77
+ end
78
+
20
79
  # Generate schema for a storage volume
21
80
  # @return [Hash]
22
81
  def self.storage_primitive
@@ -332,9 +391,8 @@ module MU
332
391
  },
333
392
  "userdata_script" => userdata_primitive,
334
393
  "windows_admin_username" => {
335
- "type" => "string",
336
- "default" => "Administrator",
337
- "description" => "Use an alternate Windows account for Administrator functions. Will change the name of the Administrator account, if it has not already been done."
394
+ "type" => "string",
395
+ "description" => "Use an alternate Windows account for Administrator functions. Will change the name of the Administrator account, if it has not already been done."
338
396
  },
339
397
  "windows_auth_vault" => {
340
398
  "type" => "object",
@@ -370,60 +428,30 @@ module MU
370
428
  }
371
429
  },
372
430
  "ssh_user" => {
373
- "type" => "string",
374
- "default" => "root",
375
- "default_if" => [
376
- {
377
- "key_is" => "platform",
378
- "value_is" => "windows",
379
- "set" => "Administrator"
380
- },
381
- {
382
- "key_is" => "platform",
383
- "value_is" => "win2k12",
384
- "set" => "Administrator"
385
- },
386
- {
387
- "key_is" => "platform",
388
- "value_is" => "win2k12r2",
389
- "set" => "Administrator"
390
- },
391
- {
392
- "key_is" => "platform",
393
- "value_is" => "win2k16",
394
- "set" => "Administrator"
395
- },
396
- {
397
- "key_is" => "platform",
398
- "value_is" => "ubuntu",
399
- "set" => "ubuntu"
400
- },
401
- {
402
- "key_is" => "platform",
403
- "value_is" => "ubuntu14",
404
- "set" => "ubuntu"
405
- },
406
- {
407
- "key_is" => "platform",
408
- "value_is" => "centos7",
409
- "set" => "centos"
410
- },
411
- {
412
- "key_is" => "platform",
413
- "value_is" => "rhel7",
414
- "set" => "ec2-user"
415
- },
416
- {
417
- "key_is" => "platform",
418
- "value_is" => "rhel71",
419
- "set" => "ec2-user"
420
- },
421
- {
422
- "key_is" => "platform",
423
- "value_is" => "amazon",
424
- "set" => "ec2-user"
425
- }
426
- ]
431
+ "type" => "string",
432
+ "default" => "root",
433
+ "default_if" => [
434
+ {
435
+ "key_is" => "platform",
436
+ "value_is" => "centos",
437
+ "set" => "centos"
438
+ },
439
+ {
440
+ "key_is" => "platform",
441
+ "value_is" => "centos6",
442
+ "set" => "centos"
443
+ },
444
+ {
445
+ "key_is" => "platform",
446
+ "value_is" => "centos7",
447
+ "set" => "centos"
448
+ },
449
+ {
450
+ "key_is" => "platform",
451
+ "value_is" => "centos8",
452
+ "set" => "centos"
453
+ }
454
+ ]
427
455
  },
428
456
  "use_cloud_provider_windows_password" => {
429
457
  "type" => "boolean",
@@ -518,7 +546,7 @@ module MU
518
546
  "additionalProperties" => false,
519
547
  "description" => "Create individual server instances.",
520
548
  "properties" => {
521
- "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"),
522
550
  "bastion" => {
523
551
  "type" => "boolean",
524
552
  "default" => false,
@@ -595,7 +623,14 @@ module MU
595
623
  server['ingress_rules'] ||= []
596
624
  server['vault_access'] ||= []
597
625
  server['vault_access'] << {"vault" => "splunk", "item" => "admin_user"}
598
- ok = false if !MU::Config.check_vault_refs(server)
626
+ ok = false if !MU::Config::Server.checkVaultRefs(server)
627
+
628
+ server['groomer'] ||= self.defaultGroomer
629
+ groomclass = MU::Groomer.loadGroomer(server['groomer'])
630
+ if !groomclass.available?(server['platform'].match(/^win/))
631
+ MU.log "Groomer #{server['groomer']} for #{server['name']} is missing or has incomplete dependencies", MU::ERR
632
+ ok = false
633
+ end
599
634
 
600
635
  if server["cloud"] != "Azure"
601
636
  server['dependencies'] << configurator.adminFirewallRuleset(vpc: server['vpc'], region: server['region'], cloud: server['cloud'], credentials: server['credentials'])
@@ -615,20 +650,12 @@ module MU
615
650
  end
616
651
 
617
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?
618
- server["dependencies"] << {
619
- "type" => "server",
620
- "name" => configurator.nat_routes[server["vpc"]["subnet_name"]],
621
- "phase" => "groom"
622
- }
653
+ MU::Config.addDependency(server, configurator.nat_routes[server["vpc"]["subnet_name"]], "server", phase: "groom", no_create_wait: true)
623
654
  elsif !server["vpc"]["name"].nil?
624
655
  siblingvpc = configurator.haveLitterMate?(server["vpc"]["name"], "vpcs")
625
656
  if siblingvpc and siblingvpc['bastion'] and
626
- server['name'] != siblingvpc['bastion'].to_h['name']
627
- server["dependencies"] << {
628
- "type" => "server",
629
- "name" => siblingvpc['bastion'].to_h['name'],
630
- "phase" => "groom"
631
- }
657
+ server['name'] != siblingvpc['bastion']['name']
658
+ MU::Config.addDependency(server, siblingvpc['bastion']['name'], "server", phase: "groom", no_create_wait: true)
632
659
  end
633
660
  end
634
661
  end
@@ -7,6 +7,7 @@ vpc:
7
7
  platform: ubuntu
8
8
  ssh_user: ubuntu
9
9
  associate_public_ip: true
10
+ add_private_ips: 3
10
11
  canned_iam_policies:
11
12
  - AmazonDynamoDBReadOnlyAccess
12
13
  - AmazonElastiCacheFullAccess
@@ -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
@@ -178,7 +178,7 @@ module MU
178
178
  pool['ingress_rules'] ||= []
179
179
  pool['vault_access'] ||= []
180
180
  pool['vault_access'] << {"vault" => "splunk", "item" => "admin_user"}
181
- ok = false if !MU::Config.check_vault_refs(pool)
181
+ ok = false if !MU::Config::Server.checkVaultRefs(pool)
182
182
 
183
183
  if !pool['scrub_mu_isms'] and pool["cloud"] != "Azure"
184
184
  pool['dependencies'] << configurator.adminFirewallRuleset(vpc: pool['vpc'], region: pool['region'], cloud: pool['cloud'], credentials: pool['credentials'])
@@ -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
@@ -202,8 +198,8 @@ module MU
202
198
  # ok = false if !insertKitten(alarm, "alarms")
203
199
  # }
204
200
  # end
205
- if pool["basis"]["server"] != nil
206
- pool["dependencies"] << {"type" => "server", "name" => pool["basis"]["server"]}
201
+ if pool["basis"] and 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
@@ -0,0 +1,200 @@
1
+ # Copyright:: Copyright (c) 2020 eGlobalTech, Inc., all rights reserved
2
+ #
3
+ # Licensed under the BSD-3 license (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License in the root of the project or at
6
+ #
7
+ # http://egt-labs.com/mu/LICENSE.html
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module MU
16
+
17
+ # Methods and structures for parsing Mu's configuration files. See also {MU::Config::BasketofKittens}.
18
+ class Config
19
+
20
+ # A wrapper for config leaves that came from ERB parameters instead of raw
21
+ # YAML or JSON. Will behave like a string for things that expect that
22
+ # sort of thing. Code that needs to know that this leaf was the result of
23
+ # a parameter will be able to tell by the object class being something
24
+ # other than a plain string, array, or hash.
25
+ class Tail
26
+ @value = nil
27
+ @name = nil
28
+ @prettyname = nil
29
+ @description = nil
30
+ @prefix = ""
31
+ @suffix = ""
32
+ @is_list_element = false
33
+ @pseudo = false
34
+ @runtimecode = nil
35
+ @valid_values = []
36
+ @index = 0
37
+ attr_reader :description
38
+ attr_reader :pseudo
39
+ attr_reader :index
40
+ attr_reader :value
41
+ attr_reader :runtimecode
42
+ attr_reader :valid_values
43
+ attr_reader :is_list_element
44
+
45
+ def initialize(name, value, prettyname = nil, cloudtype = "String", valid_values = [], description = "", is_list_element = false, prefix: "", suffix: "", pseudo: false, runtimecode: nil, index: 0)
46
+ @name = name
47
+ @bindings = {}
48
+ @value = value
49
+ @valid_values = valid_values
50
+ @pseudo = pseudo
51
+ @index = index
52
+ @runtimecode = runtimecode
53
+ @cloudtype = cloudtype
54
+ @is_list_element = is_list_element
55
+ @description ||=
56
+ if !description.nil?
57
+ description
58
+ else
59
+ ""
60
+ end
61
+ @prettyname ||=
62
+ if !prettyname.nil?
63
+ prettyname
64
+ else
65
+ @name.capitalize.gsub(/[^a-z0-9]/i, "")
66
+ end
67
+ @prefix = prefix if !prefix.nil?
68
+ @suffix = suffix if !suffix.nil?
69
+ end
70
+
71
+ # Return the parameter name of this Tail
72
+ def getName
73
+ @name
74
+ end
75
+ # Return the platform-specific cloud type of this Tail
76
+ def getCloudType
77
+ @cloudtype
78
+ end
79
+ # Return the human-friendly name of this Tail
80
+ def getPrettyName
81
+ @prettyname
82
+ end
83
+ # Walk like a String
84
+ def to_s
85
+ @prefix.to_s+@value.to_s+@suffix.to_s
86
+ end
87
+ # Quack like a String
88
+ def to_str
89
+ to_s
90
+ end
91
+ # Upcase like a String
92
+ def upcase
93
+ to_s.upcase
94
+ end
95
+ # Downcase like a String
96
+ def downcase
97
+ to_s.downcase
98
+ end
99
+ # Check for emptiness like a String
100
+ def empty?
101
+ to_s.empty?
102
+ end
103
+ # Match like a String
104
+ def match(*args)
105
+ to_s.match(*args)
106
+ end
107
+ # Check for equality like a String
108
+ def ==(o)
109
+ (o.class == self.class or o.class == "String") && o.to_s == to_s
110
+ end
111
+ # Concatenate like a string
112
+ def +(o)
113
+ return to_s if o.nil?
114
+ to_s + o.to_s
115
+ end
116
+ # Perform global substitutions like a String
117
+ def gsub(*args)
118
+ to_s.gsub(*args)
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
130
+ end
131
+
132
+ # Wrapper method for creating a {MU::Config::Tail} object as a reference to
133
+ # a parameter that's valid in the loaded configuration.
134
+ # @param param [<String>]: The name of the parameter to which this should be tied.
135
+ # @param value [<String>]: The value of the parameter to return when asked
136
+ # @param prettyname [<String>]: A human-friendly parameter name to be used when generating CloudFormation templates and the like
137
+ # @param cloudtype [<String>]: A platform-specific identifier used by cloud layers to identify a parameter's type, e.g. AWS::EC2::VPC::Id
138
+ # @param valid_values [Array<String>]: A list of acceptable String values for the given parameter.
139
+ # @param description [<String>]: A long-form description of what the parameter does.
140
+ # @param list_of [<String>]: Indicates that the value should be treated as a member of a list (array) by the cloud layer.
141
+ # @param prefix [<String>]: A static String that should be prefixed to the stored value when queried
142
+ # @param suffix [<String>]: A static String that should be appended to the stored value when queried
143
+ # @param pseudo [<Boolean>]: This is a pseudo-parameter, automatically provided, and not available as user input.
144
+ # @param runtimecode [<String>]: Actual code to allow the cloud layer to interpret literally in its own idiom, e.g. '"Ref" : "AWS::StackName"' for CloudFormation
145
+ def getTail(param, value: nil, prettyname: nil, cloudtype: "String", valid_values: [], description: nil, list_of: nil, prefix: "", suffix: "", pseudo: false, runtimecode: nil)
146
+ param = param.gsub(/[^a-z0-9_]/i, "_")
147
+ if value.nil?
148
+ if @@parameters.nil? or !@@parameters.has_key?(param)
149
+ MU.log "Parameter '#{param}' (#{param.class.name}) referenced in config but not provided (#{caller[0]})", MU::DEBUG, details: @@parameters
150
+ return nil
151
+ # raise DeployParamError
152
+ else
153
+ value = @@parameters[param]
154
+ end
155
+ end
156
+ if !prettyname.nil?
157
+ prettyname.gsub!(/[^a-z0-9]/i, "") # comply with CloudFormation restrictions
158
+ end
159
+ if value.is_a?(MU::Config::Tail)
160
+ MU.log "Parameter #{param} is using a nested parameter as a value. This rarely works, depending on the target cloud. YMMV.", MU::WARN
161
+ tail = MU::Config::Tail.new(param, value, prettyname, cloudtype, valid_values, description, prefix: prefix, suffix: suffix, pseudo: pseudo, runtimecode: runtimecode)
162
+ elsif !list_of.nil? or (@@tails.has_key?(param) and @@tails[param].is_a?(Array))
163
+ tail = []
164
+ count = 0
165
+ value.split(/\s*,\s*/).each { |subval|
166
+ if @@tails.has_key?(param) and !@@tails[param][count].nil?
167
+ subval = @@tails[param][count].values.first.to_s if subval.nil?
168
+ list_of = @@tails[param][count].values.first.getName if list_of.nil?
169
+ prettyname = @@tails[param][count].values.first.getPrettyName if prettyname.nil?
170
+ description = @@tails[param][count].values.first.description if description.nil?
171
+ valid_values = @@tails[param][count].values.first.valid_values if valid_values.nil? or valid_values.empty?
172
+ cloudtype = @@tails[param][count].values.first.getCloudType if @@tails[param][count].values.first.getCloudType != "String"
173
+ end
174
+ prettyname = param.capitalize if prettyname.nil?
175
+ tail << { list_of => MU::Config::Tail.new(list_of, subval, prettyname, cloudtype, valid_values, description, true, pseudo: pseudo, index: count) }
176
+ count = count + 1
177
+ }
178
+ else
179
+ if @@tails.has_key?(param)
180
+ pseudo = @@tails[param].pseudo
181
+ value = @@tails[param].to_s if value.nil?
182
+ prettyname = @@tails[param].getPrettyName if prettyname.nil?
183
+ description = @@tails[param].description if description.nil?
184
+ valid_values = @@tails[param].valid_values if valid_values.nil? or valid_values.empty?
185
+ cloudtype = @@tails[param].getCloudType if @@tails[param].getCloudType != "String"
186
+ end
187
+ tail = MU::Config::Tail.new(param, value, prettyname, cloudtype, valid_values, description, prefix: prefix, suffix: suffix, pseudo: pseudo, runtimecode: runtimecode)
188
+ end
189
+
190
+ if valid_values and valid_values.size > 0 and value
191
+ if !valid_values.include?(value)
192
+ raise DeployParamError, "Invalid parameter value '#{value}' supplied for '#{param}'"
193
+ end
194
+ end
195
+ @@tails[param] = tail
196
+
197
+ tail
198
+ end
199
+ end
200
+ end