jets.benforeva 3.0.17.pre.mount.pre.fix

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 (459) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +92 -0
  3. data/.cody/README.md +13 -0
  4. data/.cody/docs/bin/build.sh +7 -0
  5. data/.cody/docs/bin/bundler_setup.sh +8 -0
  6. data/.cody/docs/bin/cli_docs.sh +6 -0
  7. data/.cody/docs/bin/git_commit.sh +27 -0
  8. data/.cody/docs/bin/git_setup.sh +12 -0
  9. data/.cody/docs/bin/subnav.sh +14 -0
  10. data/.cody/docs/buildspec.yml +10 -0
  11. data/.cody/docs/project.rb +10 -0
  12. data/.github/ISSUE_TEMPLATE/bug_report.md +84 -0
  13. data/.github/ISSUE_TEMPLATE/documentation.md +27 -0
  14. data/.github/ISSUE_TEMPLATE/feature_request.md +64 -0
  15. data/.github/ISSUE_TEMPLATE/question.md +14 -0
  16. data/.github/ISSUE_TEMPLATE.md +7 -0
  17. data/.github/PULL_REQUEST_TEMPLATE.md +50 -0
  18. data/.gitignore +24 -0
  19. data/.gitmodules +0 -0
  20. data/.python-version +1 -0
  21. data/.rspec +4 -0
  22. data/.ruby-gemset +1 -0
  23. data/.ruby-version +1 -0
  24. data/CHANGELOG.md +1035 -0
  25. data/CONDUCT.md +1 -0
  26. data/CONTRIBUTING.md +1 -0
  27. data/Dockerfile +16 -0
  28. data/Dockerfile.base +53 -0
  29. data/Gemfile +14 -0
  30. data/Guardfile +22 -0
  31. data/LICENSE.txt +22 -0
  32. data/Procfile +2 -0
  33. data/README.md +212 -0
  34. data/Rakefile +24 -0
  35. data/backers.md +20 -0
  36. data/bin/release +9 -0
  37. data/exe/jets.benforeva +14 -0
  38. data/jets.benforeva.gemspec +71 -0
  39. data/lib/jets/application/defaults.rb +200 -0
  40. data/lib/jets/application.rb +240 -0
  41. data/lib/jets/authorizer/base.rb +36 -0
  42. data/lib/jets/authorizer/dsl.rb +69 -0
  43. data/lib/jets/authorizer/helpers/iam_helper.rb +47 -0
  44. data/lib/jets/autoloaders.rb +112 -0
  45. data/lib/jets/aws_info.rb +111 -0
  46. data/lib/jets/aws_services/global_memoist.rb +57 -0
  47. data/lib/jets/aws_services/s3_bucket.rb +34 -0
  48. data/lib/jets/aws_services/stack_status.rb +64 -0
  49. data/lib/jets/aws_services.rb +95 -0
  50. data/lib/jets/booter.rb +167 -0
  51. data/lib/jets/builders/code_builder.rb +410 -0
  52. data/lib/jets/builders/code_size.rb +57 -0
  53. data/lib/jets/builders/gem_replacer.rb +89 -0
  54. data/lib/jets/builders/handler_generator.rb +186 -0
  55. data/lib/jets/builders/lambda_layer.rb +68 -0
  56. data/lib/jets/builders/md5.rb +60 -0
  57. data/lib/jets/builders/md5_zip.rb +61 -0
  58. data/lib/jets/builders/purger.rb +35 -0
  59. data/lib/jets/builders/rack_packager.rb +51 -0
  60. data/lib/jets/builders/rackup_wrappers/rackup +19 -0
  61. data/lib/jets/builders/rackup_wrappers/rackup.rb +7 -0
  62. data/lib/jets/builders/reconfigure_rails/config/initializers/jets.rb +16 -0
  63. data/lib/jets/builders/reconfigure_rails.rb +114 -0
  64. data/lib/jets/builders/ruby_packager.rb +235 -0
  65. data/lib/jets/builders/shim_vars/app.rb +78 -0
  66. data/lib/jets/builders/shim_vars/base.rb +25 -0
  67. data/lib/jets/builders/shim_vars/shared.rb +37 -0
  68. data/lib/jets/builders/templates/handler.rb +12 -0
  69. data/lib/jets/builders/tidy.rb +107 -0
  70. data/lib/jets/builders/util.rb +31 -0
  71. data/lib/jets/bundle.rb +88 -0
  72. data/lib/jets/camelizer.rb +4 -0
  73. data/lib/jets/cfn/builders/api_deployment_builder.rb +56 -0
  74. data/lib/jets/cfn/builders/api_gateway_builder.rb +123 -0
  75. data/lib/jets/cfn/builders/api_resources_builder.rb +44 -0
  76. data/lib/jets/cfn/builders/authorizer_builder.rb +67 -0
  77. data/lib/jets/cfn/builders/base_child_builder.rb +69 -0
  78. data/lib/jets/cfn/builders/controller_builder.rb +50 -0
  79. data/lib/jets/cfn/builders/function_builder.rb +14 -0
  80. data/lib/jets/cfn/builders/interface.rb +133 -0
  81. data/lib/jets/cfn/builders/job_builder.rb +14 -0
  82. data/lib/jets/cfn/builders/parent_builder/stagger.rb +34 -0
  83. data/lib/jets/cfn/builders/parent_builder.rb +130 -0
  84. data/lib/jets/cfn/builders/rule_builder.rb +24 -0
  85. data/lib/jets/cfn/builders/shared_builder.rb +14 -0
  86. data/lib/jets/cfn/builders/util/source.rb +21 -0
  87. data/lib/jets/cfn/built_template.rb +15 -0
  88. data/lib/jets/cfn/ship.rb +188 -0
  89. data/lib/jets/cfn/status.rb +10 -0
  90. data/lib/jets/cfn/template_source.rb +61 -0
  91. data/lib/jets/cfn/upload.rb +157 -0
  92. data/lib/jets/cli.rb +208 -0
  93. data/lib/jets/commands/base.rb +145 -0
  94. data/lib/jets/commands/build.rb +252 -0
  95. data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
  96. data/lib/jets/commands/call/autoload_guesser.rb +136 -0
  97. data/lib/jets/commands/call/base_guesser.rb +62 -0
  98. data/lib/jets/commands/call/guesser.rb +48 -0
  99. data/lib/jets/commands/call.rb +182 -0
  100. data/lib/jets/commands/clean/base.rb +24 -0
  101. data/lib/jets/commands/clean/build.rb +13 -0
  102. data/lib/jets/commands/clean/log.rb +111 -0
  103. data/lib/jets/commands/clean.rb +19 -0
  104. data/lib/jets/commands/configure.rb +51 -0
  105. data/lib/jets/commands/console.rb +12 -0
  106. data/lib/jets/commands/db/environment-task.rake +3 -0
  107. data/lib/jets/commands/db/tasks/dummy/app.rb +25 -0
  108. data/lib/jets/commands/db/tasks/dummy/config.rb +14 -0
  109. data/lib/jets/commands/db/tasks.rb +34 -0
  110. data/lib/jets/commands/db.rb +13 -0
  111. data/lib/jets/commands/dbconsole.rb +134 -0
  112. data/lib/jets/commands/delete.rb +136 -0
  113. data/lib/jets/commands/deploy.rb +137 -0
  114. data/lib/jets/commands/dotenv.rb +9 -0
  115. data/lib/jets/commands/dynamodb/migrate.rb +9 -0
  116. data/lib/jets/commands/dynamodb/migrator.rb +36 -0
  117. data/lib/jets/commands/dynamodb.rb +19 -0
  118. data/lib/jets/commands/gems.rb +13 -0
  119. data/lib/jets/commands/help/build.md +6 -0
  120. data/lib/jets/commands/help/call.md +69 -0
  121. data/lib/jets/commands/help/clean/build.md +5 -0
  122. data/lib/jets/commands/help/clean/log.md +5 -0
  123. data/lib/jets/commands/help/console.md +18 -0
  124. data/lib/jets/commands/help/db/generate.md +8 -0
  125. data/lib/jets/commands/help/dbconsole.md +9 -0
  126. data/lib/jets/commands/help/degenerate.md +16 -0
  127. data/lib/jets/commands/help/delete.md +22 -0
  128. data/lib/jets/commands/help/deploy.md +32 -0
  129. data/lib/jets/commands/help/dynamodb/generate.md +52 -0
  130. data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
  131. data/lib/jets/commands/help/gems/check.md +6 -0
  132. data/lib/jets/commands/help/generate.md +28 -0
  133. data/lib/jets/commands/help/import/rack.md +13 -0
  134. data/lib/jets/commands/help/import/rails.md +11 -0
  135. data/lib/jets/commands/help/new.md +42 -0
  136. data/lib/jets/commands/help/routes.md +16 -0
  137. data/lib/jets/commands/help/runner.md +17 -0
  138. data/lib/jets/commands/help/server.md +15 -0
  139. data/lib/jets/commands/help/status.md +14 -0
  140. data/lib/jets/commands/help/upgrade.md +7 -0
  141. data/lib/jets/commands/help/url.md +6 -0
  142. data/lib/jets/commands/help.rb +9 -0
  143. data/lib/jets/commands/import/base.rb +49 -0
  144. data/lib/jets/commands/import/cheatsheet.rb +35 -0
  145. data/lib/jets/commands/import/rack.rb +16 -0
  146. data/lib/jets/commands/import/rails.rb +74 -0
  147. data/lib/jets/commands/import/sequence.rb +90 -0
  148. data/lib/jets/commands/import/templates/config/database.yml +30 -0
  149. data/lib/jets/commands/import/templates/submodules-cheatsheet.md +89 -0
  150. data/lib/jets/commands/import.rb +12 -0
  151. data/lib/jets/commands/main.rb +166 -0
  152. data/lib/jets/commands/markdown/creator.rb +58 -0
  153. data/lib/jets/commands/markdown/index.rb +27 -0
  154. data/lib/jets/commands/markdown/page.rb +125 -0
  155. data/lib/jets/commands/markdown/shell.rb +11 -0
  156. data/lib/jets/commands/new.rb +173 -0
  157. data/lib/jets/commands/rake_command.rb +61 -0
  158. data/lib/jets/commands/rake_tasks.rb +50 -0
  159. data/lib/jets/commands/runner.rb +16 -0
  160. data/lib/jets/commands/sequence.rb +105 -0
  161. data/lib/jets/commands/stack_info.rb +30 -0
  162. data/lib/jets/commands/templates/skeleton/.env.development.tt +3 -0
  163. data/lib/jets/commands/templates/skeleton/.env.test +3 -0
  164. data/lib/jets/commands/templates/skeleton/.env.tt +3 -0
  165. data/lib/jets/commands/templates/skeleton/.gitignore +12 -0
  166. data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
  167. data/lib/jets/commands/templates/skeleton/.rspec +3 -0
  168. data/lib/jets/commands/templates/skeleton/Gemfile.tt +39 -0
  169. data/lib/jets/commands/templates/skeleton/Procfile +7 -0
  170. data/lib/jets/commands/templates/skeleton/README.md +11 -0
  171. data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
  172. data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
  173. data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
  174. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +4 -0
  175. data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
  176. data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
  177. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +26 -0
  178. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +71 -0
  179. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +27 -0
  180. data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +22 -0
  181. data/lib/jets/commands/templates/skeleton/config/environments/development.rb +7 -0
  182. data/lib/jets/commands/templates/skeleton/config/environments/production.rb +9 -0
  183. data/lib/jets/commands/templates/skeleton/config/environments/test.rb +7 -0
  184. data/lib/jets/commands/templates/skeleton/config/routes.rb +9 -0
  185. data/lib/jets/commands/templates/skeleton/config.ru +5 -0
  186. data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
  187. data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
  188. data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
  189. data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
  190. data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
  191. data/lib/jets/commands/templates/skeleton/public/index.html.tt +91 -0
  192. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +15 -0
  193. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
  194. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
  195. data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +30 -0
  196. data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +23 -0
  197. data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
  198. data/lib/jets/commands/upgrade/templates/bin/webpack +19 -0
  199. data/lib/jets/commands/upgrade/templates/bin/webpack-dev-server +19 -0
  200. data/lib/jets/commands/upgrade/version1.rb +136 -0
  201. data/lib/jets/commands/upgrade.rb +105 -0
  202. data/lib/jets/commands/url.rb +69 -0
  203. data/lib/jets/commands/webpacker_template.rb +18 -0
  204. data/lib/jets/controller/authorization.rb +91 -0
  205. data/lib/jets/controller/base.rb +175 -0
  206. data/lib/jets/controller/callbacks.rb +73 -0
  207. data/lib/jets/controller/cookies/jar.rb +269 -0
  208. data/lib/jets/controller/cookies.rb +38 -0
  209. data/lib/jets/controller/error/invalid_authenticity_token.rb +6 -0
  210. data/lib/jets/controller/error.rb +4 -0
  211. data/lib/jets/controller/forgery_protection.rb +43 -0
  212. data/lib/jets/controller/layout.rb +17 -0
  213. data/lib/jets/controller/middleware/cors.rb +60 -0
  214. data/lib/jets/controller/middleware/local/api_gateway.rb +93 -0
  215. data/lib/jets/controller/middleware/local/mimic_aws_call.rb +38 -0
  216. data/lib/jets/controller/middleware/local/route_matcher.rb +22 -0
  217. data/lib/jets/controller/middleware/local.rb +120 -0
  218. data/lib/jets/controller/middleware/main.rb +53 -0
  219. data/lib/jets/controller/middleware/reloader.rb +15 -0
  220. data/lib/jets/controller/middleware/webpacker_setup.rb +6 -0
  221. data/lib/jets/controller/parameters_filter.rb +29 -0
  222. data/lib/jets/controller/params.rb +117 -0
  223. data/lib/jets/controller/rack/adapter.rb +94 -0
  224. data/lib/jets/controller/rack/env.rb +122 -0
  225. data/lib/jets/controller/redirection.rb +51 -0
  226. data/lib/jets/controller/rendering/rack_renderer.rb +267 -0
  227. data/lib/jets/controller/rendering.rb +96 -0
  228. data/lib/jets/controller/request.rb +29 -0
  229. data/lib/jets/controller/response.rb +61 -0
  230. data/lib/jets/controller/stage.rb +34 -0
  231. data/lib/jets/controller.rb +3 -0
  232. data/lib/jets/core.rb +157 -0
  233. data/lib/jets/core_ext/bundler.rb +7 -0
  234. data/lib/jets/core_ext/kernel.rb +13 -0
  235. data/lib/jets/db.rb +15 -0
  236. data/lib/jets/dotenv/show.rb +11 -0
  237. data/lib/jets/dotenv/ssm.rb +64 -0
  238. data/lib/jets/dotenv.rb +48 -0
  239. data/lib/jets/erb.rb +51 -0
  240. data/lib/jets/generator/templates/active_job/job/templates/application_job.rb.tt +6 -0
  241. data/lib/jets/generator/templates/active_job/job/templates/job.rb.tt +8 -0
  242. data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
  243. data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +34 -0
  244. data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
  245. data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
  246. data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
  247. data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
  248. data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
  249. data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
  250. data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
  251. data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
  252. data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
  253. data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
  254. data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +79 -0
  255. data/lib/jets/generator.rb +112 -0
  256. data/lib/jets/inflections.rb +32 -0
  257. data/lib/jets/internal/app/controllers/jets/bare_controller.rb +16 -0
  258. data/lib/jets/internal/app/controllers/jets/mailers_controller.rb +97 -0
  259. data/lib/jets/internal/app/controllers/jets/mount_controller.rb +63 -0
  260. data/lib/jets/internal/app/controllers/jets/public_controller.rb +31 -0
  261. data/lib/jets/internal/app/controllers/jets/rack_controller.rb +12 -0
  262. data/lib/jets/internal/app/functions/jets/base_path.rb +18 -0
  263. data/lib/jets/internal/app/functions/jets/base_path_mapping.rb +100 -0
  264. data/lib/jets/internal/app/helpers/jets/mailers_helper.rb +9 -0
  265. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +70 -0
  266. data/lib/jets/internal/app/shared/functions/jets/s3_bucket_config.rb +33 -0
  267. data/lib/jets/internal/app/views/jets/mailers/email.html.erb +145 -0
  268. data/lib/jets/internal/app/views/jets/mailers/index.html.erb +8 -0
  269. data/lib/jets/internal/app/views/jets/mailers/mailer.html.erb +6 -0
  270. data/lib/jets/internal/turbines/jets/mailer.rb +52 -0
  271. data/lib/jets/job/base.rb +49 -0
  272. data/lib/jets/job/dsl/dynamodb_event.rb +67 -0
  273. data/lib/jets/job/dsl/event_source_mapping.rb +11 -0
  274. data/lib/jets/job/dsl/iot_event.rb +24 -0
  275. data/lib/jets/job/dsl/kinesis_event.rb +46 -0
  276. data/lib/jets/job/dsl/log_event.rb +15 -0
  277. data/lib/jets/job/dsl/rule_event.rb +75 -0
  278. data/lib/jets/job/dsl/s3_event.rb +36 -0
  279. data/lib/jets/job/dsl/sns_event.rb +54 -0
  280. data/lib/jets/job/dsl/sqs_event.rb +96 -0
  281. data/lib/jets/job/dsl.rb +40 -0
  282. data/lib/jets/job/helpers/kinesis_event_helper.rb +13 -0
  283. data/lib/jets/job/helpers/log_event_helper.rb +17 -0
  284. data/lib/jets/job/helpers/s3_event_helper.rb +13 -0
  285. data/lib/jets/klass.rb +109 -0
  286. data/lib/jets/lambda/dsl.rb +404 -0
  287. data/lib/jets/lambda/function.rb +29 -0
  288. data/lib/jets/lambda/function_constructor.rb +55 -0
  289. data/lib/jets/lambda/functions.rb +39 -0
  290. data/lib/jets/lambda/task.rb +111 -0
  291. data/lib/jets/logger.rb +21 -0
  292. data/lib/jets/mega/hash_converter.rb +25 -0
  293. data/lib/jets/mega/request/source.rb +21 -0
  294. data/lib/jets/mega/request.rb +163 -0
  295. data/lib/jets/middleware/configurator.rb +84 -0
  296. data/lib/jets/middleware/default_stack.rb +53 -0
  297. data/lib/jets/middleware/layer.rb +34 -0
  298. data/lib/jets/middleware/stack.rb +77 -0
  299. data/lib/jets/middleware.rb +33 -0
  300. data/lib/jets/naming.rb +63 -0
  301. data/lib/jets/overrides/lambda/marshaller.rb +31 -0
  302. data/lib/jets/overrides/lambda.rb +1 -0
  303. data/lib/jets/overrides/rails/action_controller.rb +13 -0
  304. data/lib/jets/overrides/rails/asset_tag_helper.rb +114 -0
  305. data/lib/jets/overrides/rails/common_methods.rb +13 -0
  306. data/lib/jets/overrides/rails/migration_checker.rb +34 -0
  307. data/lib/jets/overrides/rails/rendering_helper.rb +27 -0
  308. data/lib/jets/overrides/rails/url_helper.rb +88 -0
  309. data/lib/jets/overrides/rails.rb +6 -0
  310. data/lib/jets/poly_fun/base_executor.rb +125 -0
  311. data/lib/jets/poly_fun/lambda_executor.rb +16 -0
  312. data/lib/jets/poly_fun/node_error.rb +8 -0
  313. data/lib/jets/poly_fun/node_executor.rb +54 -0
  314. data/lib/jets/poly_fun/python_error.rb +8 -0
  315. data/lib/jets/poly_fun/python_executor.rb +23 -0
  316. data/lib/jets/poly_fun.rb +73 -0
  317. data/lib/jets/preheat.rb +117 -0
  318. data/lib/jets/processors/deducer.rb +65 -0
  319. data/lib/jets/processors/main_processor.rb +61 -0
  320. data/lib/jets/rack_server.rb +86 -0
  321. data/lib/jets/rdoc.rb +30 -0
  322. data/lib/jets/resource/api_gateway/authorizer.rb +82 -0
  323. data/lib/jets/resource/api_gateway/base_path/function.rb +49 -0
  324. data/lib/jets/resource/api_gateway/base_path/mapping.rb +44 -0
  325. data/lib/jets/resource/api_gateway/base_path/role.rb +76 -0
  326. data/lib/jets/resource/api_gateway/cors.rb +61 -0
  327. data/lib/jets/resource/api_gateway/deployment.rb +80 -0
  328. data/lib/jets/resource/api_gateway/domain_name.rb +65 -0
  329. data/lib/jets/resource/api_gateway/method/authorization.rb +41 -0
  330. data/lib/jets/resource/api_gateway/method.rb +102 -0
  331. data/lib/jets/resource/api_gateway/resource.rb +82 -0
  332. data/lib/jets/resource/api_gateway/rest_api/change_detection.rb +10 -0
  333. data/lib/jets/resource/api_gateway/rest_api/logical_id/message.rb +49 -0
  334. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +98 -0
  335. data/lib/jets/resource/api_gateway/rest_api/routes/change/base.rb +136 -0
  336. data/lib/jets/resource/api_gateway/rest_api/routes/change/media_types.rb +36 -0
  337. data/lib/jets/resource/api_gateway/rest_api/routes/change/page.rb +93 -0
  338. data/lib/jets/resource/api_gateway/rest_api/routes/change/to.rb +25 -0
  339. data/lib/jets/resource/api_gateway/rest_api/routes/change/variable.rb +35 -0
  340. data/lib/jets/resource/api_gateway/rest_api/routes/change.rb +16 -0
  341. data/lib/jets/resource/api_gateway/rest_api/routes/collision/variable_exception.rb +7 -0
  342. data/lib/jets/resource/api_gateway/rest_api/routes/collision.rb +121 -0
  343. data/lib/jets/resource/api_gateway/rest_api/routes.rb +7 -0
  344. data/lib/jets/resource/api_gateway/rest_api.rb +64 -0
  345. data/lib/jets/resource/associated.rb +37 -0
  346. data/lib/jets/resource/base.rb +28 -0
  347. data/lib/jets/resource/child_stack/api_deployment.rb +58 -0
  348. data/lib/jets/resource/child_stack/api_gateway.rb +23 -0
  349. data/lib/jets/resource/child_stack/api_resource/page.rb +20 -0
  350. data/lib/jets/resource/child_stack/api_resource.rb +54 -0
  351. data/lib/jets/resource/child_stack/app_class.rb +149 -0
  352. data/lib/jets/resource/child_stack/authorizer.rb +40 -0
  353. data/lib/jets/resource/child_stack/base.rb +24 -0
  354. data/lib/jets/resource/child_stack/common_parameters.rb +14 -0
  355. data/lib/jets/resource/child_stack/shared.rb +85 -0
  356. data/lib/jets/resource/config/config_rule.rb +74 -0
  357. data/lib/jets/resource/config/managed_rule.rb +15 -0
  358. data/lib/jets/resource/events/rule.rb +31 -0
  359. data/lib/jets/resource/iam/application_role.rb +27 -0
  360. data/lib/jets/resource/iam/base_role_definition.rb +47 -0
  361. data/lib/jets/resource/iam/class_role.rb +74 -0
  362. data/lib/jets/resource/iam/function_role.rb +54 -0
  363. data/lib/jets/resource/iam/managed_policy.rb +22 -0
  364. data/lib/jets/resource/iam/policy_document.rb +41 -0
  365. data/lib/jets/resource/iot/topic_rule.rb +34 -0
  366. data/lib/jets/resource/lambda/event_source_mapping.rb +31 -0
  367. data/lib/jets/resource/lambda/function/environment.rb +62 -0
  368. data/lib/jets/resource/lambda/function.rb +221 -0
  369. data/lib/jets/resource/lambda/gem_layer.rb +17 -0
  370. data/lib/jets/resource/lambda/layer_version.rb +44 -0
  371. data/lib/jets/resource/logs/subscription_filter.rb +31 -0
  372. data/lib/jets/resource/permission.rb +45 -0
  373. data/lib/jets/resource/replacer.rb +85 -0
  374. data/lib/jets/resource/route53/record_set.rb +98 -0
  375. data/lib/jets/resource/s3/bucket.rb +24 -0
  376. data/lib/jets/resource/sns/subscription.rb +29 -0
  377. data/lib/jets/resource/sns/topic.rb +35 -0
  378. data/lib/jets/resource/sns/topic_policy.rb +40 -0
  379. data/lib/jets/resource/sqs/queue.rb +21 -0
  380. data/lib/jets/resource/standardizer.rb +42 -0
  381. data/lib/jets/resource.rb +71 -0
  382. data/lib/jets/router/dsl/mount.rb +13 -0
  383. data/lib/jets/router/dsl.rb +144 -0
  384. data/lib/jets/router/error.rb +4 -0
  385. data/lib/jets/router/finder.rb +47 -0
  386. data/lib/jets/router/helpers/core_helper.rb +27 -0
  387. data/lib/jets/router/helpers/named_routes_helper.rb +8 -0
  388. data/lib/jets/router/helpers.rb +4 -0
  389. data/lib/jets/router/matcher.rb +81 -0
  390. data/lib/jets/router/method_creator/code.rb +99 -0
  391. data/lib/jets/router/method_creator/edit.rb +12 -0
  392. data/lib/jets/router/method_creator/generic.rb +11 -0
  393. data/lib/jets/router/method_creator/index.rb +48 -0
  394. data/lib/jets/router/method_creator/new.rb +12 -0
  395. data/lib/jets/router/method_creator/root.rb +15 -0
  396. data/lib/jets/router/method_creator/show.rb +12 -0
  397. data/lib/jets/router/method_creator.rb +50 -0
  398. data/lib/jets/router/resources/base.rb +7 -0
  399. data/lib/jets/router/resources/filter.rb +15 -0
  400. data/lib/jets/router/resources/options.rb +13 -0
  401. data/lib/jets/router/route/authorizer.rb +57 -0
  402. data/lib/jets/router/route.rb +230 -0
  403. data/lib/jets/router/scope.rb +95 -0
  404. data/lib/jets/router/util.rb +38 -0
  405. data/lib/jets/router.rb +180 -0
  406. data/lib/jets/rule/base.rb +19 -0
  407. data/lib/jets/rule/dsl.rb +109 -0
  408. data/lib/jets/spec_helpers/controllers/params.rb +8 -0
  409. data/lib/jets/spec_helpers/controllers/request.rb +101 -0
  410. data/lib/jets/spec_helpers/controllers/response.rb +10 -0
  411. data/lib/jets/spec_helpers/controllers.rb +47 -0
  412. data/lib/jets/spec_helpers/fixtures.rb +11 -0
  413. data/lib/jets/spec_helpers.rb +21 -0
  414. data/lib/jets/stack/builder.rb +43 -0
  415. data/lib/jets/stack/definition.rb +50 -0
  416. data/lib/jets/stack/depends/item.rb +26 -0
  417. data/lib/jets/stack/depends.rb +34 -0
  418. data/lib/jets/stack/function.rb +69 -0
  419. data/lib/jets/stack/main/dsl/base.rb +63 -0
  420. data/lib/jets/stack/main/dsl/cloudwatch.rb +19 -0
  421. data/lib/jets/stack/main/dsl/iam.rb +8 -0
  422. data/lib/jets/stack/main/dsl/kinesis.rb +15 -0
  423. data/lib/jets/stack/main/dsl/lambda.rb +83 -0
  424. data/lib/jets/stack/main/dsl/s3.rb +12 -0
  425. data/lib/jets/stack/main/dsl/sns.rb +16 -0
  426. data/lib/jets/stack/main/dsl/sqs.rb +10 -0
  427. data/lib/jets/stack/main/dsl.rb +17 -0
  428. data/lib/jets/stack/main.rb +4 -0
  429. data/lib/jets/stack/output/dsl.rb +19 -0
  430. data/lib/jets/stack/output/lookup.rb +36 -0
  431. data/lib/jets/stack/output.rb +35 -0
  432. data/lib/jets/stack/parameter/dsl.rb +42 -0
  433. data/lib/jets/stack/parameter.rb +37 -0
  434. data/lib/jets/stack/resource/dsl.rb +19 -0
  435. data/lib/jets/stack/resource.rb +31 -0
  436. data/lib/jets/stack/s3_event.rb +87 -0
  437. data/lib/jets/stack.rb +88 -0
  438. data/lib/jets/tmp_loader.rb +53 -0
  439. data/lib/jets/turbine.rb +41 -0
  440. data/lib/jets/turbo/database_yaml.rb +41 -0
  441. data/lib/jets/turbo/project/.gitignore +12 -0
  442. data/lib/jets/turbo/project/.jetskeep +1 -0
  443. data/lib/jets/turbo/project/Gemfile +16 -0
  444. data/lib/jets/turbo/project/Rakefile +2 -0
  445. data/lib/jets/turbo/project/app/controllers/application_controller.rb +2 -0
  446. data/lib/jets/turbo/project/app/helpers/application_helper.rb +2 -0
  447. data/lib/jets/turbo/project/app/jobs/application_job.rb +4 -0
  448. data/lib/jets/turbo/project/config/application.rb +5 -0
  449. data/lib/jets/turbo/project/config/routes.rb +4 -0
  450. data/lib/jets/turbo/project/config.ru +5 -0
  451. data/lib/jets/turbo/rails.rb +127 -0
  452. data/lib/jets/turbo/templates/config/database.yml +30 -0
  453. data/lib/jets/turbo.rb +56 -0
  454. data/lib/jets/util.rb +40 -0
  455. data/lib/jets/version.rb +3 -0
  456. data/lib/jets.rb +31 -0
  457. data/readme/prerelease.md +6 -0
  458. data/readme/testing.md +60 -0
  459. metadata +1105 -0
