jets-fs 1.6.10

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 (379) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/bin/commit_docs.sh +26 -0
  3. data/.circleci/config.yml +126 -0
  4. data/.codebuild/README.md +68 -0
  5. data/.codebuild/bin/jets +3 -0
  6. data/.codebuild/buildspec-base.yml +14 -0
  7. data/.codebuild/integration.sh +72 -0
  8. data/.codebuild/jets.postman_collection.json +323 -0
  9. data/.codebuild/scripts/install-docker.sh +12 -0
  10. data/.codebuild/scripts/install-dynamodb-local.sh +22 -0
  11. data/.codebuild/scripts/install-java.sh +22 -0
  12. data/.codebuild/scripts/install-node.sh +4 -0
  13. data/.github/ISSUE_TEMPLATE.md +7 -0
  14. data/.github/ISSUE_TEMPLATE/bug_report.md +73 -0
  15. data/.github/ISSUE_TEMPLATE/documentation.md +27 -0
  16. data/.github/ISSUE_TEMPLATE/feature_request.md +64 -0
  17. data/.github/ISSUE_TEMPLATE/question.md +16 -0
  18. data/.github/PULL_REQUEST_TEMPLATE.md +42 -0
  19. data/.gitignore +24 -0
  20. data/.gitmodules +6 -0
  21. data/.python-version +1 -0
  22. data/.rspec +4 -0
  23. data/.ruby-version +1 -0
  24. data/CHANGELOG.md +533 -0
  25. data/Dockerfile +16 -0
  26. data/Dockerfile.base +53 -0
  27. data/Gemfile +14 -0
  28. data/Gemfile.lock +190 -0
  29. data/Guardfile +22 -0
  30. data/LICENSE.txt +22 -0
  31. data/Procfile +2 -0
  32. data/README.md +203 -0
  33. data/Rakefile +21 -0
  34. data/backers.md +16 -0
  35. data/bin/release +9 -0
  36. data/buildspec.yml +18 -0
  37. data/exe/jets +14 -0
  38. data/jets.gemspec +61 -0
  39. data/lib/jets.rb +71 -0
  40. data/lib/jets/application.rb +308 -0
  41. data/lib/jets/aws_info.rb +111 -0
  42. data/lib/jets/aws_services.rb +60 -0
  43. data/lib/jets/aws_services/stack_status.rb +59 -0
  44. data/lib/jets/booter.rb +130 -0
  45. data/lib/jets/builders.rb +16 -0
  46. data/lib/jets/builders/code_builder.rb +379 -0
  47. data/lib/jets/builders/code_size.rb +57 -0
  48. data/lib/jets/builders/gem_replacer.rb +76 -0
  49. data/lib/jets/builders/handler_generator.rb +172 -0
  50. data/lib/jets/builders/lambda_layer.rb +69 -0
  51. data/lib/jets/builders/md5.rb +60 -0
  52. data/lib/jets/builders/md5_zip.rb +61 -0
  53. data/lib/jets/builders/purger.rb +35 -0
  54. data/lib/jets/builders/rack_packager.rb +51 -0
  55. data/lib/jets/builders/rackup_wrappers/rackup +19 -0
  56. data/lib/jets/builders/rackup_wrappers/rackup.rb +7 -0
  57. data/lib/jets/builders/reconfigure_rails.rb +114 -0
  58. data/lib/jets/builders/reconfigure_rails/config/initializers/jets.rb +16 -0
  59. data/lib/jets/builders/ruby_packager.rb +207 -0
  60. data/lib/jets/builders/shim_vars.rb +5 -0
  61. data/lib/jets/builders/shim_vars/app.rb +78 -0
  62. data/lib/jets/builders/shim_vars/base.rb +25 -0
  63. data/lib/jets/builders/shim_vars/shared.rb +37 -0
  64. data/lib/jets/builders/templates/handler.rb +12 -0
  65. data/lib/jets/builders/tidy.rb +107 -0
  66. data/lib/jets/builders/util.rb +31 -0
  67. data/lib/jets/camelizer.rb +67 -0
  68. data/lib/jets/cfn.rb +6 -0
  69. data/lib/jets/cfn/builders.rb +20 -0
  70. data/lib/jets/cfn/builders/api_deployment_builder.rb +58 -0
  71. data/lib/jets/cfn/builders/api_gateway_builder.rb +80 -0
  72. data/lib/jets/cfn/builders/base_child_builder.rb +82 -0
  73. data/lib/jets/cfn/builders/controller_builder.rb +42 -0
  74. data/lib/jets/cfn/builders/function_builder.rb +14 -0
  75. data/lib/jets/cfn/builders/interface.rb +127 -0
  76. data/lib/jets/cfn/builders/job_builder.rb +14 -0
  77. data/lib/jets/cfn/builders/parent_builder.rb +93 -0
  78. data/lib/jets/cfn/builders/rule_builder.rb +24 -0
  79. data/lib/jets/cfn/builders/shared_builder.rb +14 -0
  80. data/lib/jets/cfn/ship.rb +189 -0
  81. data/lib/jets/cfn/status.rb +212 -0
  82. data/lib/jets/cfn/upload.rb +139 -0
  83. data/lib/jets/cli.rb +189 -0
  84. data/lib/jets/commands.rb +27 -0
  85. data/lib/jets/commands/base.rb +164 -0
  86. data/lib/jets/commands/build.rb +217 -0
  87. data/lib/jets/commands/call.rb +174 -0
  88. data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
  89. data/lib/jets/commands/call/autoload_guesser.rb +112 -0
  90. data/lib/jets/commands/call/base_guesser.rb +33 -0
  91. data/lib/jets/commands/call/guesser.rb +48 -0
  92. data/lib/jets/commands/clean.rb +23 -0
  93. data/lib/jets/commands/clean/base.rb +24 -0
  94. data/lib/jets/commands/clean/build.rb +13 -0
  95. data/lib/jets/commands/clean/log.rb +107 -0
  96. data/lib/jets/commands/console.rb +13 -0
  97. data/lib/jets/commands/db.rb +15 -0
  98. data/lib/jets/commands/db/environment-task.rake +3 -0
  99. data/lib/jets/commands/db/tasks.rb +44 -0
  100. data/lib/jets/commands/dbconsole.rb +131 -0
  101. data/lib/jets/commands/delete.rb +143 -0
  102. data/lib/jets/commands/deploy.rb +131 -0
  103. data/lib/jets/commands/dynamodb.rb +22 -0
  104. data/lib/jets/commands/dynamodb/migrate.rb +9 -0
  105. data/lib/jets/commands/dynamodb/migrator.rb +36 -0
  106. data/lib/jets/commands/gems.rb +21 -0
  107. data/lib/jets/commands/help.rb +9 -0
  108. data/lib/jets/commands/help/build.md +6 -0
  109. data/lib/jets/commands/help/call.md +61 -0
  110. data/lib/jets/commands/help/clean/build.md +5 -0
  111. data/lib/jets/commands/help/clean/log.md +5 -0
  112. data/lib/jets/commands/help/console.md +18 -0
  113. data/lib/jets/commands/help/db/generate.md +8 -0
  114. data/lib/jets/commands/help/dbconsole.md +9 -0
  115. data/lib/jets/commands/help/delete.md +22 -0
  116. data/lib/jets/commands/help/deploy.md +32 -0
  117. data/lib/jets/commands/help/dynamodb/generate.md +52 -0
  118. data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
  119. data/lib/jets/commands/help/gems/check.md +8 -0
  120. data/lib/jets/commands/help/generate.md +22 -0
  121. data/lib/jets/commands/help/import/rack.md +13 -0
  122. data/lib/jets/commands/help/import/rails.md +11 -0
  123. data/lib/jets/commands/help/new.md +42 -0
  124. data/lib/jets/commands/help/routes.md +16 -0
  125. data/lib/jets/commands/help/runner.md +17 -0
  126. data/lib/jets/commands/help/server.md +15 -0
  127. data/lib/jets/commands/help/status.md +14 -0
  128. data/lib/jets/commands/help/upgrade.md +5 -0
  129. data/lib/jets/commands/help/url.md +6 -0
  130. data/lib/jets/commands/import.rb +18 -0
  131. data/lib/jets/commands/import/base.rb +49 -0
  132. data/lib/jets/commands/import/cheatsheet.rb +35 -0
  133. data/lib/jets/commands/import/rack.rb +16 -0
  134. data/lib/jets/commands/import/rail.rb +74 -0
  135. data/lib/jets/commands/import/sequence.rb +90 -0
  136. data/lib/jets/commands/import/templates/config/database.yml +26 -0
  137. data/lib/jets/commands/import/templates/submodules-cheatsheet.md +89 -0
  138. data/lib/jets/commands/main.rb +152 -0
  139. data/lib/jets/commands/markdown.rb +8 -0
  140. data/lib/jets/commands/markdown/creator.rb +58 -0
  141. data/lib/jets/commands/markdown/index.rb +27 -0
  142. data/lib/jets/commands/markdown/page.rb +125 -0
  143. data/lib/jets/commands/markdown/shell.rb +11 -0
  144. data/lib/jets/commands/new.rb +157 -0
  145. data/lib/jets/commands/rake_command.rb +61 -0
  146. data/lib/jets/commands/rake_tasks.rb +45 -0
  147. data/lib/jets/commands/runner.rb +18 -0
  148. data/lib/jets/commands/sequence.rb +99 -0
  149. data/lib/jets/commands/stack_info.rb +30 -0
  150. data/lib/jets/commands/templates/skeleton/.gitignore +12 -0
  151. data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
  152. data/lib/jets/commands/templates/skeleton/.rspec +3 -0
  153. data/lib/jets/commands/templates/skeleton/Gemfile.tt +35 -0
  154. data/lib/jets/commands/templates/skeleton/Procfile +7 -0
  155. data/lib/jets/commands/templates/skeleton/README.md +11 -0
  156. data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
  157. data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
  158. data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
  159. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +4 -0
  160. data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
  161. data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
  162. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +25 -0
  163. data/lib/jets/commands/templates/skeleton/config.ru +5 -0
  164. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +66 -0
  165. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +26 -0
  166. data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +22 -0
  167. data/lib/jets/commands/templates/skeleton/config/environments/development.rb +4 -0
  168. data/lib/jets/commands/templates/skeleton/config/environments/production.rb +4 -0
  169. data/lib/jets/commands/templates/skeleton/config/routes.rb +9 -0
  170. data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
  171. data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
  172. data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
  173. data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
  174. data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
  175. data/lib/jets/commands/templates/skeleton/public/index.html.tt +91 -0
  176. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +15 -0
  177. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
  178. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
  179. data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +30 -0
  180. data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +14 -0
  181. data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
  182. data/lib/jets/commands/templates/webpacker/app/javascript/src/jets/crud.js +87 -0
  183. data/lib/jets/commands/upgrade.rb +146 -0
  184. data/lib/jets/commands/upgrade/templates/bin/webpack +19 -0
  185. data/lib/jets/commands/upgrade/templates/bin/webpack-dev-server +19 -0
  186. data/lib/jets/commands/url.rb +68 -0
  187. data/lib/jets/commands/webpacker_template.rb +18 -0
  188. data/lib/jets/controller.rb +16 -0
  189. data/lib/jets/controller/base.rb +103 -0
  190. data/lib/jets/controller/callbacks.rb +62 -0
  191. data/lib/jets/controller/cookies.rb +40 -0
  192. data/lib/jets/controller/cookies/jar.rb +269 -0
  193. data/lib/jets/controller/layout.rb +17 -0
  194. data/lib/jets/controller/middleware.rb +5 -0
  195. data/lib/jets/controller/middleware/cors.rb +60 -0
  196. data/lib/jets/controller/middleware/local.rb +119 -0
  197. data/lib/jets/controller/middleware/local/api_gateway.rb +93 -0
  198. data/lib/jets/controller/middleware/local/mimic_aws_call.rb +38 -0
  199. data/lib/jets/controller/middleware/local/route_matcher.rb +97 -0
  200. data/lib/jets/controller/middleware/main.rb +46 -0
  201. data/lib/jets/controller/middleware/webpacker_setup.rb +6 -0
  202. data/lib/jets/controller/params.rb +87 -0
  203. data/lib/jets/controller/rack.rb +5 -0
  204. data/lib/jets/controller/rack/adapter.rb +63 -0
  205. data/lib/jets/controller/rack/env.rb +105 -0
  206. data/lib/jets/controller/redirection.rb +55 -0
  207. data/lib/jets/controller/rendering.rb +84 -0
  208. data/lib/jets/controller/rendering/rack_renderer.rb +238 -0
  209. data/lib/jets/controller/request.rb +29 -0
  210. data/lib/jets/controller/response.rb +61 -0
  211. data/lib/jets/core.rb +211 -0
  212. data/lib/jets/core_ext/kernel.rb +56 -0
  213. data/lib/jets/db.rb +15 -0
  214. data/lib/jets/dotenv.rb +39 -0
  215. data/lib/jets/erb.rb +51 -0
  216. data/lib/jets/generator.rb +41 -0
  217. data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
  218. data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +39 -0
  219. data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
  220. data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
  221. data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
  222. data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
  223. data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
  224. data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
  225. data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
  226. data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
  227. data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
  228. data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
  229. data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +79 -0
  230. data/lib/jets/inflections.rb +32 -0
  231. data/lib/jets/internal/app/controllers/jets/public_controller.rb +31 -0
  232. data/lib/jets/internal/app/controllers/jets/rack_controller.rb +25 -0
  233. data/lib/jets/internal/app/functions/jets/base_path.rb +153 -0
  234. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +62 -0
  235. data/lib/jets/io.rb +14 -0
  236. data/lib/jets/job.rb +4 -0
  237. data/lib/jets/job/base.rb +29 -0
  238. data/lib/jets/job/dsl.rb +108 -0
  239. data/lib/jets/klass.rb +109 -0
  240. data/lib/jets/lambda.rb +18 -0
  241. data/lib/jets/lambda/dsl.rb +384 -0
  242. data/lib/jets/lambda/function.rb +29 -0
  243. data/lib/jets/lambda/function_constructor.rb +55 -0
  244. data/lib/jets/lambda/functions.rb +34 -0
  245. data/lib/jets/lambda/task.rb +111 -0
  246. data/lib/jets/logger.rb +24 -0
  247. data/lib/jets/mega.rb +7 -0
  248. data/lib/jets/mega/hash_converter.rb +25 -0
  249. data/lib/jets/mega/request.rb +140 -0
  250. data/lib/jets/mega/request/source.rb +21 -0
  251. data/lib/jets/middleware.rb +38 -0
  252. data/lib/jets/middleware/configurator.rb +84 -0
  253. data/lib/jets/middleware/default_stack.rb +49 -0
  254. data/lib/jets/middleware/layer.rb +34 -0
  255. data/lib/jets/middleware/stack.rb +77 -0
  256. data/lib/jets/naming.rb +49 -0
  257. data/lib/jets/overrides/lambda.rb +1 -0
  258. data/lib/jets/overrides/lambda/marshaller.rb +31 -0
  259. data/lib/jets/overrides/rails.rb +4 -0
  260. data/lib/jets/overrides/rails/asset_tag_helper.rb +114 -0
  261. data/lib/jets/overrides/rails/common_methods.rb +20 -0
  262. data/lib/jets/overrides/rails/rendering_helper.rb +26 -0
  263. data/lib/jets/overrides/rails/url_helper.rb +25 -0
  264. data/lib/jets/poly_fun.rb +82 -0
  265. data/lib/jets/poly_fun/base_executor.rb +125 -0
  266. data/lib/jets/poly_fun/lambda_executor.rb +16 -0
  267. data/lib/jets/poly_fun/node_error.rb +8 -0
  268. data/lib/jets/poly_fun/node_executor.rb +54 -0
  269. data/lib/jets/poly_fun/python_error.rb +8 -0
  270. data/lib/jets/poly_fun/python_executor.rb +23 -0
  271. data/lib/jets/preheat.rb +117 -0
  272. data/lib/jets/processors.rb +4 -0
  273. data/lib/jets/processors/deducer.rb +65 -0
  274. data/lib/jets/processors/main_processor.rb +59 -0
  275. data/lib/jets/rack_server.rb +80 -0
  276. data/lib/jets/rdoc.rb +30 -0
  277. data/lib/jets/resource.rb +74 -0
  278. data/lib/jets/resource/api_gateway.rb +9 -0
  279. data/lib/jets/resource/api_gateway/base_path.rb +5 -0
  280. data/lib/jets/resource/api_gateway/base_path/function.rb +42 -0
  281. data/lib/jets/resource/api_gateway/base_path/mapping.rb +44 -0
  282. data/lib/jets/resource/api_gateway/base_path/role.rb +76 -0
  283. data/lib/jets/resource/api_gateway/cors.rb +61 -0
  284. data/lib/jets/resource/api_gateway/deployment.rb +78 -0
  285. data/lib/jets/resource/api_gateway/domain_name.rb +59 -0
  286. data/lib/jets/resource/api_gateway/method.rb +98 -0
  287. data/lib/jets/resource/api_gateway/resource.rb +78 -0
  288. data/lib/jets/resource/api_gateway/rest_api.rb +60 -0
  289. data/lib/jets/resource/api_gateway/rest_api/change_detection.rb +42 -0
  290. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +63 -0
  291. data/lib/jets/resource/api_gateway/rest_api/routes.rb +11 -0
  292. data/lib/jets/resource/api_gateway/rest_api/routes/change.rb +12 -0
  293. data/lib/jets/resource/api_gateway/rest_api/routes/change/base.rb +130 -0
  294. data/lib/jets/resource/api_gateway/rest_api/routes/change/to.rb +29 -0
  295. data/lib/jets/resource/api_gateway/rest_api/routes/change/variable.rb +39 -0
  296. data/lib/jets/resource/api_gateway/rest_api/routes/collision.rb +123 -0
  297. data/lib/jets/resource/api_gateway/rest_api/routes/collision/variable_exception.rb +7 -0
  298. data/lib/jets/resource/associated.rb +26 -0
  299. data/lib/jets/resource/base.rb +28 -0
  300. data/lib/jets/resource/child_stack.rb +7 -0
  301. data/lib/jets/resource/child_stack/api_deployment.rb +56 -0
  302. data/lib/jets/resource/child_stack/api_gateway.rb +29 -0
  303. data/lib/jets/resource/child_stack/app_class.rb +112 -0
  304. data/lib/jets/resource/child_stack/base.rb +24 -0
  305. data/lib/jets/resource/child_stack/shared.rb +90 -0
  306. data/lib/jets/resource/config.rb +4 -0
  307. data/lib/jets/resource/config/config_rule.rb +74 -0
  308. data/lib/jets/resource/config/managed_rule.rb +15 -0
  309. data/lib/jets/resource/events.rb +3 -0
  310. data/lib/jets/resource/events/rule.rb +31 -0
  311. data/lib/jets/resource/iam.rb +8 -0
  312. data/lib/jets/resource/iam/application_role.rb +27 -0
  313. data/lib/jets/resource/iam/base_role_definition.rb +47 -0
  314. data/lib/jets/resource/iam/class_role.rb +74 -0
  315. data/lib/jets/resource/iam/function_role.rb +54 -0
  316. data/lib/jets/resource/iam/managed_policy.rb +22 -0
  317. data/lib/jets/resource/iam/policy_document.rb +41 -0
  318. data/lib/jets/resource/lambda.rb +5 -0
  319. data/lib/jets/resource/lambda/function.rb +216 -0
  320. data/lib/jets/resource/lambda/function/environment.rb +61 -0
  321. data/lib/jets/resource/lambda/gem_layer.rb +17 -0
  322. data/lib/jets/resource/lambda/layer_version.rb +44 -0
  323. data/lib/jets/resource/permission.rb +45 -0
  324. data/lib/jets/resource/replacer.rb +77 -0
  325. data/lib/jets/resource/route53.rb +3 -0
  326. data/lib/jets/resource/route53/record_set.rb +70 -0
  327. data/lib/jets/resource/s3.rb +17 -0
  328. data/lib/jets/resource/sns.rb +3 -0
  329. data/lib/jets/resource/sqs.rb +3 -0
  330. data/lib/jets/resource/standardizer.rb +42 -0
  331. data/lib/jets/route.rb +166 -0
  332. data/lib/jets/router.rb +175 -0
  333. data/lib/jets/router/scope.rb +30 -0
  334. data/lib/jets/rule.rb +4 -0
  335. data/lib/jets/rule/base.rb +19 -0
  336. data/lib/jets/rule/dsl.rb +110 -0
  337. data/lib/jets/spec_helpers.rb +52 -0
  338. data/lib/jets/spec_helpers/params.rb +10 -0
  339. data/lib/jets/spec_helpers/request.rb +98 -0
  340. data/lib/jets/spec_helpers/response.rb +5 -0
  341. data/lib/jets/stack.rb +103 -0
  342. data/lib/jets/stack/builder.rb +38 -0
  343. data/lib/jets/stack/definition.rb +50 -0
  344. data/lib/jets/stack/function.rb +60 -0
  345. data/lib/jets/stack/main.rb +5 -0
  346. data/lib/jets/stack/main/dsl.rb +33 -0
  347. data/lib/jets/stack/main/extensions/base.rb +45 -0
  348. data/lib/jets/stack/main/extensions/cloudwatch.rb +19 -0
  349. data/lib/jets/stack/main/extensions/lambda.rb +71 -0
  350. data/lib/jets/stack/main/extensions/sns.rb +12 -0
  351. data/lib/jets/stack/main/extensions/sqs.rb +36 -0
  352. data/lib/jets/stack/output.rb +38 -0
  353. data/lib/jets/stack/output/dsl.rb +19 -0
  354. data/lib/jets/stack/output/lookup.rb +36 -0
  355. data/lib/jets/stack/parameter.rb +38 -0
  356. data/lib/jets/stack/parameter/dsl.rb +42 -0
  357. data/lib/jets/stack/resource.rb +32 -0
  358. data/lib/jets/stack/resource/dsl.rb +19 -0
  359. data/lib/jets/tmp_loader.rb +52 -0
  360. data/lib/jets/turbine.rb +30 -0
  361. data/lib/jets/turbo.rb +47 -0
  362. data/lib/jets/turbo/database_yaml.rb +41 -0
  363. data/lib/jets/turbo/project/.gitignore +12 -0
  364. data/lib/jets/turbo/project/.jetskeep +1 -0
  365. data/lib/jets/turbo/project/Gemfile +16 -0
  366. data/lib/jets/turbo/project/Rakefile +2 -0
  367. data/lib/jets/turbo/project/app/controllers/application_controller.rb +2 -0
  368. data/lib/jets/turbo/project/app/helpers/application_helper.rb +2 -0
  369. data/lib/jets/turbo/project/app/jobs/application_job.rb +4 -0
  370. data/lib/jets/turbo/project/config.ru +5 -0
  371. data/lib/jets/turbo/project/config/application.rb +4 -0
  372. data/lib/jets/turbo/project/config/routes.rb +4 -0
  373. data/lib/jets/turbo/rail.rb +113 -0
  374. data/lib/jets/turbo/templates/config/database.yml +26 -0
  375. data/lib/jets/util.rb +38 -0
  376. data/lib/jets/version.rb +3 -0
  377. data/readme/prerelease.md +6 -0
  378. data/readme/testing.md +60 -0
  379. metadata +859 -0
