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/*/api.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/api.rb
18
18
  class Endpoint
19
19
 
20
20
  # Base configuration schema for an Endpoint (e.g. AWS API Gateway)
@@ -32,6 +32,7 @@ module MU
32
32
  "iam_role" => {"type" => "string"},
33
33
  "region" => MU::Config.region_primitive,
34
34
  "vpc" => MU::Config::VPC.reference(MU::Config::VPC::NO_SUBNETS, MU::Config::VPC::NO_NAT_OPTS),
35
+ "dns_records" => MU::Config::DNSZone.records_primitive(need_target: false, default_type: "CNAME", need_zone: true, embedded_type: "endpoint"),
35
36
  "methods" => {
36
37
  "type" => "array",
37
38
  "items" => {
@@ -57,10 +58,10 @@ module MU
57
58
  end
58
59
 
59
60
  # Generic pre-processing of {MU::Config::BasketofKittens::endpoints}, bare and unvalidated.
60
- # @param endpoint [Hash]: The resource to process and validate
61
- # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
61
+ # @param _endpoint [Hash]: The resource to process and validate
62
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
62
63
  # @return [Boolean]: True if validation succeeded, False otherwise
63
- def self.validate(endpoint, configurator)
64
+ def self.validate(_endpoint, _configurator)
64
65
  ok = true
65
66
 
66
67
  ok
@@ -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/*/firewall_rule.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/firewall_rule.rb
18
18
  class FirewallRule
19
19
 
20
20
  # Base configuration schema for a FirewallRule
@@ -100,14 +100,113 @@ module MU
100
100
  end
101
101
 
102
102
  # Generic pre-processing of {MU::Config::BasketofKittens::firewall_rules}, bare and unvalidated.
103
- # @param acl [Hash]: The resource to process and validate
104
- # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
103
+ # @param _acl [Hash]: The resource to process and validate
104
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
105
105
  # @return [Boolean]: True if validation succeeded, False otherwise
106
- def self.validate(acl, configurator)
106
+ def self.validate(_acl, _configurator)
107
107
  ok = true
108
108
  ok
109
109
  end
110
110
 
111
111
  end
