cloud-mu 2.1.0beta → 3.0.0beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (291) hide show
  1. checksums.yaml +5 -5
  2. data/Berksfile +4 -5
  3. data/Berksfile.lock +179 -0
  4. data/README.md +1 -6
  5. data/ansible/roles/geerlingguy.firewall/templates/firewall.bash.j2 +0 -0
  6. data/ansible/roles/mu-installer/README.md +33 -0
  7. data/ansible/roles/mu-installer/defaults/main.yml +2 -0
  8. data/ansible/roles/mu-installer/handlers/main.yml +2 -0
  9. data/ansible/roles/mu-installer/meta/main.yml +60 -0
  10. data/ansible/roles/mu-installer/tasks/main.yml +13 -0
  11. data/ansible/roles/mu-installer/tests/inventory +2 -0
  12. data/ansible/roles/mu-installer/tests/test.yml +5 -0
  13. data/ansible/roles/mu-installer/vars/main.yml +2 -0
  14. data/bin/mu-adopt +125 -0
  15. data/bin/mu-aws-setup +4 -4
  16. data/bin/mu-azure-setup +265 -0
  17. data/bin/mu-azure-tests +43 -0
  18. data/bin/mu-cleanup +20 -8
  19. data/bin/mu-configure +224 -98
  20. data/bin/mu-deploy +8 -3
  21. data/bin/mu-gcp-setup +16 -8
  22. data/bin/mu-gen-docs +92 -8
  23. data/bin/mu-load-config.rb +52 -12
  24. data/bin/mu-momma-cat +36 -0
  25. data/bin/mu-node-manage +34 -27
  26. data/bin/mu-self-update +2 -2
  27. data/bin/mu-ssh +12 -8
  28. data/bin/mu-upload-chef-artifacts +11 -4
  29. data/bin/mu-user-manage +3 -0
  30. data/cloud-mu.gemspec +8 -11
  31. data/cookbooks/firewall/libraries/helpers_iptables.rb +2 -2
  32. data/cookbooks/firewall/metadata.json +1 -1
  33. data/cookbooks/firewall/recipes/default.rb +5 -9
  34. data/cookbooks/mu-firewall/attributes/default.rb +2 -0
  35. data/cookbooks/mu-firewall/metadata.rb +1 -1
  36. data/cookbooks/mu-glusterfs/templates/default/mu-gluster-client.erb +0 -0
  37. data/cookbooks/mu-master/Berksfile +2 -2
  38. data/cookbooks/mu-master/files/default/check_mem.pl +0 -0
  39. data/cookbooks/mu-master/files/default/cloudamatic.png +0 -0
  40. data/cookbooks/mu-master/metadata.rb +5 -4
  41. data/cookbooks/mu-master/recipes/389ds.rb +1 -1
  42. data/cookbooks/mu-master/recipes/basepackages.rb +30 -10
  43. data/cookbooks/mu-master/recipes/default.rb +59 -7
  44. data/cookbooks/mu-master/recipes/firewall-holes.rb +1 -1
  45. data/cookbooks/mu-master/recipes/init.rb +65 -47
  46. data/cookbooks/mu-master/recipes/{eks-kubectl.rb → kubectl.rb} +4 -10
  47. data/cookbooks/mu-master/recipes/sssd.rb +2 -1
  48. data/cookbooks/mu-master/recipes/update_nagios_only.rb +6 -6
  49. data/cookbooks/mu-master/templates/default/web_app.conf.erb +2 -2
  50. data/cookbooks/mu-master/templates/mods/ldap.conf.erb +4 -0
  51. data/cookbooks/mu-php54/Berksfile +1 -2
  52. data/cookbooks/mu-php54/metadata.rb +4 -5
  53. data/cookbooks/mu-php54/recipes/default.rb +1 -1
  54. data/cookbooks/mu-splunk/templates/default/splunk-init.erb +0 -0
  55. data/cookbooks/mu-tools/Berksfile +3 -2
  56. data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
  57. data/cookbooks/mu-tools/libraries/helper.rb +20 -8
  58. data/cookbooks/mu-tools/metadata.rb +5 -2
  59. data/cookbooks/mu-tools/recipes/apply_security.rb +2 -3
  60. data/cookbooks/mu-tools/recipes/eks.rb +1 -1
  61. data/cookbooks/mu-tools/recipes/gcloud.rb +5 -30
  62. data/cookbooks/mu-tools/recipes/nagios.rb +1 -1
  63. data/cookbooks/mu-tools/recipes/rsyslog.rb +1 -0
  64. data/cookbooks/mu-tools/recipes/selinux.rb +19 -0
  65. data/cookbooks/mu-tools/recipes/split_var_partitions.rb +0 -1
  66. data/cookbooks/mu-tools/recipes/windows-client.rb +256 -122
  67. data/cookbooks/mu-tools/resources/disk.rb +3 -1
  68. data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +1 -1
  69. data/cookbooks/mu-tools/templates/default/etc_hosts.erb +1 -1
  70. data/cookbooks/mu-tools/templates/default/{kubeconfig.erb → kubeconfig-eks.erb} +0 -0
  71. data/cookbooks/mu-tools/templates/default/kubeconfig-gke.erb +27 -0
  72. data/cookbooks/mu-tools/templates/windows-10/sshd_config.erb +137 -0
  73. data/cookbooks/mu-utility/recipes/nat.rb +4 -0
  74. data/extras/alpha.png +0 -0
  75. data/extras/beta.png +0 -0
  76. data/extras/clean-stock-amis +2 -2
  77. data/extras/generate-stock-images +131 -0
  78. data/extras/git-fix-permissions-hook +0 -0
  79. data/extras/image-generators/AWS/centos6.yaml +17 -0
  80. data/extras/image-generators/{aws → AWS}/centos7-govcloud.yaml +0 -0
  81. data/extras/image-generators/{aws → AWS}/centos7.yaml +0 -0
  82. data/extras/image-generators/{aws → AWS}/rhel7.yaml +0 -0
  83. data/extras/image-generators/{aws → AWS}/win2k12.yaml +0 -0
  84. data/extras/image-generators/{aws → AWS}/win2k16.yaml +0 -0
  85. data/extras/image-generators/{aws → AWS}/windows.yaml +0 -0
  86. data/extras/image-generators/{gcp → Google}/centos6.yaml +1 -0
  87. data/extras/image-generators/Google/centos7.yaml +18 -0
  88. data/extras/python_rpm/build.sh +0 -0
  89. data/extras/release.png +0 -0
  90. data/extras/ruby_rpm/build.sh +0 -0
  91. data/extras/ruby_rpm/muby.spec +1 -1
  92. data/install/README.md +43 -5
  93. data/install/deprecated-bash-library.sh +0 -0
  94. data/install/installer +1 -1
  95. data/install/jenkinskeys.rb +0 -0
  96. data/install/mu-master.yaml +55 -0
  97. data/modules/mommacat.ru +41 -7
  98. data/modules/mu.rb +444 -149
  99. data/modules/mu/adoption.rb +500 -0
  100. data/modules/mu/cleanup.rb +235 -158
  101. data/modules/mu/cloud.rb +675 -138
  102. data/modules/mu/clouds/aws.rb +156 -24
  103. data/modules/mu/clouds/aws/alarm.rb +4 -14
  104. data/modules/mu/clouds/aws/bucket.rb +60 -18
  105. data/modules/mu/clouds/aws/cache_cluster.rb +8 -20
  106. data/modules/mu/clouds/aws/collection.rb +12 -22
  107. data/modules/mu/clouds/aws/container_cluster.rb +209 -118
  108. data/modules/mu/clouds/aws/database.rb +120 -45
  109. data/modules/mu/clouds/aws/dnszone.rb +7 -18
  110. data/modules/mu/clouds/aws/endpoint.rb +5 -15
  111. data/modules/mu/clouds/aws/firewall_rule.rb +144 -72
  112. data/modules/mu/clouds/aws/folder.rb +4 -11
  113. data/modules/mu/clouds/aws/function.rb +6 -16
  114. data/modules/mu/clouds/aws/group.rb +4 -12
  115. data/modules/mu/clouds/aws/habitat.rb +11 -13
  116. data/modules/mu/clouds/aws/loadbalancer.rb +40 -28
  117. data/modules/mu/clouds/aws/log.rb +5 -13
  118. data/modules/mu/clouds/aws/msg_queue.rb +9 -24
  119. data/modules/mu/clouds/aws/nosqldb.rb +4 -12
  120. data/modules/mu/clouds/aws/notifier.rb +6 -13
  121. data/modules/mu/clouds/aws/role.rb +69 -40
  122. data/modules/mu/clouds/aws/search_domain.rb +17 -20
  123. data/modules/mu/clouds/aws/server.rb +184 -94
  124. data/modules/mu/clouds/aws/server_pool.rb +33 -38
  125. data/modules/mu/clouds/aws/storage_pool.rb +5 -12
  126. data/modules/mu/clouds/aws/user.rb +59 -33
  127. data/modules/mu/clouds/aws/userdata/linux.erb +18 -30
  128. data/modules/mu/clouds/aws/userdata/windows.erb +9 -9
  129. data/modules/mu/clouds/aws/vpc.rb +214 -145
  130. data/modules/mu/clouds/azure.rb +978 -44
  131. data/modules/mu/clouds/azure/container_cluster.rb +413 -0
  132. data/modules/mu/clouds/azure/firewall_rule.rb +500 -0
  133. data/modules/mu/clouds/azure/habitat.rb +167 -0
  134. data/modules/mu/clouds/azure/loadbalancer.rb +205 -0
  135. data/modules/mu/clouds/azure/role.rb +211 -0
  136. data/modules/mu/clouds/azure/server.rb +810 -0
  137. data/modules/mu/clouds/azure/user.rb +257 -0
  138. data/modules/mu/clouds/azure/userdata/README.md +4 -0
  139. data/modules/mu/clouds/azure/userdata/linux.erb +137 -0
  140. data/modules/mu/clouds/azure/userdata/windows.erb +275 -0
  141. data/modules/mu/clouds/azure/vpc.rb +782 -0
  142. data/modules/mu/clouds/cloudformation.rb +12 -9
  143. data/modules/mu/clouds/cloudformation/firewall_rule.rb +5 -13
  144. data/modules/mu/clouds/cloudformation/server.rb +10 -1
  145. data/modules/mu/clouds/cloudformation/server_pool.rb +1 -0
  146. data/modules/mu/clouds/cloudformation/vpc.rb +0 -2
  147. data/modules/mu/clouds/google.rb +554 -117
  148. data/modules/mu/clouds/google/bucket.rb +173 -32
  149. data/modules/mu/clouds/google/container_cluster.rb +1112 -157
  150. data/modules/mu/clouds/google/database.rb +24 -47
  151. data/modules/mu/clouds/google/firewall_rule.rb +344 -89
  152. data/modules/mu/clouds/google/folder.rb +156 -79
  153. data/modules/mu/clouds/google/group.rb +272 -82
  154. data/modules/mu/clouds/google/habitat.rb +177 -52
  155. data/modules/mu/clouds/google/loadbalancer.rb +9 -34
  156. data/modules/mu/clouds/google/role.rb +1211 -0
  157. data/modules/mu/clouds/google/server.rb +491 -227
  158. data/modules/mu/clouds/google/server_pool.rb +233 -48
  159. data/modules/mu/clouds/google/user.rb +479 -125
  160. data/modules/mu/clouds/google/userdata/linux.erb +3 -3
  161. data/modules/mu/clouds/google/userdata/windows.erb +9 -9
  162. data/modules/mu/clouds/google/vpc.rb +381 -223
  163. data/modules/mu/config.rb +689 -214
  164. data/modules/mu/config/bucket.rb +1 -1
  165. data/modules/mu/config/cache_cluster.rb +1 -1
  166. data/modules/mu/config/cache_cluster.yml +0 -4
  167. data/modules/mu/config/container_cluster.rb +18 -9
  168. data/modules/mu/config/database.rb +6 -23
  169. data/modules/mu/config/firewall_rule.rb +9 -15
  170. data/modules/mu/config/folder.rb +22 -21
  171. data/modules/mu/config/habitat.rb +22 -21
  172. data/modules/mu/config/loadbalancer.rb +2 -2
  173. data/modules/mu/config/role.rb +9 -40
  174. data/modules/mu/config/server.rb +26 -5
  175. data/modules/mu/config/server_pool.rb +1 -1
  176. data/modules/mu/config/storage_pool.rb +2 -2
  177. data/modules/mu/config/user.rb +4 -0
  178. data/modules/mu/config/vpc.rb +350 -110
  179. data/modules/mu/defaults/{amazon_images.yaml → AWS.yaml} +37 -39
  180. data/modules/mu/defaults/Azure.yaml +17 -0
  181. data/modules/mu/defaults/Google.yaml +24 -0
  182. data/modules/mu/defaults/README.md +1 -1
  183. data/modules/mu/deploy.rb +168 -125
  184. data/modules/mu/groomer.rb +2 -1
  185. data/modules/mu/groomers/ansible.rb +104 -32
  186. data/modules/mu/groomers/chef.rb +96 -44
  187. data/modules/mu/kittens.rb +20602 -0
  188. data/modules/mu/logger.rb +38 -11
  189. data/modules/mu/master.rb +90 -8
  190. data/modules/mu/master/chef.rb +2 -3
  191. data/modules/mu/master/ldap.rb +0 -1
  192. data/modules/mu/master/ssl.rb +250 -0
  193. data/modules/mu/mommacat.rb +917 -513
  194. data/modules/scratchpad.erb +1 -1
  195. data/modules/tests/super_complex_bok.yml +0 -0
  196. data/modules/tests/super_simple_bok.yml +0 -0
  197. data/roles/mu-master.json +2 -1
  198. data/spec/azure_creds +5 -0
  199. data/spec/mu.yaml +56 -0
  200. data/spec/mu/clouds/azure_spec.rb +164 -27
  201. data/spec/spec_helper.rb +5 -0
  202. data/test/clean_up.py +0 -0
  203. data/test/exec_inspec.py +0 -0
  204. data/test/exec_mu_install.py +0 -0
  205. data/test/exec_retry.py +0 -0
  206. data/test/smoke_test.rb +0 -0
  207. metadata +90 -118
  208. data/cookbooks/mu-jenkins/Berksfile +0 -14
  209. data/cookbooks/mu-jenkins/CHANGELOG.md +0 -13
  210. data/cookbooks/mu-jenkins/LICENSE +0 -37
  211. data/cookbooks/mu-jenkins/README.md +0 -105
  212. data/cookbooks/mu-jenkins/attributes/default.rb +0 -42
  213. data/cookbooks/mu-jenkins/files/default/cleanup_deploy_config.xml +0 -73
  214. data/cookbooks/mu-jenkins/files/default/deploy_config.xml +0 -44
  215. data/cookbooks/mu-jenkins/metadata.rb +0 -21
  216. data/cookbooks/mu-jenkins/recipes/default.rb +0 -195
  217. data/cookbooks/mu-jenkins/recipes/node-ssh-config.rb +0 -54
  218. data/cookbooks/mu-jenkins/recipes/public_key.rb +0 -24
  219. data/cookbooks/mu-jenkins/templates/default/example_job.config.xml.erb +0 -24
  220. data/cookbooks/mu-jenkins/templates/default/org.jvnet.hudson.plugins.SSHBuildWrapper.xml.erb +0 -14
  221. data/cookbooks/mu-jenkins/templates/default/ssh_config.erb +0 -6
  222. data/cookbooks/nagios/Berksfile +0 -11
  223. data/cookbooks/nagios/CHANGELOG.md +0 -589
  224. data/cookbooks/nagios/CONTRIBUTING.md +0 -11
  225. data/cookbooks/nagios/LICENSE +0 -37
  226. data/cookbooks/nagios/README.md +0 -328
  227. data/cookbooks/nagios/TESTING.md +0 -2
  228. data/cookbooks/nagios/attributes/config.rb +0 -171
  229. data/cookbooks/nagios/attributes/default.rb +0 -228
  230. data/cookbooks/nagios/chefignore +0 -102
  231. data/cookbooks/nagios/definitions/command.rb +0 -33
  232. data/cookbooks/nagios/definitions/contact.rb +0 -33
  233. data/cookbooks/nagios/definitions/contactgroup.rb +0 -33
  234. data/cookbooks/nagios/definitions/host.rb +0 -33
  235. data/cookbooks/nagios/definitions/hostdependency.rb +0 -33
  236. data/cookbooks/nagios/definitions/hostescalation.rb +0 -34
  237. data/cookbooks/nagios/definitions/hostgroup.rb +0 -33
  238. data/cookbooks/nagios/definitions/nagios_conf.rb +0 -38
  239. data/cookbooks/nagios/definitions/resource.rb +0 -33
  240. data/cookbooks/nagios/definitions/service.rb +0 -33
  241. data/cookbooks/nagios/definitions/servicedependency.rb +0 -33
  242. data/cookbooks/nagios/definitions/serviceescalation.rb +0 -34
  243. data/cookbooks/nagios/definitions/servicegroup.rb +0 -33
  244. data/cookbooks/nagios/definitions/timeperiod.rb +0 -33
  245. data/cookbooks/nagios/libraries/base.rb +0 -314
  246. data/cookbooks/nagios/libraries/command.rb +0 -91
  247. data/cookbooks/nagios/libraries/contact.rb +0 -230
  248. data/cookbooks/nagios/libraries/contactgroup.rb +0 -112
  249. data/cookbooks/nagios/libraries/custom_option.rb +0 -36
  250. data/cookbooks/nagios/libraries/data_bag_helper.rb +0 -23
  251. data/cookbooks/nagios/libraries/default.rb +0 -90
  252. data/cookbooks/nagios/libraries/host.rb +0 -412
  253. data/cookbooks/nagios/libraries/hostdependency.rb +0 -181
  254. data/cookbooks/nagios/libraries/hostescalation.rb +0 -173
  255. data/cookbooks/nagios/libraries/hostgroup.rb +0 -119
  256. data/cookbooks/nagios/libraries/nagios.rb +0 -282
  257. data/cookbooks/nagios/libraries/resource.rb +0 -59
  258. data/cookbooks/nagios/libraries/service.rb +0 -455
  259. data/cookbooks/nagios/libraries/servicedependency.rb +0 -215
  260. data/cookbooks/nagios/libraries/serviceescalation.rb +0 -195
  261. data/cookbooks/nagios/libraries/servicegroup.rb +0 -144
  262. data/cookbooks/nagios/libraries/timeperiod.rb +0 -160
  263. data/cookbooks/nagios/libraries/users_helper.rb +0 -54
  264. data/cookbooks/nagios/metadata.rb +0 -25
  265. data/cookbooks/nagios/recipes/_load_databag_config.rb +0 -153
  266. data/cookbooks/nagios/recipes/_load_default_config.rb +0 -241
  267. data/cookbooks/nagios/recipes/apache.rb +0 -48
  268. data/cookbooks/nagios/recipes/default.rb +0 -204
  269. data/cookbooks/nagios/recipes/nginx.rb +0 -82
  270. data/cookbooks/nagios/recipes/pagerduty.rb +0 -143
  271. data/cookbooks/nagios/recipes/server_package.rb +0 -40
  272. data/cookbooks/nagios/recipes/server_source.rb +0 -164
  273. data/cookbooks/nagios/templates/default/apache2.conf.erb +0 -96
  274. data/cookbooks/nagios/templates/default/cgi.cfg.erb +0 -266
  275. data/cookbooks/nagios/templates/default/commands.cfg.erb +0 -13
  276. data/cookbooks/nagios/templates/default/contacts.cfg.erb +0 -37
  277. data/cookbooks/nagios/templates/default/hostgroups.cfg.erb +0 -25
  278. data/cookbooks/nagios/templates/default/hosts.cfg.erb +0 -15
  279. data/cookbooks/nagios/templates/default/htpasswd.users.erb +0 -6
  280. data/cookbooks/nagios/templates/default/nagios.cfg.erb +0 -22
  281. data/cookbooks/nagios/templates/default/nginx.conf.erb +0 -62
  282. data/cookbooks/nagios/templates/default/pagerduty.cgi.erb +0 -185
  283. data/cookbooks/nagios/templates/default/resource.cfg.erb +0 -27
  284. data/cookbooks/nagios/templates/default/servicedependencies.cfg.erb +0 -15
  285. data/cookbooks/nagios/templates/default/servicegroups.cfg.erb +0 -14
  286. data/cookbooks/nagios/templates/default/services.cfg.erb +0 -14
  287. data/cookbooks/nagios/templates/default/templates.cfg.erb +0 -31
  288. data/cookbooks/nagios/templates/default/timeperiods.cfg.erb +0 -13
  289. data/extras/image-generators/aws/centos6.yaml +0 -18
  290. data/modules/mu/defaults/google_images.yaml +0 -16
  291. data/roles/mu-master-jenkins.json +0 -24