@@ -0,0 +1,102 @@
1
+ # Converts a Jets::Route to a CloudFormation Jets::Resource::ApiGateway::Method resource
2
+ module Jets::Resource::ApiGateway
3
+ class Method < Jets::Resource::Base
4
+ include Authorization
5
+
6
+ # also delegate permission for a method
7
+ delegate :permission, to: :resource
8
+
9
+ # route - Jets::Route
10
+ def initialize(route)
11
+ @route = route
12
+ end
13
+
14
+ def definition
15
+ {
16
+ method_logical_id => {
17
+ type: "AWS::ApiGateway::Method",
18
+ properties: props
19
+ }
20
+ }
21
+ end
22
+
23
+ def props
24
+ props = {
25
+ resource_id: "!Ref #{resource_id}",
26
+ rest_api_id: "!Ref #{RestApi.logical_id}",
27
+ http_method: @route.method,
28
+ request_parameters: {},
29
+ authorization_type: authorization_type,
30
+ api_key_required: api_key_required?,
31
+ integration: {
32
+ integration_http_method: "POST",
33
+ type: "AWS_PROXY",
34
+ uri: "!Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${{namespace}LambdaFunction.Arn}/invocations"
35
+ },
36
+ method_responses: []
37
+ }
38
+ props[:authorizer_id] = authorizer_id if authorizer_id
39
+ props[:authorization_scopes] = authorization_scopes if authorization_scopes
40
+
41
+ props
42
+ end
43
+
44
+ def method_logical_id
45
+ # https://stackoverflow.com/questions/6104240/how-do-i-strip-non-alphanumeric-characters-from-a-string-and-keep-spaces
46
+ # Add path to the logical id to allow 2 different paths to be connected to the same controller action.
47
+ # Example:
48
+ #
49
+ # root "jets/public#show"
50
+ # any "*catchall", to: "jets/public#show"
51
+ #
52
+ # Without the path in the logical id, the logical id would be ShowApiMethod for both routes and only the
53
+ # last one would be created in the CloudFormation template.
54
+ path = @route.path.gsub('*','')
55
+ .gsub(/[^0-9a-z]/i, ' ')
56
+ .gsub(/\s+/, '_')
57
+ path = nil if path == ''
58
+ http_verb = @route.method.downcase
59
+ [path, "{namespace}_#{http_verb}_api_method"].compact.join('_')
60
+ end
61
+
62
+ def replacements
63
+ # mimic task to grab replacements, we want the namespace to be the lambda function's namespace
64
+ resources = [definition]
65
+ task = Jets::Lambda::Task.new(@route.controller_name, @route.action_name,
66
+ resources: resources)
67
+ task.replacements
68
+ end
69
+
70
+ def cors
71
+ Cors.new(@route)
72
+ end
73
+ memoize :cors
74
+
75
+ private
76
+
77
+ def controller_klass
78
+ @controller_klass ||= "#{controller_name}_controller".camelize.constantize
79
+ end
80
+
81
+ def controller_name
82
+ @controller_name ||= @route.to.split('#').first
83
+ end
84
+
85
+ def resource_id
86
+ @route.path == '' ?
87
+ "RootResourceId" :
88
+ Jets::Resource.truncate_id(resource_logical_id.camelize, "ApiResource")
89
+ end
90
+
91
+ # Example: Posts
92
+ def resource_logical_id
93
+ camelized_path.underscore
94
+ end
95
+
96
+ def camelized_path
97
+ path = @route.path
98
+ path = "homepage" if path == ''
99
+ path.gsub('/','_').gsub(':','').gsub('*','').gsub('.','').camelize
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,82 @@
1
+ module Jets::Resource::ApiGateway
2
+ class Resource < Jets::Resource::Base
3
+ def initialize(path, internal: false)
4
+ @path = path # Examples: "posts/:id/edit" or "posts"
5
+ @internal = internal
6
+ end
7
+
8
+ def definition
9
+ {
10
+ resource_logical_id => {
11
+ type: "AWS::ApiGateway::Resource",
12
+ properties: {
13
+ parent_id: parent_id,
14
+ path_part: path_part,
15
+ rest_api_id: "!Ref #{RestApi.logical_id(@internal)}",
16
+ }
17
+ }
18
+ }
19
+ end
20
+
21
+ def outputs
22
+ {
23
+ logical_id => "!Ref #{logical_id}",
24
+ }
25
+ end
26
+
27
+ def resource_logical_id
28
+ if @path == ''
29
+ "RootResourceId"
30
+ else
31
+ Jets::Resource.truncate_id path_logical_id(@path), "ApiResource"
32
+ end
33
+ end
34
+
35
+ # For parameter description
36
+ def desc
37
+ path.empty? ? 'Homepage route: /' : "Route for: /#{path}"
38
+ end
39
+
40
+ def parent_path_parameter
41
+ if @path.include?('/') # posts/:id or posts/:id/edit
42
+ parent_path = @path.split('/')[0..-2].join('/')
43
+ parent_logical_id = path_logical_id(parent_path)
44
+ Jets::Resource.truncate_id(parent_logical_id, "ApiResource")
45
+ else
46
+ "RootResourceId"
47
+ end
48
+ end
49
+
50
+ def parent_id
51
+ "!Ref " + parent_path_parameter
52
+ end
53
+
54
+ def path_part
55
+ last_part = path.split('/').last
56
+ last_part.split('/').map {|s| transform_capture(s) }.join('/') if last_part
57
+ end
58
+
59
+ # Modify the path to conform to API Gateway capture expressions
60
+ def path
61
+ @path.split('/').map {|s| transform_capture(s) }.join('/')
62
+ end
63
+
64
+ def transform_capture(text)
65
+ if text.starts_with?(':')
66
+ text = text.sub(':','')
67
+ text = "{#{text}}" # :foo => {foo}
68
+ end
69
+ if text.starts_with?('*')
70
+ text = text.sub('*','')
71
+ text = "{#{text}+}" # *foo => {foo+}
72
+ end
73
+ text
74
+ end
75
+
76
+ private
77
+ # Similar path_logical_id method in resource/route.rb
78
+ def path_logical_id(path)
79
+ path.gsub('/','_').gsub(':','').gsub('*','').gsub('-','_').gsub('.','_').camelize
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,10 @@
1
+ class Jets::Resource::ApiGateway::RestApi
2
+ class ChangeDetection
3
+ extend Memoist
4
+ include Jets::AwsServices
5
+
6
+ def changed?
7
+ Routes.changed?
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,49 @@
1
+ class Jets::Resource::ApiGateway::RestApi::LogicalId
2
+ class Message
3
+ def routes_changed
4
+ <<~EOL
5
+ Routes Change Detection: Jets has detected that a new brand API Gateway is required to be deployed.
6
+ IMPORTANT: This will result in the API Gateway endpoint changing.
7
+ EOL
8
+ end
9
+
10
+ def custom_domain
11
+ api = Jets::Resource::ApiGateway::DomainName.new
12
+ domain_name = api.domain_name
13
+ if domain_name
14
+ <<~EOL
15
+ It looks like you have already set up a custom domain.
16
+ The domain name: #{domain_name}
17
+
18
+ So you should be good to go as the custom domain will be updated with the new API Gateway endpoint.
19
+ To avoid this prompt in the future, you can configure:
20
+
21
+ config/application.rb
22
+
23
+ config.api.auto_replace = true
24
+
25
+ More info: custom domain docs: https://rubyonjets.com/docs/routing/custom-domain/
26
+ EOL
27
+ else
28
+ "Please set up a custom domain https://rubyonjets.com/docs/routing/custom-domain/"
29
+ end
30
+ end
31
+
32
+ def auto_replace_disabled
33
+ <<~EOL
34
+ It looks like `config.api.auto_replace = false`. IE:
35
+
36
+ config/application.rb
37
+
38
+ config.api.auto_replace = false
39
+
40
+ The deploy will not continue. See:
41
+
42
+ * https://rubyonjets.com/docs/app-config/reference/
43
+ * https://rubyonjets.com/docs/routing/custom-domain/
44
+
45
+ EOL
46
+ end
47
+ end
48
+ end
49
+
@@ -0,0 +1,98 @@
1
+ class Jets::Resource::ApiGateway::RestApi
2
+ class LogicalId
3
+ extend Memoist
4
+ include Jets::AwsServices
5
+
6
+ def get
7
+ return default if ENV['JETS_BUILD_NO_INTERNET']
8
+ return default unless stack_exists?(parent_stack_name) && api_gateway_exists?
9
+
10
+ if changed?
11
+ auto_replace_prompt
12
+ new_id
13
+ else
14
+ current
15
+ end
16
+ end
17
+
18
+ def auto_replace_prompt
19
+ return if ENV['JETS_API_AUTO_REPLACE']
20
+ return unless ARGV[0] == "deploy"
21
+ case Jets.config.api.auto_replace
22
+ when nil
23
+ puts message.routes_changed
24
+ puts message.custom_domain
25
+ print "Would you like to continue the deployment? (y/N) "
26
+ answer = get_answer
27
+ exit 1 unless answer =~ /^y/
28
+ when false
29
+ puts message.routes_changed
30
+ puts message.auto_replace_disabled
31
+ exit 1
32
+ end
33
+ end
34
+
35
+ def message
36
+ Message.new
37
+ end
38
+ memoize :message
39
+
40
+ TIMEOUT_PERIOD = 120
41
+ def get_answer
42
+ Timeout::timeout(TIMEOUT_PERIOD) do
43
+ $stdin.gets
44
+ end
45
+ rescue Timeout::Error => e
46
+ puts "#{e.class}: #{e.message}".color(:red)
47
+ puts "Deployment timeout after #{TIMEOUT_PERIOD}s. Waited too long answer. Exiting."
48
+ exit 1
49
+ end
50
+
51
+ def changed?
52
+ change_detection = ChangeDetection.new
53
+ change_detection.changed?
54
+ end
55
+
56
+ # Takes current logical id and increments the number that is appended to it.
57
+ #
58
+ # Examples:
59
+ #
60
+ # RestApi => RestApi1
61
+ # RestApi1 => RestApi2
62
+ # RestApi2 => RestApi3
63
+ # RestApi7 => RestApi8
64
+ def new_id
65
+ regexp = /(\d+)/
66
+ md = current.match(regexp)
67
+ if md
68
+ current.gsub(regexp,'') + (md[1].to_i + 1).to_s
69
+ else
70
+ current + "1"
71
+ end
72
+ end
73
+
74
+ def current
75
+ resources = cfn.describe_stack_resources(stack_name: api_gateway_stack_arn).stack_resources
76
+ rest_api = resources.find { |r| r.resource_type == 'AWS::ApiGateway::RestApi' }
77
+ rest_api.logical_resource_id
78
+ end
79
+ memoize :current
80
+
81
+ def api_gateway_stack_arn
82
+ stack = cfn.describe_stacks(stack_name: parent_stack_name).stacks.first
83
+ lookup(stack[:outputs], "ApiGateway") # api_gateway_stack_arn
84
+ end
85
+
86
+ def api_gateway_exists?
87
+ !!api_gateway_stack_arn
88
+ end
89
+
90
+ def parent_stack_name
91
+ Jets::Naming.parent_stack_name
92
+ end
93
+
94
+ def default
95
+ "RestApi"
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,136 @@
1
+ class Jets::Resource::ApiGateway::RestApi::Routes::Change
2
+ class Base
3
+ extend Memoist
4
+ include Jets::AwsServices
5
+
6
+ def self.changed?
7
+ new.changed?
8
+ end
9
+
10
+ # Build up deployed routes from the existing CloudFormation resources.
11
+ def deployed_routes
12
+ routes = []
13
+
14
+ resources, position = [], true
15
+ while position
16
+ position = nil if position == true # start of loop
17
+ resp = apigateway.get_resources(
18
+ rest_api_id: rest_api_id,
19
+ position: position,
20
+ limit: 500, # default: 25 max: 500
21
+ )
22
+ resources += resp.items
23
+ position = resp.position
24
+ end
25
+
26
+ resources.each do |resource|
27
+ resource_methods = resource.resource_methods
28
+ next if resource_methods.nil?
29
+
30
+ resource_methods.each do |http_verb, resource_method|
31
+ # puts "#{http_verb} #{resource.path} | resource.id #{resource.id}"
32
+ # puts to(resource.id, http_verb)
33
+
34
+ # Test changing config.cors and CloudFormation does an in-place update
35
+ # on the resource. So no need to do bluegreen deployments for OPTIONS.
36
+ next if http_verb == "OPTIONS"
37
+
38
+ path = recreate_path(resource.path)
39
+ method = http_verb.downcase.to_sym
40
+ to = to(resource.id, http_verb)
41
+ route = Jets::Router::Route.new(path: path, method: method, to: to)
42
+ routes << route
43
+ end
44
+ end
45
+ routes
46
+ end
47
+ memoize :deployed_routes
48
+
49
+ def recreate_path(path)
50
+ path = path.gsub(%r{^/},'')
51
+ path = path.gsub(/{([^}]*)\+}/, '*\1')
52
+ path.gsub(/{([^}]*)}/, ':\1')
53
+ end
54
+
55
+ def to(resource_id, http_method)
56
+ uri = method_uri(resource_id, http_method)
57
+ recreate_to(uri) unless uri.nil?
58
+ end
59
+
60
+ def method_uri(resource_id, http_method)
61
+ # https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html
62
+ resp = apigateway.get_method(
63
+ rest_api_id: rest_api_id,
64
+ resource_id: resource_id,
65
+ http_method: http_method
66
+ )
67
+ resp.method_integration.uri
68
+ end
69
+
70
+ # Parses method uri and recreates a Route to argument.
71
+ # So:
72
+ # "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:112233445566:function:demo-test-posts_controller-new/invocations"
73
+ # Returns:
74
+ # posts#new
75
+ def recreate_to(method_uri)
76
+ md = method_uri.match(/function:(.*)\//)
77
+ function_arn = md[1] # IE: demo-dev-posts_controller-new
78
+ controller, action = get_controller_action(function_arn)
79
+ "#{controller}##{action}" # IE: posts#new
80
+ end
81
+
82
+ def get_controller_action(function_arn)
83
+ if function_arn.include?('_controller-')
84
+ controller_action_from_string(function_arn)
85
+ else
86
+ controller_action_from_api(function_arn)
87
+ end
88
+ end
89
+
90
+ # TODO: If this hits the Lambda Rate limit, then list_functions also contains the Lambda
91
+ # function description. So we can paginate through list_functions results and store
92
+ # description from there if needed.
93
+ # Dont think this will be needed though because controller_action_from_string gets called
94
+ # most of the time. Also, user might be able to request their Lambda limit to be increased.
95
+ def controller_action_from_api(function_arn)
96
+ desc = lambda_function_description(function_arn)
97
+ controller, action = desc.split('#')
98
+ controller = controller.underscore.sub(/_controller$/,'')
99
+ [controller, action]
100
+ end
101
+
102
+ def controller_action_from_string(function_arn)
103
+ controller_action = function_arn.sub("#{Jets.project_namespace}-", '')
104
+ md = controller_action.match(/(.*)_controller-(.*)/)
105
+ controller = md[1]
106
+ controller = controller.gsub('-','/')
107
+ action = md[2]
108
+ [controller, action]
109
+ end
110
+
111
+ def lambda_function_description(function_arn)
112
+ resp = aws_lambda.get_function(function_name: function_arn)
113
+ resp.configuration.description # contains full info: PostsController#index
114
+ end
115
+
116
+ # Duplicated in rest_api/change_detection.rb, base_path/role.rb, rest_api/routes.rb
117
+ def rest_api_id
118
+ stack_name = Jets::Naming.parent_stack_name
119
+ return "RestApi" unless stack_exists?(stack_name)
120
+
121
+ stack = cfn.describe_stacks(stack_name: stack_name).stacks.first
122
+
123
+ api_gateway_stack_arn = lookup(stack[:outputs], "ApiGateway")
124
+
125
+ # resources = cfn.describe_stack_resources(stack_name: api_gateway_stack_arn).stack_resources
126
+ stack = cfn.describe_stacks(stack_name: api_gateway_stack_arn).stacks.first
127
+ lookup(stack[:outputs], "RestApi") # rest_api_id
128
+ end
129
+ memoize :rest_api_id
130
+
131
+ def new_routes
132
+ Jets::Router.routes
133
+ end
134
+ memoize :new_routes
135
+ end
136
+ end
@@ -0,0 +1,36 @@
1
+ class Jets::Resource::ApiGateway::RestApi::Routes::Change
2
+ class MediaTypes < Base
3
+ def changed?
4
+ current_binary_media_types != new_binary_media_types
5
+ end
6
+
7
+ def new_binary_media_types
8
+ rest_api = Jets::Resource::ApiGateway::RestApi.new
9
+ rest_api.binary_media_types
10
+ end
11
+ memoize :new_binary_media_types
12
+
13
+ def current_binary_media_types
14
+ return nil unless parent_stack_exists?
15
+
16
+ stack = cfn.describe_stacks(stack_name: parent_stack_name).stacks.first
17
+
18
+ api_gateway_stack_arn = lookup(stack[:outputs], "ApiGateway")
19
+
20
+ stack = cfn.describe_stacks(stack_name: api_gateway_stack_arn).stacks.first
21
+ rest_api_id = lookup(stack[:outputs], "RestApi")
22
+
23
+ resp = apigateway.get_rest_api(rest_api_id: rest_api_id)
24
+ resp.binary_media_types
25
+ end
26
+ memoize :current_binary_media_types
27
+
28
+ def parent_stack_exists?
29
+ stack_exists?(parent_stack_name)
30
+ end
31
+
32
+ def parent_stack_name
33
+ Jets::Naming.parent_stack_name
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,93 @@
1
+ class Jets::Resource::ApiGateway::RestApi::Routes::Change
2
+ class Page < Base
3
+ def changed?
4
+ route_page_moved? || old_api_template?
5
+ end
6
+
7
+ def route_page_moved?
8
+ moved?(new_pages, deployed_pages)
9
+ end
10
+
11
+ # Routes page to logical ids
12
+ def moved?(new_pages, deployed_pages)
13
+ not_moved = true # page has not moved
14
+ new_pages.each do |logical_id, new_page_number|
15
+ if !deployed_pages[logical_id].nil? && deployed_pages[logical_id] != new_page_number
16
+ not_moved = false # page has moved
17
+ break
18
+ end
19
+ end
20
+ !not_moved # moved
21
+ end
22
+
23
+ def new_pages
24
+ local_logical_ids_map
25
+ end
26
+ memoize :new_pages
27
+
28
+ def deployed_pages
29
+ remote_logical_ids_map
30
+ end
31
+ memoize :deployed_pages
32
+
33
+ # logical id to page map
34
+ # Important: In Cfn::Builders::ApiGatewayBuilder, the add_gateway_routes and ApiResourcesBuilder needs to run
35
+ # before the parent add_gateway_rest_api method.
36
+ def local_logical_ids_map(path_expression="#{Jets::Naming.template_path_prefix}-api-resources-*.yml")
37
+ logical_ids = {} # logical id => page number
38
+
39
+ Dir.glob(path_expression).each do |path|
40
+ md = path.match(/-api-resources-(\d+).yml/)
41
+ page_number = md[1]
42
+
43
+ template = Jets::Cfn::BuiltTemplate.get(path)
44
+ template['Resources'].keys.each do |logical_id|
45
+ logical_ids[logical_id] = page_number
46
+ end
47
+ end
48
+
49
+ logical_ids
50
+ end
51
+
52
+ # aws cloudformation describe-stack-resources --stack-name demo-dev-ApiResources1-DYGLIEY3VAWT | jq -r '.StackResources[].LogicalResourceId'
53
+ def remote_logical_ids_map
54
+ logical_ids = {} # logical id => page number
55
+
56
+ parent_resources.each do |resource|
57
+ stack_name = resource.physical_resource_id # full physical id can be used as stack name also
58
+ regexp = Regexp.new("#{Jets.config.project_namespace}-ApiResources(\\d+)-") # tricky to escape \d pattern
59
+ md = stack_name.match(regexp)
60
+ if md
61
+ page_number = md[1]
62
+
63
+ resp = cfn.describe_stack_resources(stack_name: stack_name)
64
+ resp.stack_resources.map(&:logical_resource_id).each do |logical_id|
65
+ logical_ids[logical_id] = page_number
66
+ end
67
+ end
68
+ end
69
+
70
+ logical_ids
71
+ end
72
+
73
+ def old_api_template?
74
+ logical_resource_ids = parent_resources.map(&:logical_resource_id)
75
+
76
+ api_gateway_found = logical_resource_ids.detect do |logical_id|
77
+ logical_id == "ApiGateway"
78
+ end
79
+ return false unless api_gateway_found
80
+
81
+ api_resources_found = logical_resource_ids.detect do |logical_id|
82
+ logical_id.match(/^ApiResources\d+$/)
83
+ end
84
+ !api_resources_found # if api_resources_found then it's the new structure. so opposite is old structure
85
+ end
86
+
87
+ def parent_resources
88
+ resp = cfn.describe_stack_resources(stack_name: Jets::Naming.parent_stack_name)
89
+ resp.stack_resources
90
+ end
91
+ memoize :parent_resources
92
+ end
93
+ end
@@ -0,0 +1,25 @@
1
+ # Detects route to changes
2
+ class Jets::Resource::ApiGateway::RestApi::Routes::Change
3
+ class To < Base
4
+ def changed?
5
+ deployed_routes.each do |deployed_route|
6
+ new_route = find_comparable_route(deployed_route)
7
+ if new_route && new_route.to != deployed_route.to
8
+ # change in already deployed route has been detected, requires bluegreen deploy
9
+ return true
10
+ end
11
+ end
12
+ false # Reaching here means no routes have been changed in a way that requires a bluegreen deploy
13
+ end
14
+
15
+ # Find a route that has the same path and method. This is a comparable route
16
+ # Then we will compare the to or controller action to see if an already
17
+ # deployed route has been changed.
18
+ def find_comparable_route(deployed_route)
19
+ new_routes.find do |new_route|
20
+ new_route.path == deployed_route.path &&
21
+ new_route.method == deployed_route.method
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ # Detects route variable changes
2
+ class Jets::Resource::ApiGateway::RestApi::Routes::Change
3
+ class Variable < Base
4
+ def changed?
5
+ changed = false
6
+ deployed_routes.each do |deployed_route|
7
+ parent = collision.variable_parent(deployed_route.path)
8
+ parent_variables = collision.parent_variables(parent, [deployed_route.path])
9
+ new_parent_variables = collision.parent_variables(parent, new_paths)
10
+
11
+ changed = parent_variables.size > 0 && new_parent_variables.size > 0 &&
12
+ parent_variables != new_parent_variables
13
+ break if changed
14
+ end
15
+ changed
16
+ end
17
+
18
+ # Only consider paths with variables
19
+ def new_paths
20
+ new_routes.map(&:path).select {|p| p.include?(':')}.uniq
21
+ end
22
+
23
+ # Only consider deployed routes with variables
24
+ def deployed_routes
25
+ deployed_routes = super
26
+ deployed_routes.select do |route|
27
+ route.path.include?(':')
28
+ end
29
+ end
30
+
31
+ def collision
32
+ @collision ||= Jets::Resource::ApiGateway::RestApi::Routes::Collision.new
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ # Detects route changes
2
+ class Jets::Resource::ApiGateway::RestApi::Routes
3
+ class Change
4
+ include Jets::AwsServices
5
+
6
+ def changed?
7
+ return false unless parent_stack_exists?
8
+
9
+ MediaTypes.changed? || To.changed? || Variable.changed? || Page.changed? || ENV['JETS_REPLACE_API']
10
+ end
11
+
12
+ def parent_stack_exists?
13
+ stack_exists?(Jets::Naming.parent_stack_name)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ class Jets::Resource::ApiGateway::RestApi::Routes::Collision
2
+ class VariableException < RuntimeError
3
+ def initialize(message="Route variable collisions")
4
+ super(message)
5
+ end
6
+ end
7
+ end