112
+
113
+ # FirewallRules can reference other FirewallRules, which means we need to do
114
+ # an extra pass to make sure we get all intra-stack dependencies correct.
115
+ # @param acl [Hash]: The configuration hash for the FirewallRule to check
116
+ # @return [Hash]
117
+ def resolveIntraStackFirewallRefs(acl, delay_validation = false)
118
+ acl["rules"].each { |acl_include|
119
+ if acl_include['sgs']
120
+ acl_include['sgs'].each { |sg_ref|
121
+ if haveLitterMate?(sg_ref, "firewall_rules")
122
+ MU::Config.addDependency(acl, sg_ref, "firewall_rule", no_create_wait: true)
123
+ siblingfw = haveLitterMate?(sg_ref, "firewall_rules")
124
+ if !siblingfw["#MU_VALIDATED"]
125
+ # XXX raise failure somehow
126
+ insertKitten(siblingfw, "firewall_rules", delay_validation: delay_validation)
127
+ end
128
+ end
129
+ }
130
+ end
131
+ }
132
+ acl
133
+ end
134
+
135
+ # Generate configuration for the general-purpose admin firewall rulesets
136
+ # (security groups in AWS). Note that these are unique to regions and
137
+ # individual VPCs (as well as Classic, which is just a degenerate case of
138
+ # a VPC for our purposes.
139
+ # @param vpc [Hash]: A VPC reference as defined in our config schema. This originates with the calling resource, so we'll peel out just what we need (a name or cloud id of a VPC).
140
+ # @param admin_ip [String]: Optional string of an extra IP address to allow blanket access to the calling resource.
141
+ # @param cloud [String]: The parent resource's cloud plugin identifier
142
+ # @param region [String]: Cloud provider region, if applicable.
143
+ # @return [Hash<String>]: A dependency description that the calling resource can then add to itself.
144
+ def adminFirewallRuleset(vpc: nil, admin_ip: nil, region: nil, cloud: nil, credentials: nil, rules_only: false)
145
+ if !cloud or (cloud == "AWS" and !region)
146
+ raise MuError, "Cannot call adminFirewallRuleset without specifying the parent's region and cloud provider"
147
+ end
148
+ hosts = Array.new
149
+ hosts << "#{MU.my_public_ip}/32" if MU.my_public_ip
150
+ hosts << "#{MU.my_private_ip}/32" if MU.my_private_ip
151
+ hosts << "#{MU.mu_public_ip}/32" if MU.mu_public_ip
152
+ hosts << "#{admin_ip}/32" if admin_ip
153
+ hosts.uniq!
154
+
155
+ rules = []
156
+ if cloud == "Google"
157
+ rules = [
158
+ { "ingress" => true, "proto" => "all", "hosts" => hosts },
159
+ { "egress" => true, "proto" => "all", "hosts" => hosts }
160
+ ]
161
+ else
162
+ rules = [
163
+ { "proto" => "tcp", "port_range" => "0-65535", "hosts" => hosts },
164
+ { "proto" => "udp", "port_range" => "0-65535", "hosts" => hosts },
165
+ { "proto" => "icmp", "port_range" => "-1", "hosts" => hosts }
166
+ ]
167
+ end
168
+
169
+ if rules_only
170
+ return rules
171
+ end
172
+
173
+ name = "admin"
174
+ name += credentials.to_s if credentials
175
+ realvpc = nil
176
+ if vpc
177
+ realvpc = {}
178
+ ['vpc_name', 'vpc_id'].each { |p|
179
+ if vpc[p]
180
+ vpc[p.sub(/^vpc_/, '')] = vpc[p]
181
+ vpc.delete(p)
182
+ end
183
+ }
184
+ ['cloud', 'id', 'name', 'deploy_id', 'habitat', 'credentials'].each { |field|
185
+ realvpc[field] = vpc[field] if !vpc[field].nil?
186
+ }
187
+ if !realvpc['id'].nil? and !realvpc['id'].empty?
188
+ # Stupid kludge for Google cloud_ids which are sometimes URLs and
189
+ # sometimes not. Requirements are inconsistent from scenario to
190
+ # scenario.
191
+ name = name + "-" + realvpc['id'].gsub(/.*\//, "")
192
+ realvpc['id'] = getTail("id", value: realvpc['id'], prettyname: "Admin Firewall Ruleset #{name} Target VPC", cloudtype: "AWS::EC2::VPC::Id") if realvpc["id"].is_a?(String)
193
+ elsif !realvpc['name'].nil?
194
+ name = name + "-" + realvpc['name']
195
+ end
196
+ end
197
+
198
+
199
+ acl = {"name" => name, "rules" => rules, "vpc" => realvpc, "cloud" => cloud, "admin" => true, "credentials" => credentials }
200
+ if cloud == "Google" and acl["vpc"] and acl["vpc"]["habitat"]
201
+ acl['project'] = acl["vpc"]["habitat"]["id"] || acl["vpc"]["habitat"]["name"]
202
+ end
203
+ acl.delete("vpc") if !acl["vpc"]
204
+ if !MU::Cloud.resourceClass(cloud, "FirewallRule").isGlobal? and !region.nil? and !region.empty?
205
+ acl["region"] = region
206
+ end
207
+ @admin_firewall_rules << acl if !@admin_firewall_rules.include?(acl)
208
+ return {"type" => "firewall_rule", "name" => name}
209
+ end
210
+
112
211
  end
113
212
  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/*/folder.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/folder.rb
18
18
  class Folder
19
19
 
20
20
  # Base configuration schema for a Folder
@@ -59,10 +59,10 @@ module MU
59
59
  end
60
60
 
61
61
  # Generic pre-processing of {MU::Config::BasketofKittens::folder}, bare and unvalidated.
62
- # @param folder [Hash]: The resource to process and validate
63
- # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
62
+ # @param _folder [Hash]: The resource to process and validate
63
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
64
64
  # @return [Boolean]: True if validation succeeded, False otherwise
65
- def self.validate(folder, configurator)
65
+ def self.validate(_folder, _configurator)
66
66
  ok = true
67
67
  ok
68
68
  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/*/function.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/function.rb
18
18
  class Function
19
19
 
20
20
  # Base configuration schema for a Function
@@ -71,6 +71,10 @@ module MU
71
71
  "zip_file" => {
72
72
  "type" => "string",
73
73
  "description" => "Path to a zipped deployment package to upload."
74
+ },
75
+ "path" => {
76
+ "type" => "string",
77
+ "description" => "Path to a directory that can be zipped into deployment package to upload."
74
78
  }
75
79
  }