@@ -180,7 +180,7 @@ module MU
180
180
  pool['vault_access'] << {"vault" => "splunk", "item" => "admin_user"}
181
181
  ok = false if !MU::Config.check_vault_refs(pool)
182
182
 
183
- if !pool['scrub_mu_isms']
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'])
185
185
  end
186
186
 
@@ -93,7 +93,7 @@ module MU
93
93
  siblingvpc = configurator.haveLitterMate?(mp["vpc"]["vpc_name"], "vpcs")
94
94
  if !MU::Config::VPC.processReference(mp['vpc'],
95
95
  "storage_pools",
96
- "storagepool '#{pool['name']}'",
96
+ pool,
97
97
  configurator,
98
98
  dflt_region: pool['region'],
99
99
  credentials: pool['credentials'],
@@ -104,7 +104,7 @@ module MU
104
104
  else
105
105
  if !MU::Config::VPC.processReference(mp["vpc"],
106
106
  "storage_pools",
107
- "storagepool #{pool['name']}",
107
+ pool,
108
108
  configurator,
109
109
  dflt_region: pool['region'],
110
110
  credentials: pool['credentials'])
@@ -41,6 +41,10 @@ module MU
41
41
  "description" => "If we attempt to create or associate a user that already exists, simply modify that user in-place and use it, rather than throwing an error. If this flag is set, the user will *not* be deleted on cleanup, nor will we overwrite any existing tags on cloud platforms that support user tagging.",
42
42
  "default" => true
43
43
  },