@@ -0,0 +1,24 @@
1
+ # Implements:
2
+ #
3
+ # compose
4
+ # template_path
5
+ #
6
+ class Jets::Cfn::Builders
7
+ class RuleBuilder < BaseChildBuilder
8
+ def compose
9
+ add_common_parameters
10
+ add_functions
11
+ add_resources
12
+ add_managed_rules
13
+ end
14
+
15
+ # Handle config_rules associated with aws managed rules.
16
+ # List of AWS Config Managed Rules: https://amzn.to/2BOt9KN
17
+ def add_managed_rules
18
+ @app_class.managed_rules.each do |rule|
19
+ resource = Jets::Resource.new(rule[:definition], rule[:replacements])
20
+ add_resource(resource)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ class Jets::Cfn::Builders
2
+ class SharedBuilder < BaseChildBuilder
3
+ def compose
4
+ stack = @app_class.new # @app_class is subclass. IE: Alarm < Jets::Stack
5
+ builder = Jets::Stack::Builder.new(stack)
6
+ @template = builder.template # overwrite entire @template
7
+ end
8
+
9
+ # template_path is an interface method for Interface module
10
+ def template_path
11
+ Jets::Naming.shared_template_path(@app_class)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,189 @@
1
+ class Jets::Cfn
2
+ class Ship
3
+ extend Memoist
4
+ include Jets::AwsServices
5
+
6
+ def initialize(options)
7
+ @options = options
8
+ @parent_stack_name = Jets::Naming.parent_stack_name
9
+ @template_path = Jets::Naming.parent_template_path
10
+ end
11
+
12
+ def run
13
+ # s3 bucket is available only when stack_type is full
14
+ upload_to_s3 if @options[:stack_type] == :full
15
+
16
+ stack_in_progress?(@parent_stack_name)
17
+
18
+ puts "Deploying CloudFormation stack with jets app!"
19
+ begin
20
+ save_stack
21
+ rescue Aws::CloudFormation::Errors::InsufficientCapabilitiesException => e
22
+ capabilities = e.message.match(/\[(.*)\]/)[1]
23
+ confirm = prompt_for_iam(capabilities)
24
+ if confirm =~ /^y/
25
+ @options.merge!(capabilities: [capabilities])
26
+ puts "Re-running: #{command_with_iam(capabilities).color(:green)}"
27
+ retry
28
+ else
29
+ puts "Exited"
30
+ exit 1
31
+ end
32
+ end
33
+
34
+ success = wait_for_stack
35
+ unless success
36
+ puts <<~EOL
37
+ The Jets application failed to deploy. Jets creates a few CloudFormation stacks to deploy your application.
38
+ The logs above show the CloudFormation parent stack events and points to the stack with the error.
39
+ Please go to the CloudFormation console and look for the specific stack with the error.
40
+ The specific child stack usually shows more detailed information and can be used to resolve the issue.
41
+ Example of checking the CloudFormation console: http://rubyonjets.com/docs/debugging-cloudformation/
42
+ EOL
43
+ return
44
+ end
45
+
46
+ prewarm
47
+ clean_deploy_logs
48
+ show_api_endpoint
49
+ show_custom_domain
50
+ end
51
+
52
+ def save_stack
53
+ if stack_exists?(@parent_stack_name)
54
+ update_stack
55
+ else
56
+ create_stack
57
+ end
58
+ end
59
+
60
+ def create_stack
61
+ # parent stack template is on filesystem and child stacks templates is on s3
62
+ cfn.create_stack(stack_options)
63
+ end
64
+
65
+ def update_stack
66
+ begin
67
+ cfn.update_stack(stack_options)
68
+ rescue Aws::CloudFormation::Errors::ValidationError => e
69
+ puts "ERROR: #{e.message}".red
70
+ true # error
71
+ end
72
+ end
73
+
74
+ # options common to both create_stack and update_stack
75
+ def stack_options
76
+ {
77
+ stack_name: @parent_stack_name,
78
+ template_body: IO.read(@template_path),
79
+ capabilities: capabilities, # ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
80
+ # disable_rollback: !@options[:rollback],
81
+ }
82
+ end
83
+
84
+ # check for /(_COMPLETE|_FAILED)$/ status
85
+ def wait_for_stack
86
+ Jets::Cfn::Status.new(@options).wait
87
+ end
88
+
89
+ def prewarm
90
+ if ENV['SKIP_PREWARMING']
91
+ puts "Skipping prewarming" # useful for testing
92
+ return
93
+ end
94
+ return unless @options[:stack_type] == :full # s3 bucket is available
95
+ return unless Jets.config.prewarm.enable
96
+ return if Jets.poly_only?
97
+
98
+ puts "Prewarming application."
99
+ if Jets::PreheatJob::CONCURRENCY > 1
100
+ Jets::PreheatJob.perform_now(:torch, {quiet: true})
101
+ else
102
+ Jets::PreheatJob.perform_now(:warm, {quiet: true})
103
+ end
104
+ end
105
+
106
+ def clean_deploy_logs
107
+ Jets::Commands::Clean::Log.new.clean_deploys
108
+ end
109
+
110
+ def endpoint_unavailable?
111
+ return true unless @options[:stack_type] == :full # s3 bucket is available
112
+ return true if Jets::Router.routes.empty?
113
+ _, status = stack_status
114
+ return true if status.include?("ROLLBACK")
115
+ return true unless api_gateway
116
+ end
117
+
118
+ # Do not memoize this because on first stack run it will be nil
119
+ # It only gets called one more time so just let it get called.
120
+ def api_gateway
121
+ resp = cfn.describe_stack_resources(stack_name: @parent_stack_name)
122
+ resources = resp.stack_resources
123
+ resources.find { |resource| resource.logical_resource_id == "ApiGateway" }
124
+ end
125
+ memoize :api_gateway
126
+
127
+ def endpoint_available?
128
+ !endpoint_unavailable?
129
+ end
130
+
131
+ def show_api_endpoint
132
+ return unless endpoint_available?
133
+
134
+ stack_id = api_gateway["physical_resource_id"]
135
+
136
+ resp = cfn.describe_stacks(stack_name: stack_id)
137
+ stack = resp["stacks"].first
138
+ output = stack["outputs"].find { |o| o["output_key"] == "RestApiUrl" }
139
+ endpoint = output["output_value"]
140
+ puts "API Gateway Endpoint: #{endpoint}"
141
+ end
142
+
143
+ def show_custom_domain
144
+ return unless endpoint_available? && Jets.custom_domain? && Jets.config.domain.route53
145
+
146
+ domain_name = Jets::Resource::ApiGateway::DomainName.new
147
+ # Looks funny but its right.
148
+ # domain_name is a method on the Jets::Resource::ApiGateway::Domain instance
149
+ url = "https://#{domain_name.domain_name}"
150
+ puts "Custom Domain: #{url}"
151
+ end
152
+
153
+ # All CloudFormation states listed here:
154
+ # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-describing-stacks.html
155
+ def stack_status
156
+ resp = cfn.describe_stacks(stack_name: @parent_stack_name)
157
+ status = resp.stacks[0].stack_status
158
+ [resp, status]
159
+ end
160
+
161
+ def prompt_for_iam(capabilities)
162
+ puts "This stack will create IAM resources. Please approve to run the command again with #{capabilities} capabilities."
163
+ puts " #{command_with_iam(capabilities)}"
164
+
165
+ puts "Please confirm (y/n)"
166
+ $stdin.gets # confirm
167
+ end
168
+
169
+ def command_with_iam(capabilities)
170
+ "#{File.basename($0)} #{ARGV.join(' ')} --capabilities #{capabilities}"
171
+ end
172
+
173
+ def capabilities
174
+ ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"] # TODO: remove capabilities hardcode
175
+ # return @options[:capabilities] if @options[:capabilities]
176
+ # if @options[:iam]
177
+ # ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
178
+ # end
179
+ end
180
+
181
+ # Upload both code and child templates to s3
182
+ def upload_to_s3
183
+ raise "Did not specify @options[:s3_bucket] #{@options[:s3_bucket].inspect}" unless @options[:s3_bucket]
184
+
185
+ uploader = Upload.new(@options[:s3_bucket])
186
+ uploader.upload
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,212 @@
1
+ class Jets::Cfn
2
+ class Status
3
+ include Jets::AwsServices
4
+
5
+ attr_reader :events
6
+ def initialize(options={})
7
+ @options = options
8
+ @stack_name = Jets::Naming.parent_stack_name
9
+ reset
10
+ end
11
+
12
+ # used for the jets status command
13
+ def run
14
+ unless stack_exists?(@stack_name)
15
+ puts "The stack #{@stack_name.color(:green)} does not exist."
16
+ return
17
+ end
18
+
19
+ resp = cfn.describe_stacks(stack_name: @stack_name)
20
+ stack = resp.stacks.first
21
+
22
+ puts "The current status for the stack #{@stack_name.color(:green)} is #{stack.stack_status.color(:green)}"
23
+ if stack.stack_status =~ /_IN_PROGRESS$/
24
+ puts "Stack events (tailing):"
25
+ # tail all events until done
26
+ @hide_time_took = true
27
+ wait
28
+ else
29
+ puts "Stack events:"
30
+ # show the last events that was user initiated
31
+ refresh_events
32
+ show_events(true)
33
+ end
34
+ end
35
+
36
+ def reset
37
+ @events = [] # constantly replaced with recent events
38
+ @last_shown_event_id = nil
39
+ @stack_deletion_completed = nil
40
+ end
41
+
42
+ # check for /(_COMPLETE|_FAILED)$/ status
43
+ def wait
44
+ start_time = Time.now
45
+
46
+ refresh_events
47
+ until completed || @stack_deletion_completed
48
+ show_events
49
+ end
50
+ show_events(true) # show the final event
51
+
52
+ if @stack_deletion_completed
53
+ puts "Stack #{@stack_name} deleted."
54
+ return
55
+ end
56
+
57
+ success = false
58
+ if last_event_status =~ /_FAILED/
59
+ puts "Stack failed: #{last_event_status}".color(:red)
60
+ puts "Stack reason #{@events[0]["resource_status_reason"]}".color(:red)
61
+ elsif last_event_status =~ /_ROLLBACK_/
62
+ puts "Stack rolled back: #{last_event_status}".color(:red)
63
+ else # success
64
+ puts "Stack success status: #{last_event_status}".color(:green)
65
+ success = true
66
+ end
67
+
68
+ # Never gets here when deleting a stack because the describe stack returns nothing
69
+ # once the stack is deleted. Gets here for stack create and update though.
70
+ return if @hide_time_took # set in run
71
+ took = Time.now - start_time
72
+ puts "Time took for stack deployment: #{pretty_time(took).color(:green)}."
73
+
74
+ success
75
+ end
76
+
77
+ def completed
78
+ last_event_status =~ /(_COMPLETE|_FAILED)$/ &&
79
+ @events[0]["logical_resource_id"] == @stack_name &&
80
+ @events[0]["resource_type"] == "AWS::CloudFormation::Stack"
81
+ end
82
+
83
+ def last_event_status
84
+ @events[0]["resource_status"]
85
+ end
86
+
87
+ # Only shows new events
88
+ def show_events(final=false)
89
+ if @last_shown_event_id.nil?
90
+ i = find_index(:start)
91
+ print_events(i)
92
+ else
93
+ i = find_index(:last_shown)
94
+ # puts "last_shown index #{i}"
95
+ print_events(i-1) unless i == 0
96
+ end
97
+
98
+ return if final
99
+ sleep 5 unless ENV['TEST']
100
+ refresh_events
101
+ end
102
+
103
+ def print_events(i)
104
+ @events[0..i].reverse.each do |e|
105
+ print_event(e)
106
+ end
107
+ @last_shown_event_id = @events[0]["event_id"]
108
+ # puts "@last_shown_event_id #{@last_shown_event_id.inspect}"
109
+ end
110
+
111
+ def print_event(e)
112
+ message = [
113
+ event_time(e["timestamp"]),
114
+ e["resource_status"],
115
+ e["resource_type"],
116
+ e["logical_resource_id"],
117
+ e["resource_status_reason"]
118
+ ].join(" ")
119
+ message = message.color(:red) if e["resource_status"] =~ /_FAILED/
120
+ puts message
121
+ end
122
+
123
+ # https://stackoverflow.com/questions/18000432/rails-12-hour-am-pm-range-for-a-day
124
+ def event_time(timestamp)
125
+ Time.parse(timestamp.to_s).localtime.strftime("%I:%M:%S%p")
126
+ end
127
+
128
+ # refreshes the loaded events in memory
129
+ def refresh_events
130
+ resp = cfn.describe_stack_events(stack_name: @stack_name)
131
+ @events = resp["stack_events"]
132
+ rescue Aws::CloudFormation::Errors::ValidationError => e
133
+ if e.message =~ /Stack .* does not exis/
134
+ @stack_deletion_completed = true
135
+ else
136
+ raise
137
+ end
138
+ end
139
+
140
+ def find_index(name)
141
+ send("#{name}_index")
142
+ end
143
+
144
+ def start_index
145
+ @events.find_index do |event|
146
+ event["resource_type"] == "AWS::CloudFormation::Stack" &&
147
+ event["resource_status_reason"] == "User Initiated"
148
+ end
149
+ end
150
+
151
+ def last_shown_index
152
+ @events.find_index do |event|
153
+ event["event_id"] == @last_shown_event_id
154
+ end
155
+ end
156
+
157
+ def success?
158
+ resource_status = @events[0]["resource_status"]
159
+ %w[CREATE_COMPLETE UPDATE_COMPLETE].include?(resource_status)
160
+ end
161
+
162
+ def update_rollback?
163
+ @events[0]["resource_status"] == "UPDATE_ROLLBACK_COMPLETE"
164
+ end
165
+
166
+ def find_update_failed_event
167
+ i = @events.find_index do |event|
168
+ event["resource_type"] == "AWS::CloudFormation::Stack" &&
169
+ event["resource_status_reason"] == "User Initiated"
170
+ end
171
+
172
+ @events[0..i].reverse.find do |e|
173
+ e["resource_status"] == "UPDATE_FAILED"
174
+ end
175
+ end
176
+
177
+ def rollback_error_message
178
+ return unless update_rollback?
179
+
180
+ event = find_update_failed_event
181
+ return unless event
182
+
183
+ reason = event["resource_status_reason"]
184
+ messages_map.each do |pattern, message|
185
+ if reason =~ pattern
186
+ return message
187
+ end
188
+ end
189
+
190
+ reason # default message is original reason if not found in messages map
191
+ end
192
+
193
+ def messages_map
194
+ {
195
+ /CloudFormation cannot update a stack when a custom-named resource requires replacing/ => "A workaround is to run ufo again with STATIC_NAME=0 and to switch to dynamic names for resources. Then run ufo again with STATIC_NAME=1 to get back to statically name resources. Note, there are caveats with the workaround.",
196
+ /cannot be associated with more than one load balancer/ => "There's was an issue updating the stack. Target groups can only be associated with one load balancer at a time. The workaround for this is to use UFO_FORCE_TARGET_GROUP=1 and run the command again. This will force the recreation of the target group resource.",
197
+ /SetSubnets is not supported for load balancers of type/ => "Changing subnets for Network Load Balancers is currently not supported. You can try workarouding this with UFO_FORCE_ELB=1 and run the command again. This will force the recreation of the elb resource."
198
+ }
199
+ end
200
+
201
+ # http://stackoverflow.com/questions/4175733/convert-duration-to-hoursminutesseconds-or-similar-in-rails-3-or-ruby
202
+ def pretty_time(total_seconds)
203
+ minutes = (total_seconds / 60) % 60
204
+ seconds = total_seconds % 60
205
+ if total_seconds < 60
206
+ "#{seconds.to_i}s"
207
+ else
208
+ "#{minutes.to_i}m #{seconds.to_i}s"
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,139 @@
1
+ require 'action_view'
2
+ require 'digest'
3
+
4
+ class Jets::Cfn
5
+ class Upload
6
+ include Jets::AwsServices
7
+ include ActionView::Helpers::NumberHelper # number_to_human_size
8
+
9
+ attr_reader :bucket_name
10
+ def initialize(bucket_name)
11
+ @bucket_name = bucket_name
12
+ end
13
+
14
+ def upload
15
+ upload_cfn_templates
16
+ upload_zip_files
17
+ upload_assets
18
+ end
19
+
20
+ def upload_cfn_templates
21
+ puts "Uploading CloudFormation templates to S3."
22
+ expression = "#{Jets::Naming.template_path_prefix}-*"
23
+ Dir.glob(expression).each do |path|
24
+ next unless File.file?(path)
25
+
26
+ key = "jets/cfn-templates/#{File.basename(path)}"
27
+ obj = s3_resource.bucket(bucket_name).object(key)
28
+ obj.upload_file(path)
29
+ end
30
+ end
31
+
32
+ def upload_zip_files
33
+ puts "Uploading code zip files to S3."
34
+ zip_area = "#{Jets.build_root}/stage/zips"
35
+ Dir.glob("#{zip_area}/*").each do |file|
36
+ upload_zip_file(file)
37
+ end
38
+ end
39
+
40
+ def upload_zip_file(path)
41
+ file_size = number_to_human_size(File.size(path))
42
+
43
+ puts "Uploading #{path} (#{file_size}) to S3"
44
+ start_time = Time.now
45
+ s3_key = "jets/code/#{File.basename(path)}"
46
+ obj = s3_resource.bucket(bucket_name).object(s3_key)
47
+ obj.upload_file(path)
48
+ puts "Uploaded to s3://#{bucket_name}/#{s3_key}".color(:green)
49
+ puts "Time to upload code to s3: #{pretty_time(Time.now-start_time).color(:green)}"
50
+ end
51
+
52
+ def upload_assets
53
+ puts "Checking for modified public assets and uploading to S3."
54
+ start_time = Time.now
55
+ upload_public_assets
56
+ puts "Time for public assets to s3: #{pretty_time(Time.now-start_time).color(:green)}"
57
+ end
58
+
59
+ def upload_public_assets
60
+ public_folders = %w[public]
61
+ public_folders = add_rack_assets(public_folders)
62
+ public_folders.each do |folder|
63
+ upload_asset_folder(folder)
64
+ end
65
+ end
66
+
67
+ def add_rack_assets(public_folders)
68
+ return public_folders unless Jets.rack?
69
+ public_folders + %w[rack/public]
70
+ end
71
+
72
+ def upload_asset_folder(folder)
73
+ expression = "#{Jets.root}/#{folder}/**/*"
74
+ group_size = 10
75
+ Dir.glob(expression).each_slice(group_size) do |paths|
76
+ threads = []
77
+ paths.each do |full_path|
78
+ next unless File.file?(full_path)
79
+
80
+ threads << Thread.new do
81
+ upload_to_s3(full_path)
82
+ end
83
+ end
84
+ threads.each(&:join)
85
+ end
86
+ end
87
+
88
+ def upload_to_s3(full_path)
89
+ return if identical_on_s3?(full_path)
90
+
91
+ key = s3_key(full_path)
92
+ obj = s3_resource.bucket(bucket_name).object(key)
93
+ puts "Uploading s3://#{bucket_name}/#{key}" # uncomment to see and debug
94
+ obj.upload_file(full_path, acl: "public-read", cache_control: cache_control)
95
+ end
96
+
97
+ def s3_key(full_path)
98
+ relative_path = full_path.sub("#{Jets.root}/", '')
99
+ "jets/#{relative_path}"
100
+ end
101
+
102
+ def identical_on_s3?(full_path)
103
+ local_md5 = ::Digest::MD5.file(full_path)
104
+ key = s3_key(full_path)
105
+ begin
106
+ resp = s3.head_object(bucket: bucket_name, key: key)
107
+ rescue Aws::S3::Errors::NotFound
108
+ return false
109
+ end
110
+
111
+ remote_md5 = resp.etag.delete_prefix('"').delete_suffix('"')
112
+ local_md5 == remote_md5
113
+ end
114
+
115
+ # If cache_control is provided, then it will set the entire cache-control header.
116
+ # If only max_age is provided, then we'll generate a cache_control header.
117
+ # Using max_age is the shorter and simply way of setting the cache_control header.
118
+ def cache_control
119
+ cache_control = Jets.config.assets.cache_control
120
+ unless cache_control
121
+ max_age = Jets.config.assets.max_age # defaults to 3600 in jets/application.rb
122
+ cache_control = "public, max-age=#{max_age}"
123
+ end
124
+ cache_control
125
+ end
126
+
127
+ # http://stackoverflow.com/questions/4175733/convert-duration-to-hoursminutesseconds-or-similar-in-rails-3-or-ruby
128
+ def pretty_time(total_seconds)
129
+ minutes = (total_seconds / 60) % 60
130
+ seconds = total_seconds % 60
131
+ if total_seconds < 60
132
+ "#{seconds.to_i}s"
133
+ else
134
+ "#{minutes.to_i}m #{seconds.to_i}s"
135
+ end
136
+ end
137
+
138
+ end
139
+ end