76
80
  },
@@ -99,20 +103,25 @@ module MU
99
103
 
100
104
  # Generic pre-processing of {MU::Config::BasketofKittens::functions}, bare and unvalidated.
101
105
  # @param function [Hash]: The resource to process and validate
102
- # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
106
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
103
107
  # @return [Boolean]: True if validation succeeded, False otherwise
104
- def self.validate(function, configurator)
108
+ def self.validate(function, _configurator)
105
109
  ok = true
106
110
  if !function['code']
107
111
  ok = false
108
112
  end
109
- if function['code'] and function['code']['zip_file']
110
- if !File.readable?(function['code']['zip_file'])
111
- MU.log "Can't read Function deployment package #{function['code']['zip_file']}", MU::ERR
112
- ok = false
113
- else
114
- function['code']['zip_file'] = File.realpath(File.expand_path(function['code']['zip_file']))
115
- end
113
+
114
+ if function['code']
115
+ ['zip_file', 'path'].each { |src|
116
+ if function['code'][src]
117
+ if !File.readable?(function['code'][src]) and !Dir.exists?(function['code'][src])
118
+ MU.log "Function '#{function['name']}' specifies a deployment package that I can't read at #{function['code'][src]}", MU::ERR
119
+ ok = false
120
+ else
121
+ function['code'][src] = File.realpath(File.expand_path(function['code'][src]))
122
+ end
123
+ end
124
+ }
116
125
  end
117
126
 
118
127
  ok
@@ -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/*/group.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/group.rb
18
18
  class Group
19
19
 
20
20
  # Base configuration schema for a Group
@@ -51,10 +51,10 @@ module MU
51
51
  end
52
52
 
53
53
  # Generic pre-processing of {MU::Config::BasketofKittens::group}, bare and unvalidated.
54
- # @param group [Hash]: The resource to process and validate
55
- # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
54
+ # @param _group [Hash]: The resource to process and validate
55
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
56
56
  # @return [Boolean]: True if validation succeeded, False otherwise
57
- def self.validate(group, configurator)
57
+ def self.validate(_group, _configurator)
58
58
  ok = true
59
59
  ok
60
60
  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/*/project.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/project.rb
18
18
  class Habitat
19
19
 
20
20
  # Base configuration schema for a Habitat
@@ -38,10 +38,10 @@ module MU
38
38
  end
39
39
 
40
40
  # Generic pre-processing of {MU::Config::BasketofKittens::habitat}, bare and unvalidated.
41
- # @param habitat [Hash]: The resource to process and validate
42
- # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
41
+ # @param _habitat [Hash]: The resource to process and validate
42
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
43
43
  # @return [Boolean]: True if validation succeeded, False otherwise
44
- def self.validate(habitat, configurator)
44
+ def self.validate(_habitat, _configurator)
45
45
  ok = true
46
46
  ok
47
47
  end