44
+ "force_password_change" => {
45
+ "type" => "boolean",
46
+ "description" => "For supported platforms and user types, require the user to reset their password on their next login. Our default behavior is to set this flag when initially creating an account. Setting it explicitly +true+ will set this flag on every subsequent +groom+ of the user, which may not be desired behavior."
47
+ },
44
48
  "create_api_key" => {
45
49
  "type" => "boolean",
46
50
  "default" => false,
@@ -27,15 +27,21 @@ module MU
27
27
  "description" => "Create Virtual Private Clouds with custom public or private subnets.",
28
28
  "properties" => {
29
29
  "name" => {"type" => "string"},
30
+ "habitat" => MU::Config::Habitat.reference,
30
31
  "cloud" => MU::Config.cloud_primitive,
31
32
  "ip_block" => {
32
33
  "type" => "string",
33
34
  "pattern" => MU::Config::CIDR_PATTERN,
34
- "description" => MU::Config::CIDR_DESCRIPTION,
35
- "default" => "10.0.0.0/16"
35
+ "description" => MU::Config::CIDR_DESCRIPTION
36
36
  },
37
37
  "tags" => MU::Config.tags_primitive,
38
38
  "optional_tags" => MU::Config.optional_tags_primitive,
39
+ "create_bastion" => {
40
+ "type" => "boolean",
41
+ "description" => "If we have private subnets and our Mu Master will not be able to route directly to them, create a small instance to serve as an ssh relay.",
42
+ "default" => true
43
+ },
44
+ "bastion" => MU::Config::Ref.schema(type: "servers", desc: "A reference to a bastion host that can be used to tunnel into private address space in this VPC."),
39
45
  "create_standard_subnets" => {
40
46
  "type" => "boolean",
41
47
  "description" => "If the 'subnets' parameter to this VPC is not specified, we will instead create one set of public subnets and one set of private, with a public/private pair in each Availability Zone in the target region.",
@@ -117,19 +123,45 @@ module MU
117
123
  }
118
124
  },
119
125
  "route_tables" => {
120
- "type" => "array",
121
- "items" => {
122
- "type" => "object",
123
- "required" => ["name", "routes"],
124
- "description" => "A table of route entries, typically for use inside a VPC.",
125
- "properties" => {
126
- "name" => {"type" => "string"},
127
- "routes" => {
128
- "type" => "array",
129
- "items" => routeschema
130
- }
126
+ "default_if" => [
127
+ {
128
+ "key_is" => "create_standard_subnets",
129
+ "value_is" => true,
130
+ "set" => [
131
+ {
132
+ "name" => "internet",
133
+ "routes" => [ { "destination_network" => "0.0.0.0/0", "gateway" => "#INTERNET" } ]
134
+ },
135
+ {
136
+ "name" => "private",
137
+ "routes" => [ { "destination_network" => "0.0.0.0/0", "gateway" => "#NAT" } ]
131
138
  }
139
+ ]
140
+ },
141
+ {
142
+ "key_is" => "create_standard_subnets",
143
+ "value_is" => false,
144
+ "set" => [
145
+ {
146
+ "name" => "private",
147
+ "routes" => [ { "destination_network" => "0.0.0.0/0" } ]
148
+ }
149
+ ]
132
150
  }
151
+ ],
152
+ "type" => "array",
153
+ "items" => {
154
+ "type" => "object",
155
+ "required" => ["name", "routes"],
156
+ "description" => "A table of route entries, typically for use inside a VPC.",
157
+ "properties" => {
158
+ "name" => {"type" => "string"},
159
+ "routes" => {
160
+ "type" => "array",
161
+ "items" => routeschema
162
+ }
163
+ }
164
+ }
133
165
  },
134
166
  "subnets" => {
135
167
  "type" => "array",
@@ -223,34 +255,40 @@ module MU
223
255
  # @param subnet_pref [String]:
224
256
  # @return [Hash]
225
257
  def self.reference(subnets = MANY_SUBNETS, nat_opts = NAT_OPTS, subnet_pref = nil)
226
- vpc_ref_schema = {
227
- "type" => "object",
228
- "description" => "Deploy, attach, allow access from, or peer this resource with a VPC of VPCs.",
229
- "minProperties" => 1,
230
- "additionalProperties" => false,
231
- "properties" => {
232
- "vpc_id" => {
233
- "type" => "string",
234
- "description" => "Discover this VPC by looking for this cloud provider identifier."
235
- },
236
- "credentials" => MU::Config.credentials_primitive,
237
- "vpc_name" => {
238
- "type" => "string",
239
- "description" => "Discover this VPC by Mu-internal name; typically the shorthand 'name' field of a VPC declared elsewhere in the deploy, or in another deploy that's being referenced with 'deploy_id'."
240
- },
241
- "region" => MU::Config.region_primitive,
242
- "cloud" => MU::Config.cloud_primitive,
243
- "tag" => {
244
- "type" => "string",
245
- "description" => "Discover this VPC by a cloud provider tag (key=value); note that this tag must not match more than one resource.",
246
- "pattern" => "^[^=]+=.+"
247
- },
248
- "deploy_id" => {
249
- "type" => "string",
250
- "description" => "Search for this VPC in an existing Mu deploy; specify a Mu deploy id (e.g. DEMO-DEV-2014111400-NG)."
251
- }
252
- }
253
- }
258
+ schema_aliases = [
259
+ { "vpc_id" => "id" },
260
+ { "vpc_name" => "name" }
261
+ ]
262
+ vpc_ref_schema = MU::Config::Ref.schema(schema_aliases, type: "vpcs")
263
+
264
+ # vpc_ref_schema = {
265
+ # "type" => "object",
266
+ # "description" => "Deploy, attach, allow access from, or peer this resource with a VPC of VPCs.",
267
+ # "minProperties" => 1,
268
+ # "additionalProperties" => false,
269
+ # "properties" => {
270
+ # "vpc_id" => {
271
+ # "type" => "string",
272
+ # "description" => "Discover this VPC by looking for this cloud provider identifier."
273
+ # },
274
+ # "credentials" => MU::Config.credentials_primitive,
275
+ # "vpc_name" => {
276
+ # "type" => "string",
277
+ # "description" => "Discover this VPC by Mu-internal name; typically the shorthand 'name' field of a VPC declared elsewhere in the deploy, or in another deploy that's being referenced with 'deploy_id'."
278
+ # },
279
+ # "region" => MU::Config.region_primitive,
280
+ # "cloud" => MU::Config.cloud_primitive,
281
+ # "tag" => {
282
+ # "type" => "string",
283
+ # "description" => "Discover this VPC by a cloud provider tag (key=value); note that this tag must not match more than one resource.",
284
+ # "pattern" => "^[^=]+=.+"
285
+ # },
286
+ # "deploy_id" => {
287
+ # "type" => "string",
288
+ # "description" => "Search for this VPC in an existing Mu deploy; specify a Mu deploy id (e.g. DEMO-DEV-2014111400-NG)."
289
+ # }
290
+ # }
291
+ # }
254
292
 
255
293
  if nat_opts
256
294
  vpc_ref_schema["properties"].merge!(
@@ -374,19 +412,142 @@ module MU
374
412
  def self.validate(vpc, configurator)
375
413
  ok = true
376
414
 
415
+ have_public = false
416
+ have_private = false
417
+
418
+ using_default_cidr = false
419
+ if !vpc['ip_block']
420
+ using_default_cidr = true
421
+ vpc['ip_block'] = "10.0.0.0/16"
422
+ end
423
+
377
424
  # Look for a common YAML screwup in route table land
378
- if vpc['route_tables']
379
- vpc['route_tables'].each { |rtb|
380
- next if !rtb['routes']
381
- rtb['routes'].each { |r|
382
- if r.has_key?("gateway") and (!r["gateway"] or r["gateway"].to_s.empty?)
383
- MU.log "Route gateway in VPC #{vpc['name']} cannot be nil- did you forget to puts quotes around a #INTERNET, #NAT, or #DENY?", MU::ERR, details: rtb
384
- ok = false
425
+ vpc['route_tables'].each { |rtb|
426
+ next if !rtb['routes']
427
+ rtb['routes'].each { |r|
428
+ have_public = true if r['gateway'] == "#INTERNET"
429
+ have_private = true if r['gateway'] == "#NAT" or r['gateway'] == "#DENY"
430
+ # XXX the above logic doesn't cover VPN ids, peering connections, or
431
+ # instances used as routers. If you're doing anything that complex
432
+ # you should probably be declaring your own bastion hosts and
433
+ # routing behaviors, rather than relying on our inferred defaults.
434
+ if r.has_key?("gateway") and (!r["gateway"] or r["gateway"].to_s.empty?)
435
+ MU.log "Route gateway in VPC #{vpc['name']} cannot be nil- did you forget to puts quotes around a #INTERNET, #NAT, or #DENY?", MU::ERR, details: rtb
436
+ ok = false
437
+ end
438
+ }
439
+ rtb['routes'].uniq!
440
+ }
441
+
442
+ # if we're peering with other on-the-fly VPCs who might be using
443
+ # the default range, make sure our ip_blocks don't overlap
444
+ peer_blocks = []
445
+ my_cidr = NetAddr::IPv4Net.parse(vpc['ip_block'].to_s)
446
+ if vpc["peers"]
447
+ siblings = configurator.haveLitterMate?(nil, "vpcs", has_multiple: true)
448
+ siblings.each { |v|
449
+ next if v['name'] == vpc['name']
450
+ peer_blocks << v['ip_block'] if v['ip_block']
451
+ }
452
+ if peer_blocks.size > 0 and using_default_cidr
453
+ begin
454
+ have_overlaps = false
455
+ peer_blocks.each { |cidr|
456
+ sibling_cidr = NetAddr::IPv4Net.parse(cidr)
457
+ have_overlaps = true if my_cidr.rel(sibling_cidr) != nil
458
+ }
459
+ if have_overlaps
460
+ my_cidr = my_cidr.next_sib
461
+ my_cidr = nil if my_cidr.to_s.match(/^10\.255\./)
385
462
  end
463
+ end while have_overlaps
464
+ if !my_cidr.nil? and vpc['ip_block'] != my_cidr.to_s
465
+ vpc['ip_block'] = my_cidr.to_s
466
+ else
467
+ my_cidr = NetAddr::IPv4Net.parse(vpc['ip_block'])
468
+ end
469
+ end
470
+ end
471
+
472
+ # Work out what we'll do
473
+ if have_private
474
+ vpc["cloud"] ||= MU.defaultCloud
475
+
476
+ # See if we'll be able to create peering connections
477
+ can_peer = false
478
+ if MU.myCloud == vpc["cloud"] and MU.myVPCObj
479
+ peer_blocks.concat(MU.myVPCObj.routes)
480
+ begin
481
+ can_peer = true
482
+ peer_blocks.each { |cidr|
483
+ cidr_obj = NetAddr::IPv4Net.parse(cidr)
484
+ if my_cidr.rel(cidr_obj) != nil
485
+ can_peer = false
486
+ end
487
+ }
488
+ if !can_peer and using_default_cidr
489
+ my_cidr = my_cidr.next_sib
490
+ my_cidr = nil if my_cidr.to_s.match(/^10\.255\./)
491
+ end
492
+ end while !can_peer and using_default_cidr and !my_cidr.nil?
493
+ if !my_cidr.nil? and vpc['ip_block'] != my_cidr.to_s
494
+ vpc['ip_block'] = my_cidr.to_s
495
+ end
496
+ if using_default_cidr
497
+ MU.log "Defaulting address range for VPC #{vpc['name']} to #{vpc['ip_block']}", MU::NOTICE
498
+ end
499
+ if can_peer
500
+ vpc['peers'] ||= []
501
+ vpc['peers'] << {
502
+ "vpc" => { "id" => MU.myVPC, "type" => "vpcs" }
503
+ }
504
+ else
505
+ MU.log "#{vpc['ip_block']} overlaps with existing routes, will not be able to peer with Master's VPC", MU::WARN
506
+ end
507
+ end
508
+
509
+
510
+ # Feeling that, generate a generic bastion/NAT host to do the job.
511
+ # Clouds that don't have some kind of native NAT gateway can also
512
+ # leverage this host to honor "gateway" => "#NAT" situations.
513
+ if !can_peer and have_public and vpc["create_bastion"]
514
+ serverclass = Object.const_get("MU").const_get("Cloud").const_get(vpc["cloud"]).const_get("Server")
515
+ bastion = serverclass.genericNAT.dup
516
+ bastion['name'] = vpc['name']+"-natstion" # XXX account for multiples somehow
517
+ bastion['credentials'] = vpc['credentials']
518
+ bastion['ingress_rules'] ||= []
519
+ ["tcp", "udp", "icmp"].each { |proto|
520
+ bastion['ingress_rules'] << {
521
+ "hosts" => [vpc["ip_block"].to_s],
522
+ "proto" => proto
523
+ }
386
524
  }
387
- }
525
+ bastion["application_attributes"] = {
526
+ "nat" => {
527
+ "private_net" => vpc["ip_block"].to_s
528
+ }
529
+ }
530
+ bastion["vpc"] = {
531
+ "name" => vpc["name"],
532
+ "subnet_pref" => "public"
533
+ }
534
+ vpc["dependencies"] << {
535
+ "type" => "server",
536
+ "name" => bastion['name'],
537
+ }
538
+ vpc["bastion"] = MU::Config::Ref.get(
539
+ name: bastion['name'],
540
+ cloud: vpc['cloud'],
541
+ credentials: vpc['credentials'],
542
+ type: "servers"
543
+ )
544
+
545
+ ok = false if !configurator.insertKitten(bastion, "servers", true)
546
+ end
547
+
388
548
  end
389
549
 
550
+
390
551
  ok = false if !resolvePeers(vpc, configurator)
391
552
 
392
553
  ok
@@ -404,22 +565,26 @@ module MU
404
565
  append = []
405
566
  delete = []
406
567
  vpc["peers"].each { |peer|
568
+ if peer.nil? or !peer.is_a?(Hash) or !peer["vpc"]
569
+ MU.log "Skipping malformed VPC peer in #{vpc['name']}", MU::ERR, details: peer
570
+ next
571
+ end
407
572
  peer["#MU_CLOUDCLASS"] = Object.const_get("MU").const_get("Cloud").const_get("VPC")
408
573
  # We check for multiple siblings because some implementations
409
574
  # (Google) can split declared VPCs into parts to get the mimic the
410
575
  # routing behaviors we expect.
411
- siblings = configurator.haveLitterMate?(peer['vpc']["vpc_name"], "vpcs", has_multiple: true)
576
+ siblings = configurator.haveLitterMate?(peer['vpc']["name"], "vpcs", has_multiple: true)
412
577
 
413
578
  # If we're peering with a VPC in this deploy, set it as a dependency
414
- if !peer['vpc']["vpc_name"].nil? and siblings.size > 0 and
579
+ if !peer['vpc']["name"].nil? and siblings.size > 0 and
415
580
  peer["vpc"]['deploy_id'].nil? and peer["vpc"]['vpc_id'].nil?
416
581
 
417
582
  peer['vpc']['cloud'] = vpc['cloud'] if peer['vpc']['cloud'].nil?
418
583
  siblings.each { |sib|
419
- if sib['name'] != peer['vpc']["vpc_name"]
584
+ if sib['name'] != peer['vpc']["name"]
420
585
  if sib['name'] != vpc['name']
421
586
  append_me = { "vpc" => peer["vpc"].dup }
422
- append_me['vpc']['vpc_name'] = sib['name']
587
+ append_me['vpc']['name'] = sib['name']
423
588
  append << append_me
424
589
  vpc["dependencies"] << {
425
590
  "type" => "vpc",
@@ -430,7 +595,7 @@ module MU
430
595
  else
431
596
  vpc["dependencies"] << {
432
597
  "type" => "vpc",
433
- "name" => peer['vpc']["vpc_name"]
598
+ "name" => peer['vpc']["name"]
434
599
  }
435
600
  end
436
601
  delete << peer if sib['name'] == vpc['name']
@@ -461,17 +626,19 @@ module MU
461
626
  ok
462
627
  end
463
628
 
629
+
630
+ @@reference_cache = {}
631
+
464
632
  # Pick apart an external VPC reference, validate it, and resolve it and its
465
633
  # various subnets and NAT hosts to live resources.
466
634
  # @param vpc_block [Hash]:
467
635
  # @param parent_type [String]:
468
- # @param parent_name [String]:
636
+ # @param parent [MU::Cloud::VPC]:
469
637
  # @param configurator [MU::Config]:
470
- # @param is_sibling [Boolean]:
471
638
  # @param sibling_vpcs [Array]:
472
639
  # @param dflt_region [String]:
473
- def self.processReference(vpc_block, parent_type, parent_name, configurator, is_sibling: false, sibling_vpcs: [], dflt_region: MU.curRegion, credentials: nil)
474
- puts vpc_block.ancestors if !vpc_block.is_a?(Hash)
640
+ def self.processReference(vpc_block, parent_type, parent, configurator, sibling_vpcs: [], dflt_region: MU.curRegion, dflt_project: nil, credentials: nil)
641
+
475
642
  if !vpc_block.is_a?(Hash) and vpc_block.kind_of?(MU::Cloud::VPC)
476
643
  return true
477
644
  end
@@ -480,8 +647,56 @@ module MU
480
647
  if vpc_block['region'].nil? and dflt_region and !dflt_region.empty?
481
648
  vpc_block['region'] = dflt_region.to_s
482
649
  end
650
+ dflt_region ||= vpc_block['region']
651
+ vpc_block['name'] ||= vpc_block['vpc_name'] if vpc_block['vpc_name']
652
+ vpc_block['id'] ||= vpc_block['vpc_id'] if vpc_block['vpc_id']
483
653
 
484
654
  vpc_block['credentials'] ||= credentials if credentials
655
+ vpc_block['project'] ||= dflt_project if dflt_project
656
+ vpc_block["cloud"] ||= parent["cloud"]
657
+
658
+ # XXX the right thing to do here is have a per-cloud callback hook for resolving
659
+ # projects/accounts/whatever, but for now let's get it working with Google's case
660
+ if vpc_block["cloud"] and vpc_block["cloud"] == "Google" and
661
+ vpc_block['project']
662
+ vpc_block["habitat"] ||= MU::Cloud::Google.projectToRef(vpc_block['project'], config: configurator, credentials: vpc_block['credentials']).to_h
663
+ vpc_block.delete("project")
664
+ end
665
+
666
+ # If this appears to be a sibling VPC that's destined to live in a
667
+ # sibling habitat, then by definition it doesn't exist yet. So don't
668
+ # try to do anything else clever here.
669
+ # XXX except maybe there's some stuff we should still do
670
+ if vpc_block["habitat"] and vpc_block["habitat"]["name"] and
671
+ !vpc_block["habitat"]["id"]
672
+ return ok
673
+ end
674
+
675
+ # Resolve "forked" Google VPCs to the correct literal resources, based
676
+ # on the original reference to the (now virtual) parent VPC and, if
677
+ # set, subnet_pref or subnet_name
678
+ sibling_vpcs.each { |sibling|
679
+ if sibling['virtual_name'] and
680
+ sibling['virtual_name'] == vpc_block['name']
681
+ if vpc_block['region'] and
682
+ sibling['regions'].include?(vpc_block['region'])
683
+ gateways = sibling['route_tables'].map { |rtb|
684
+ rtb['routes'].map { |r| r["gateway"] }
685
+ }.flatten.uniq
686
+ if ["public", "all_public"].include?(vpc_block['subnet_pref']) and
687
+ gateways.include?("#INTERNET")
688
+ vpc_block['name'] = sibling['name']
689
+ break
690
+ elsif ["private", "all_private"].include?(vpc_block['subnet_pref']) and
691
+ !gateways.include?("#INTERNET")
692
+ vpc_block['name'] = sibling['name']
693
+ break
694
+ end
695
+ end
696
+ end
697
+ }
698
+
699
+ is_sibling = (vpc_block['name'] and configurator.haveLitterMate?(vpc_block["name"], "vpcs"))
485
700
 
486
701
  # Sometimes people set subnet_pref to "private" or "public" when they
487
702
  # mean "all_private" or "all_public." Help them out.
@@ -496,27 +711,47 @@ module MU
496
711
 
497
712
  flags = {}
498
713
  flags["subnet_pref"] = vpc_block["subnet_pref"] if !vpc_block["subnet_pref"].nil?
714
+ hab_arg = if vpc_block['habitat']
715
+ if vpc_block['habitat'].is_a?(MU::Config::Ref)
716
+ [vpc_block['habitat'].id] # XXX actually, findStray it
717
+ elsif vpc_block['habitat'].is_a?(Hash)
718
+ [vpc_block['habitat']['id']] # XXX actually, findStray it
719
+ else
720
+ [vpc_block['habitat'].to_s]
721
+ end
722
+ elsif vpc_block['project']
723
+ [vpc_block['project']]
724
+ else
725
+ []
726
+ end
499
727
 
500
728
  # First, dig up the enclosing VPC
501
729
  tag_key, tag_value = vpc_block['tag'].split(/=/, 2) if !vpc_block['tag'].nil?
502
730
  if !is_sibling
503
731
  begin
504
732
  if vpc_block['cloud'] != "CloudFormation"
505
- found = MU::MommaCat.findStray(
506
- vpc_block['cloud'],
507
- "vpc",
508
- deploy_id: vpc_block["deploy_id"],
509
- cloud_id: vpc_block["vpc_id"],
510
- name: vpc_block["vpc_name"],
511
- credentials: vpc_block["credentials"],
512
- tag_key: tag_key,
513
- tag_value: tag_value,
514
- region: vpc_block["region"],
515
- flags: flags,
516
- dummy_ok: true
517
- )
518
-
519
- ext_vpc = found.first if found.size == 1
733
+ ext_vpc = if @@reference_cache[vpc_block]
734
+ MU.log "VPC lookup cache hit", MU::WARN, details: vpc_block
735
+ @@reference_cache[vpc_block]
736
+ else
737
+ found = MU::MommaCat.findStray(
738
+ vpc_block['cloud'],
739
+ "vpc",
740
+ deploy_id: vpc_block["deploy_id"],
741
+ cloud_id: vpc_block["id"],
742
+ name: vpc_block["name"],
743
+ credentials: vpc_block["credentials"],
744
+ tag_key: tag_key,
745
+ tag_value: tag_value,
746
+ region: vpc_block["region"],
747
+ flags: flags,
748
+ habitats: hab_arg,
749
+ dummy_ok: true
750
+ )
751
+
752
+ found.first if found and found.size == 1
753
+ end
754
+ @@reference_cache[vpc_block] ||= ext_vpc
520
755
 
521
756
  # Make sure we don't have a weird mismatch between requested
522
757
  # credential sets and the VPC we actually found
@@ -525,26 +760,27 @@ module MU
525
760
  if vpc_block['credentials'] and # probably can't happen
526
761
  vpc_block['credentials'] != ext_vpc.cloudobj.config["credentials"]
527
762
  ok = false
528
- MU.log "#{parent_type} #{parent_name} requested a VPC on credentials '#{vpc_block['credentials']}' but matched VPC is under credentials '#{ext_vpc.cloudobj.config["credentials"]}'", MU::ERR, details: vpc_block
763
+ MU.log "#{parent_type} #{parent['name']} requested a VPC on credentials '#{vpc_block['credentials']}' but matched VPC is under credentials '#{ext_vpc.cloudobj.config["credentials"]}'", MU::ERR, details: vpc_block
529
764
  end
530
765
  if credentials and
531
766
  credentials != ext_vpc.cloudobj.config["credentials"]
532
767
  ok = false
533
- MU.log "#{parent_type} #{parent_name} is using credentials '#{credentials}' but matched VPC is under credentials '#{ext_vpc.cloudobj.config["credentials"]}'", MU::ERR, details: vpc_block
768
+ MU.log "#{parent_type} #{parent['name']} is using credentials '#{credentials}' but matched VPC is under credentials '#{ext_vpc.cloudobj.config["credentials"]}'", MU::ERR, details: vpc_block
534
769
  end
770
+ @@reference_cache[vpc_block] ||= ext_vpc if ok
535
771
  vpc_block['credentials'] ||= ext_vpc.cloudobj.config["credentials"]
536
772
  end
537
-
773
+ @@reference_cache[vpc_block] ||= ext_vpc if ok
538
774
  end
539
775
  rescue Exception => e
540
776
  raise MuError, e.inspect, e.backtrace
541
777
  ensure
542
778
  if !ext_vpc and vpc_block['cloud'] != "CloudFormation"
543
- MU.log "Couldn't resolve VPC reference to a unique live VPC in #{parent_name} (called by #{caller[0]})", MU::ERR, details: vpc_block
779
+ MU.log "Couldn't resolve VPC reference to a unique live VPC in #{parent_type} #{parent['name']} (called by #{caller[0]})", MU::ERR, details: vpc_block
544
780
  return false
545
- elsif !vpc_block["vpc_id"]
546
- MU.log "Resolved VPC to #{ext_vpc.cloud_id} in #{parent_name}", MU::DEBUG, details: vpc_block
547
- vpc_block["vpc_id"] = configurator.getTail("#{parent_name} Target VPC", value: ext_vpc.cloud_id, prettyname: "#{parent_name} Target VPC", cloudtype: "AWS::EC2::VPC::Id")
781
+ elsif !vpc_block["id"]
782
+ MU.log "Resolved VPC to #{ext_vpc.cloud_id} in #{parent['name']}", MU::DEBUG, details: vpc_block
783
+ vpc_block["id"] = configurator.getTail("#{parent['name']} Target VPC", value: ext_vpc.cloud_id, prettyname: "#{parent['name']} Target VPC", cloudtype: "AWS::EC2::VPC::Id")
548
784
  end
549
785
  end
550
786
 
@@ -565,20 +801,20 @@ module MU
565
801
  nat_ip: vpc_block['nat_host_ip']
566
802
  )
567
803
  ssh_keydir = Etc.getpwnam(MU.mu_user).dir+"/.ssh"
568
- if !vpc_block['nat_ssh_key'].nil? and !File.exists?(ssh_keydir+"/"+vpc_block['nat_ssh_key'])
569
- MU.log "Couldn't find alternate NAT key #{ssh_keydir}/#{vpc_block['nat_ssh_key']} in #{parent_name}", MU::ERR, details: vpc_block
804
+ if !vpc_block['nat_ssh_key'].nil? and !File.exist?(ssh_keydir+"/"+vpc_block['nat_ssh_key'])
805
+ MU.log "Couldn't find alternate NAT key #{ssh_keydir}/#{vpc_block['nat_ssh_key']} in #{parent['name']}", MU::ERR, details: vpc_block
570
806
  return false
571
807
  end
572
808
 
573
809
  if !ext_nat
574
810
  if vpc_block["nat_host_id"].nil? and nat_tag_key.nil? and vpc_block['nat_host_ip'].nil? and vpc_block["deploy_id"].nil?
575
- MU.log "Couldn't resolve NAT host to a live instance in #{parent_name}.", MU::DEBUG, details: vpc_block
811
+ MU.log "Couldn't resolve NAT host to a live instance in #{parent['name']}.", MU::DEBUG, details: vpc_block
576
812
  else
577
- MU.log "Couldn't resolve NAT host to a live instance in #{parent_name}", MU::ERR, details: vpc_block
813
+ MU.log "Couldn't resolve NAT host to a live instance in #{parent['name']}", MU::ERR, details: vpc_block
578
814
  return false
579
815
  end
580
816
  elsif !vpc_block["nat_host_id"]
581
- MU.log "Resolved NAT host to #{ext_nat.cloud_id} in #{parent_name}", MU::DEBUG, details: vpc_block
817
+ MU.log "Resolved NAT host to #{ext_nat.cloud_id} in #{parent['name']}", MU::DEBUG, details: vpc_block
582
818
  vpc_block["nat_host_id"] = ext_nat.cloud_id
583
819
  vpc_block.delete('nat_host_name')
584
820
  vpc_block.delete('nat_host_ip')
@@ -600,13 +836,13 @@ module MU
600
836
 
601
837
  if ext_subnet.nil? and vpc_block["cloud"] != "CloudFormation"
602
838
  ok = false
603
- MU.log "Couldn't resolve subnet reference (list) in #{parent_name} to a live subnet", MU::ERR, details: subnet
839
+ MU.log "Couldn't resolve subnet reference (list) in #{parent['name']} to a live subnet", MU::ERR, details: subnet
604
840
  elsif !subnet['subnet_id']
605
841
  subnet['subnet_id'] = ext_subnet.cloud_id
606
842
  subnet['az'] = ext_subnet.az
607
843
  subnet.delete('subnet_name')
608
844
  subnet.delete('tag')
609
- MU.log "Resolved subnet reference in #{parent_name} to #{ext_subnet.cloud_id}", MU::DEBUG, details: subnet
845
+ MU.log "Resolved subnet reference in #{parent['name']} to #{ext_subnet.cloud_id}", MU::DEBUG, details: subnet
610
846
  end
611
847
  }
612
848
  # ...others single subnets
@@ -619,13 +855,13 @@ module MU
619
855
 
620
856
  if ext_subnet.nil?
621
857
  ok = false
622
- MU.log "Couldn't resolve subnet reference (name/id) in #{parent_name} to a live subnet", MU::ERR, details: vpc_block
858
+ MU.log "Couldn't resolve subnet reference (name/id) in #{parent['name']} to a live subnet", MU::ERR, details: vpc_block
623
859
  elsif !vpc_block['subnet_id']
624
860
  vpc_block['subnet_id'] = ext_subnet.cloud_id
625
861
  vpc_block['az'] = ext_subnet.az
626
862
  vpc_block.delete('subnet_name')
627
863
  vpc_block.delete('subnet_pref')
628
- MU.log "Resolved subnet reference in #{parent_name} to #{ext_subnet.cloud_id}", MU::DEBUG, details: vpc_block
864
+ MU.log "Resolved subnet reference in #{parent['name']} to #{ext_subnet.cloud_id}", MU::DEBUG, details: vpc_block
629
865
  end
630
866
  end
631
867
  end
@@ -641,7 +877,7 @@ module MU
641
877
  honor_subnet_prefs=false
642
878
  end
643
879
  if !subnet['subnet_id'].nil? and subnet['subnet_id'].is_a?(String)
644
- subnet['subnet_id'] = configurator.getTail("Subnet #{count} for #{parent_name}", value: subnet['subnet_id'], prettyname: "Subnet #{count} for #{parent_name}", cloudtype: "AWS::EC2::Subnet::Id")
880
+ subnet['subnet_id'] = configurator.getTail("Subnet #{count} for #{parent['name']}", value: subnet['subnet_id'], prettyname: "Subnet #{count} for #{parent['name']}", cloudtype: "AWS::EC2::Subnet::Id")
645
881
  count = count + 1
646
882
  end
647
883
  }
@@ -662,11 +898,11 @@ module MU
662
898
  ext_vpc.subnets.each { |subnet|
663
899
  next if dflt_region and vpc_block["cloud"] == "Google" and subnet.az != dflt_region
664
900
  if subnet.private? and (vpc_block['subnet_pref'] != "all_public" and vpc_block['subnet_pref'] != "public")
665
- private_subnets << { "subnet_id" => configurator.getTail("#{parent_name} Private Subnet #{priv}", value: subnet.cloud_id, prettyname: "#{parent_name} Private Subnet #{priv}", cloudtype: "AWS::EC2::Subnet::Id"), "az" => subnet.az }
901
+ private_subnets << { "subnet_id" => configurator.getTail("#{parent['name']} Private Subnet #{priv}", value: subnet.cloud_id, prettyname: "#{parent['name']} Private Subnet #{priv}", cloudtype: "AWS::EC2::Subnet::Id"), "az" => subnet.az }
666
902
  private_subnets_map[subnet.cloud_id] = subnet
667
903
  priv = priv + 1
668
904
  elsif !subnet.private? and vpc_block['subnet_pref'] != "all_private" and vpc_block['subnet_pref'] != "private"
669
- public_subnets << { "subnet_id" => configurator.getTail("#{parent_name} Public Subnet #{pub}", value: subnet.cloud_id, prettyname: "#{parent_name} Public Subnet #{pub}", cloudtype: "AWS::EC2::Subnet::Id"), "az" => subnet.az }
905
+ public_subnets << { "subnet_id" => configurator.getTail("#{parent['name']} Public Subnet #{pub}", value: subnet.cloud_id, prettyname: "#{parent['name']} Public Subnet #{pub}", cloudtype: "AWS::EC2::Subnet::Id"), "az" => subnet.az }
670
906
  public_subnets_map[subnet.cloud_id] = subnet
671
907
  pub = pub + 1
672
908
  else
@@ -674,12 +910,15 @@ module MU
674
910
  end
675
911
  }
676
912
  else
677
- sibling_vpcs.each { |ext_vpc|
678
- if ext_vpc['name'].to_s == vpc_block['vpc_name'].to_s and ext_vpc['subnets']
913
+ sibling_vpcs.each { |sibling_vpc|
914
+ if (sibling_vpc['name'].to_s == vpc_block['name'].to_s or
915
+ sibling_vpc['virtual_name'].to_s == vpc_block['name'].to_s) and
916
+ sibling_vpc['subnets']
679
917
  subnet_ptr = "subnet_name"
680
- ext_vpc['subnets'].each { |subnet|
681
- next if dflt_region and vpc_block["cloud"] == "Google" and subnet['availability_zone'] != dflt_region
682
- if subnet['is_public'] # NAT nonsense calculated elsewhere, ew
918
+
919
+ sibling_vpc['subnets'].each { |subnet|
920
+ next if dflt_region and vpc_block["cloud"].to_s == "Google" and subnet['availability_zone'] != dflt_region
921
+ if subnet['is_public']
683
922
  public_subnets << {"subnet_name" => subnet['name'].to_s}
684
923
  else
685
924
  private_subnets << {"subnet_name" => subnet['name'].to_s}
@@ -689,13 +928,12 @@ module MU
689
928
  end
690
929
  end
691
930
  }
692
- break
693
931
  end
694
932
  }
695
933
  end
696
934
 
697
935
  if public_subnets.size == 0 and private_subnets == 0
698
- MU.log "Couldn't find any subnets for #{parent_name}", MU::ERR
936
+ MU.log "Couldn't find any subnets for #{parent['name']}", MU::ERR
699
937
  return false
700
938
  end
701
939
  all_subnets = public_subnets + private_subnets
@@ -705,14 +943,16 @@ module MU
705
943
  if !public_subnets.nil? and public_subnets.size > 0
706
944
  vpc_block.merge!(public_subnets[rand(public_subnets.length)]) if public_subnets
707
945
  else
708
- MU.log "Public subnet requested for #{parent_name}, but none found in #{vpc_block}", MU::ERR
946
+ MU.log "Public subnet requested for #{parent_type} #{parent['name']}, but none found among #{all_subnets.join(", ")}", MU::ERR, details: vpc_block.to_h
947
+ pp is_sibling
709
948
  return false
710
949
  end
711
950
  when "private"
712
951
  if !private_subnets.nil? and private_subnets.size > 0
713
952
  vpc_block.merge!(private_subnets[rand(private_subnets.length)])
714
953
  else
715
- MU.log "Private subnet requested for #{parent_name}, but none found in #{vpc_block}", MU::ERR
954
+ MU.log "Private subnet requested for #{parent_type} #{parent['name']}, but none found among #{all_subnets.join(", ")}", MU::ERR, details: vpc_block.to_h
955
+ pp is_sibling
716
956
  return false
717
957
  end
718
958
  if !is_sibling and !private_subnets_map[vpc_block[subnet_ptr]].nil?
@@ -748,9 +988,9 @@ module MU
748
988
  else
749
989
  vpc_block['subnets'] ||= []
750
990
 
751
- sibling_vpcs.each { |ext_vpc|
752
- next if ext_vpc["name"] != vpc_block["vpc_name"]
753
- ext_vpc["subnets"].each { |subnet|
991
+ sibling_vpcs.each { |sibling_vpc|
992
+ next if sibling_vpc["name"] != vpc_block["name"]
993
+ sibling_vpc["subnets"].each { |subnet|
754
994
  if subnet["route_table"] == vpc_block["subnet_pref"]
755
995
  vpc_block["subnets"] << subnet
756
996
  end
@@ -784,16 +1024,16 @@ module MU
784
1024
  }
785
1025
  end
786
1026
 
787
- vpc_block.delete('deploy_id')
788
- vpc_block.delete('vpc_name') if vpc_block.has_key?('vpc_id')
1027
+ vpc_block.delete('id') if vpc_block['id'].nil?
1028
+ vpc_block.delete('name') if vpc_block.has_key?('id')
789
1029
  vpc_block.delete('tag')
790
- MU.log "Resolved VPC resources for #{parent_name}", MU::DEBUG, details: vpc_block
1030
+ MU.log "Resolved VPC resources for #{parent['name']}", MU::DEBUG, details: vpc_block
791
1031
  end
792
1032
 
793
- if !vpc_block["vpc_id"].nil? and vpc_block["vpc_id"].is_a?(String)
794
- vpc_block["vpc_id"] = configurator.getTail("#{parent_name}vpc_id", value: vpc_block["vpc_id"], prettyname: "#{parent_name} Target VPC", cloudtype: "AWS::EC2::VPC::Id")
1033
+ if !vpc_block["id"].nil? and vpc_block["id"].is_a?(String)
1034
+ vpc_block["id"] = configurator.getTail("#{parent['name']}_id", value: vpc_block["id"], prettyname: "#{parent['name']} Target VPC", cloudtype: "AWS::EC2::VPC::Id")
795
1035
  elsif !vpc_block["nat_host_name"].nil? and vpc_block["nat_host_name"].is_a?(String)
796
- vpc_block["nat_host_name"] = MU::Config::Tail.new("#{parent_name}nat_host_name", vpc_block["nat_host_name"])
1036
+ vpc_block["nat_host_name"] = MU::Config::Tail.new("#{parent['name']}nat_host_name", vpc_block["nat_host_name"])
797
1037
 
798
1038
  end
799
1039