@@ -0,0 +1,89 @@
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
+ class Config
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/job.rb
18
+ class Job
19
+
20
+ # Base configuration schema for a scheduled job
21
+ # @return [Hash]
22
+ def self.schema
23
+ {
24
+ "type" => "object",
25
+ "additionalProperties" => false,
26
+ "description" => "A cloud provider-specific facility for triggered or scheduled tasks, such as AWS CloudWatch Events or Google Cloud Scheduler.",
27
+ "properties" => {
28
+ "name" => {
29
+ "type" => "string"
30
+ },
31
+ "region" => MU::Config.region_primitive,
32
+ "credentials" => MU::Config.credentials_primitive,
33
+ "description" => {
34
+ "type" => "string",
35
+ "description" => "Human-readable description field for this job (this will field be overriden with the Mu deploy id on most providers unless +scrub_mu_isms+ is set)"
36
+ },
37
+ "schedule" => {
38
+ "type" => "object",
39
+ "description" => "A schedule on which to invoke this task, typically unix crontab style.",
40
+ "properties" => {
41
+ "minute" => {
42
+ "type" => "string",
43
+ "description" => "The minute of the hour at which to invoke this job, typically an integer between 0 and 59. This will be validated by the cloud provider, where other more human-readable values may be supported.",
44
+ "default" => "0"
45
+ },
46
+ "hour" => {
47
+ "type" => "string",
48
+ "description" => "The hour at which to invoke this job, typically an integer between 0 and 23. This will be validated by the cloud provider, where other more human-readable values may be supported.",
49
+ "default" => "*"
50
+ },
51
+ "day_of_month" => {
52
+ "type" => "string",
53
+ "description" => "The day of the month which to invoke this job, typically an integer between 1 and 31. This will be validated by the cloud provider, where other more human-readable values may be supported.",
54
+ "default" => "*"
55
+ },
56
+ "month" => {
57
+ "type" => "string",
58
+ "description" => "The month in which to invoke this job, typically an integer between 1 and 12. This will be validated by the cloud provider, where other more human-readable values may be supported.",
59
+ "default" => "*"
60
+ },
61
+ "day_of_week" => {
62
+ "type" => "string",
63
+ "description" => "The day of the week on which to invoke this job, typically an integer between 0 and 6. This will be validated by the cloud provider, where other more human-readable values may be supported.",
64
+ "default" => "*"
65
+ },
66
+ "year" => {
67
+ "type" => "string",
68
+ "description" => "The year in which to invoke this job. Not honored by all cloud providers.",
69
+ "default" => "*"
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ end
76
+
77
+ # Generic pre-processing of {MU::Config::BasketofKittens::jobs}, bare and unvalidated.
78
+ # @param _job [Hash]: The resource to process and validate
79
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
80
+ # @return [Boolean]: True if validation succeeded, False otherwise
81
+ def self.validate(_job, _configurator)
82
+ ok = true
83
+
84
+ ok
85
+ end
86
+
87
+ end
88
+ end
89
+ 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/*/loadbalancer.rb
17
+ # Basket of Kittens config schema and parser logic. See modules/mu/providers/*/loadbalancer.rb
18
18
  class LoadBalancer
19
19
 
20
20
  # Generate schema for a LoadBalancer health check
@@ -64,6 +64,45 @@ module MU
64
64
  }
65
65
  end
66
66
 
67
+ # Generate schema for a LoadBalancer redirect
68
+ # @return [Hash]
69
+ def self.redirect
70
+ {
71
+ "type" => "object",
72
+ "title" => "redirect",
73
+ "additionalProperties" => false,
74
+ "description" => "Instruct our LoadBalancer to redirect traffic to another host, port, and/or path.",
75
+ "properties" => {
76
+ "protocol" => {
77
+ "type" => "string",
78
+ "default" => "HTTPS"
79
+ },
80
+ "port" => {
81
+ "type" => "integer",
82
+ "default" => 443
83
+ },
84
+ "host" => {
85
+ "type" => "string",
86
+ "default" => "\#{host}"
87
+ },
88
+ "path" => {
89
+ "type" => "string",
90
+ "default" => "/\#{path}"
91
+ },
92
+ "query" => {
93
+ "type" => "string",
94
+ "default" => "\#{query}"
95
+ },
96
+ "status_code" => {
97
+ "type" => "integer",
98
+ "description" => "The HTTP status code when issuing a redirect",
99
+ "default" => 301,
100
+ "enum" => [301, 302]
101
+ },
102
+ }
103
+ }
104
+ end
105
+
67
106
  # Base configuration schema for a LoadBalancer
68
107
  # @return [Hash]
69
108
  def self.schema
@@ -261,7 +300,7 @@ module MU
261
300
  "type" => "array",
262
301
  "items" => {
263
302
  "type" => "object",
264
- "required" => ["lb_protocol", "lb_port", "instance_protocol", "instance_port"],
303
+ "required" => ["lb_protocol", "lb_port"],
265
304
  "additionalProperties" => false,
266
305
  "description" => "A list of port/protocols which this Load Balancer should answer.",
267
306
  "properties" => {
@@ -279,6 +318,7 @@ module MU
279
318
  "enum" => ["HTTP", "HTTPS", "TCP", "SSL", "UDP"],
280
319
  "description" => "Specifies the load balancer transport protocol to use for routing - HTTP, HTTPS, TCP, SSL, or UDP. SSL and UDP are only valid in Google Cloud."
281
320
  },
321
+ "redirect" => MU::Config::LoadBalancer.redirect,
282
322
  "targetgroup" => {
283
323
  "type" => "string",
284
324
  "description" => "Which of our declared targetgroups should be the back-end for this listener's traffic"
@@ -309,14 +349,14 @@ module MU
309
349
  "items" => {
310
350
  "type" => "object",
311
351
  "description" => "Rules to route requests to different target groups based on the request path",
312
- "required" => ["conditions", "order"],
352
+ "required" => ["order", "conditions"],
313
353
  "additionalProperties" => false,
314
354
  "properties" => {
315
355
  "conditions" => {
316
356
  "type" => "array",
317
357
  "items" => {
318
358
  "type" => "object",
319
- "description" => "Rule condition",
359
+ "description" => "Rule conditionl; if none are specified (or if none match) the default action will be set.",
320
360
  "required" => ["field", "values"],
321
361
  "additionalProperties" => false,
322
362
  "properties" => {
@@ -339,16 +379,17 @@ module MU
339
379
  "type" => "array",
340
380
  "items" => {
341
381
  "type" => "object",
342
- "description" => "Rule action",
343
- "required" => ["action", "targetgroup"],
382
+ "description" => "Rule action, which must specify one of +targetgroup+ or +redirect+",
383
+ "required" => ["action"],
344
384
  "additionalProperties" => false,
345
385
  "properties" => {
346
386
  "action" => {
347
387
  "type" => "string",
348
388
  "default" => "forward",
349
389
  "description" => "An action to take when a match occurs. Currently, only forwarding to a targetgroup is supported.",
350
- "enum" => ["forward"]
390
+ "enum" => ["forward", "redirect"]
351
391
  },
392
+ "redirect" => MU::Config::LoadBalancer.redirect,
352
393
  "targetgroup" => {
353
394
  "type" => "string",
354
395
  "description" => "Which of our declared targetgroups should be the recipient of this traffic. If left unspecified, will default to the default targetgroup of this listener."
@@ -383,9 +424,9 @@ module MU
383
424
 
384
425
  # Generic pre-processing of {MU::Config::BasketofKittens::loadbalancers}, bare and unvalidated.
385
426
  # @param lb [Hash]: The resource to process and validate
386
- # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member
427
+ # @param _configurator [MU::Config]: The overall deployment configurator of which this resource is a member
387
428
  # @return [Boolean]: True if validation succeeded, False otherwise
388
- def self.validate(lb, configurator)
429
+ def self.validate(lb, _configurator)
389
430
  ok = true
390
431
  # Convert old-school listener declarations into target groups and health
391
432
  # checks, for which AWS and Google both have equivalents.
@@ -405,13 +446,18 @@ module MU
405
446
  "proto" => l["instance_protocol"],
406
447
  "port" => l["instance_port"]
407
448
  }
408
- if lb["healthcheck"]
409
- hc_target = lb['healthcheck']['target'].match(/^([^:]+):(\d+)(.*)/)
410
- tg["healthcheck"] = lb['healthcheck'].dup
449
+ if l["redirect"]
450
+ tg["proto"] ||= l["redirect"]["protocol"]
451
+ tg["port"] ||= l["redirect"]["port"]
452
+ end
453
+ l['healthcheck'] ||= lb['healthcheck'] if lb['healthcheck']
454
+ if l["healthcheck"]
455
+ hc_target = l['healthcheck']['target'].match(/^([^:]+):(\d+)(.*)/)
456
+ tg["healthcheck"] = l['healthcheck'].dup
411
457
  proto = ["HTTP", "HTTPS"].include?(hc_target[1]) ? hc_target[1] : l["instance_protocol"]
412
458
  tg['healthcheck']['target'] = "#{proto}:#{hc_target[2]}#{hc_target[3]}"
413
459
  tg['healthcheck']["httpcode"] = "200,301,302"
414
- MU.log "Converting classic-style ELB health check target #{lb['healthcheck']['target']} to ALB style for target group #{tgname} (#{l["instance_protocol"]}:#{l["instance_port"]}).", details: tg['healthcheck']
460
+ MU.log "Converting classic-style ELB health check target #{l['healthcheck']['target']} to ALB style for target group #{tgname} (#{l["instance_protocol"]}:#{l["instance_port"]}).", details: tg['healthcheck']
415
461
  end
416
462
  lb["targetgroups"] << tg
417
463
  }
@@ -446,7 +492,7 @@ module MU
446
492
  else
447
493
  found = false
448
494
  lb['targetgroups'].each { |tg|
449
- if l['targetgroup'] == action['targetgroup']
495
+ if tg['name'] == action['targetgroup']
450
496
  found = true
451
497
  break
452
498
  end