jets 0.2.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/bin/commit_docs.sh +26 -0
  3. data/.circleci/config.yml +126 -0
  4. data/.codebuild/README.md +57 -0
  5. data/.codebuild/bin/jets +3 -0
  6. data/.codebuild/buildspec-base.yml +14 -0
  7. data/.codebuild/integration.sh +54 -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 +20 -0
  12. data/.codebuild/scripts/install-node.sh +4 -0
  13. data/.gitignore +3 -0
  14. data/.gitmodules +9 -0
  15. data/.python-version +1 -0
  16. data/.rspec +2 -0
  17. data/.ruby-version +1 -1
  18. data/CHANGELOG.md +3 -0
  19. data/Dockerfile +16 -0
  20. data/Dockerfile.base +53 -0
  21. data/Gemfile +8 -1
  22. data/Gemfile.lock +132 -28
  23. data/LICENSE.txt +1 -1
  24. data/Procfile +2 -0
  25. data/README.md +116 -17
  26. data/Rakefile +6 -0
  27. data/buildspec.yml +18 -0
  28. data/exe/jets +14 -0
  29. data/jets.gemspec +31 -3
  30. data/lib/jets.rb +56 -8
  31. data/lib/jets/application.rb +121 -0
  32. data/lib/jets/application/middleware.rb +23 -0
  33. data/lib/jets/aws_services.rb +71 -0
  34. data/lib/jets/booter.rb +95 -0
  35. data/lib/jets/builders.rb +6 -0
  36. data/lib/jets/builders/code_builder.rb +431 -0
  37. data/lib/jets/builders/deducer.rb +73 -0
  38. data/lib/jets/builders/gem_replacer.rb +154 -0
  39. data/lib/jets/builders/handler_generator.rb +76 -0
  40. data/lib/jets/builders/node-hello.js +73 -0
  41. data/lib/jets/builders/node-shim.js +151 -0
  42. data/lib/jets/cfn.rb +5 -4
  43. data/lib/jets/cfn/ship.rb +178 -0
  44. data/lib/jets/cfn/status.rb +208 -0
  45. data/lib/jets/cfn/template_builders.rb +21 -0
  46. data/lib/jets/cfn/template_builders/api_gateway_builder.rb +73 -0
  47. data/lib/jets/cfn/template_builders/api_gateway_deployment_builder.rb +38 -0
  48. data/lib/jets/cfn/template_builders/base_child_builder.rb +38 -0
  49. data/lib/jets/cfn/template_builders/controller_builder.rb +107 -0
  50. data/lib/jets/cfn/template_builders/function_builder.rb +20 -0
  51. data/lib/jets/cfn/template_builders/function_properties.rb +6 -0
  52. data/lib/jets/cfn/template_builders/function_properties/base_builder.rb +106 -0
  53. data/lib/jets/cfn/template_builders/function_properties/node_builder.rb +12 -0
  54. data/lib/jets/cfn/template_builders/function_properties/python_builder.rb +12 -0
  55. data/lib/jets/cfn/template_builders/function_properties/ruby_builder.rb +13 -0
  56. data/lib/jets/cfn/template_builders/interface.rb +91 -0
  57. data/lib/jets/cfn/template_builders/job_builder.rb +63 -0
  58. data/lib/jets/cfn/template_builders/parent_builder.rb +97 -0
  59. data/lib/jets/cfn/template_builders/rule_builder.rb +55 -0
  60. data/lib/jets/cfn/template_builders/templates/minimal-stack.yml +45 -0
  61. data/lib/jets/cfn/template_mappers.rb +23 -0
  62. data/lib/jets/cfn/template_mappers/api_gateway_deployment_mapper.rb +48 -0
  63. data/lib/jets/cfn/template_mappers/api_gateway_mapper.rb +4 -0
  64. data/lib/jets/cfn/template_mappers/child_mapper.rb +41 -0
  65. data/lib/jets/cfn/template_mappers/config_rule_mapper.rb +34 -0
  66. data/lib/jets/cfn/template_mappers/controller_mapper.rb +36 -0
  67. data/lib/jets/cfn/template_mappers/events_rule_mapper.rb +40 -0
  68. data/lib/jets/cfn/template_mappers/function_mapper.rb +4 -0
  69. data/lib/jets/cfn/template_mappers/gateway_method_mapper.rb +56 -0
  70. data/lib/jets/cfn/template_mappers/gateway_resource_mapper.rb +62 -0
  71. data/lib/jets/cfn/template_mappers/job_mapper.rb +4 -0
  72. data/lib/jets/cfn/template_mappers/lambda_function_mapper.rb +50 -0
  73. data/lib/jets/cfn/template_mappers/rule_mapper.rb +5 -0
  74. data/lib/jets/cli.rb +180 -15
  75. data/lib/jets/commands.rb +22 -0
  76. data/lib/jets/commands/base.rb +151 -0
  77. data/lib/jets/commands/build.rb +186 -0
  78. data/lib/jets/commands/call.rb +175 -0
  79. data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
  80. data/lib/jets/commands/call/autoload_guesser.rb +112 -0
  81. data/lib/jets/commands/call/base_guesser.rb +33 -0
  82. data/lib/jets/commands/call/guesser.rb +51 -0
  83. data/lib/jets/commands/console.rb +12 -0
  84. data/lib/jets/commands/db.rb +15 -0
  85. data/lib/jets/commands/db/environment-task.rake +3 -0
  86. data/lib/jets/commands/db/tasks.rb +30 -0
  87. data/lib/jets/commands/dbconsole.rb +131 -0
  88. data/lib/jets/commands/delete.rb +119 -0
  89. data/lib/jets/commands/deploy.rb +53 -0
  90. data/lib/jets/commands/dynamodb.rb +22 -0
  91. data/lib/jets/commands/dynamodb/migrate.rb +9 -0
  92. data/lib/jets/commands/dynamodb/migrator.rb +36 -0
  93. data/lib/jets/commands/help.rb +9 -0
  94. data/lib/jets/commands/help/build.md +1 -0
  95. data/lib/jets/commands/help/call.md +55 -0
  96. data/lib/jets/commands/help/console.md +4 -0
  97. data/lib/jets/commands/help/db/generate.md +8 -0
  98. data/lib/jets/commands/help/dbconsole.md +5 -0
  99. data/lib/jets/commands/help/delete.md +9 -0
  100. data/lib/jets/commands/help/deploy.md +5 -0
  101. data/lib/jets/commands/help/dynamodb/generate.md +50 -0
  102. data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
  103. data/lib/jets/commands/help/generate.md +5 -0
  104. data/lib/jets/commands/help/new.md +9 -0
  105. data/lib/jets/commands/help/process/controller.md +6 -0
  106. data/lib/jets/commands/help/process/function.md +5 -0
  107. data/lib/jets/commands/help/process/job.md +5 -0
  108. data/lib/jets/commands/help/process/rule.md +5 -0
  109. data/lib/jets/commands/help/routes.md +3 -0
  110. data/lib/jets/commands/help/server.md +6 -0
  111. data/lib/jets/commands/help/status.md +1 -0
  112. data/lib/jets/commands/help/url.md +5 -0
  113. data/lib/jets/commands/main.rb +111 -0
  114. data/lib/jets/commands/markdown.rb +8 -0
  115. data/lib/jets/commands/markdown/creator.rb +58 -0
  116. data/lib/jets/commands/markdown/index.rb +27 -0
  117. data/lib/jets/commands/markdown/page.rb +125 -0
  118. data/lib/jets/commands/markdown/shell.rb +11 -0
  119. data/lib/jets/commands/new.rb +110 -0
  120. data/lib/jets/commands/rake_command.rb +61 -0
  121. data/lib/jets/commands/rake_tasks.rb +45 -0
  122. data/lib/jets/commands/sequence.rb +44 -0
  123. data/lib/jets/commands/stack_info.rb +30 -0
  124. data/lib/jets/commands/templates/skeleton/.env +2 -0
  125. data/lib/jets/commands/templates/skeleton/.env.development.tt +3 -0
  126. data/lib/jets/commands/templates/skeleton/.env.test +3 -0
  127. data/lib/jets/commands/templates/skeleton/.gitignore +14 -0
  128. data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
  129. data/lib/jets/commands/templates/skeleton/Gemfile.tt +27 -0
  130. data/lib/jets/commands/templates/skeleton/Procfile +7 -0
  131. data/lib/jets/commands/templates/skeleton/README.md +4 -0
  132. data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
  133. data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
  134. data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
  135. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +2 -0
  136. data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
  137. data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
  138. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +24 -0
  139. data/lib/jets/commands/templates/skeleton/bin/ruby_server +18 -0
  140. data/lib/jets/commands/templates/skeleton/bin/ruby_server.rb +2 -0
  141. data/lib/jets/commands/templates/skeleton/config.ru +4 -0
  142. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +26 -0
  143. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +27 -0
  144. data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +25 -0
  145. data/lib/jets/commands/templates/skeleton/config/routes.rb +8 -0
  146. data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
  147. data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
  148. data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
  149. data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
  150. data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
  151. data/lib/jets/commands/templates/skeleton/public/index.html.tt +79 -0
  152. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +18 -0
  153. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
  154. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
  155. data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +27 -0
  156. data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +14 -0
  157. data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
  158. data/lib/jets/commands/templates/webpacker/app/javascript/src/jets/crud.js +87 -0
  159. data/lib/jets/commands/url.rb +45 -0
  160. data/lib/jets/commands/webpacker_template.rb +19 -0
  161. data/lib/jets/controller.rb +9 -0
  162. data/lib/jets/controller/base.rb +50 -0
  163. data/lib/jets/controller/callbacks.rb +43 -0
  164. data/lib/jets/controller/layout.rb +17 -0
  165. data/lib/jets/controller/params.rb +53 -0
  166. data/lib/jets/controller/redirection.rb +55 -0
  167. data/lib/jets/controller/renderers.rb +5 -0
  168. data/lib/jets/controller/renderers/aws_proxy_renderer.rb +69 -0
  169. data/lib/jets/controller/renderers/base_renderer.rb +16 -0
  170. data/lib/jets/controller/renderers/template_renderer.rb +107 -0
  171. data/lib/jets/controller/rendering.rb +80 -0
  172. data/lib/jets/controller/request.rb +55 -0
  173. data/lib/jets/core.rb +81 -0
  174. data/lib/jets/default/application.rb +20 -0
  175. data/lib/jets/dotenv.rb +37 -0
  176. data/lib/jets/erb.rb +51 -0
  177. data/lib/jets/generator.rb +40 -0
  178. data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
  179. data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +39 -0
  180. data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
  181. data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
  182. data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
  183. data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
  184. data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
  185. data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
  186. data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
  187. data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
  188. data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
  189. data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
  190. data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +71 -0
  191. data/lib/jets/internal/app/controllers/jets/public_controller.rb +30 -0
  192. data/lib/jets/internal/app/controllers/jets/public_controller/python/show.py +47 -0
  193. data/lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc +0 -0
  194. data/lib/jets/internal/app/controllers/jets/welcome_controller.rb +22 -0
  195. data/lib/jets/internal/app/controllers/jets/welcome_controller/python/index.py +24 -0
  196. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +52 -0
  197. data/lib/jets/job.rb +5 -0
  198. data/lib/jets/job/base.rb +29 -0
  199. data/lib/jets/job/dsl.rb +58 -0
  200. data/lib/jets/job/task.rb +17 -0
  201. data/lib/jets/klass.rb +71 -0
  202. data/lib/jets/lambda.rb +18 -0
  203. data/lib/jets/lambda/dsl.rb +153 -0
  204. data/lib/jets/lambda/function.rb +29 -0
  205. data/lib/jets/lambda/function_constructor.rb +60 -0
  206. data/lib/jets/lambda/functions.rb +22 -0
  207. data/lib/jets/lambda/task.rb +77 -0
  208. data/lib/jets/naming.rb +61 -0
  209. data/lib/jets/pascalize.rb +30 -0
  210. data/lib/jets/poly_fun.rb +61 -0
  211. data/lib/jets/poly_fun/base_executor.rb +129 -0
  212. data/lib/jets/poly_fun/lambda_executor.rb +16 -0
  213. data/lib/jets/poly_fun/node_error.rb +8 -0
  214. data/lib/jets/poly_fun/node_executor.rb +54 -0
  215. data/lib/jets/poly_fun/python_error.rb +8 -0
  216. data/lib/jets/poly_fun/python_executor.rb +23 -0
  217. data/lib/jets/preheat.rb +72 -0
  218. data/lib/jets/processors.rb +4 -0
  219. data/lib/jets/processors/deducer.rb +54 -0
  220. data/lib/jets/processors/main_processor.rb +57 -0
  221. data/lib/jets/rails_overrides.rb +4 -0
  222. data/lib/jets/rails_overrides/asset_tag_helper.rb +41 -0
  223. data/lib/jets/rails_overrides/common_methods.rb +13 -0
  224. data/lib/jets/rails_overrides/rendering_helper.rb +26 -0
  225. data/lib/jets/rails_overrides/url_helper.rb +26 -0
  226. data/lib/jets/route.rb +145 -0
  227. data/lib/jets/router.rb +115 -0
  228. data/lib/jets/ruby_server.rb +91 -0
  229. data/lib/jets/rule.rb +5 -0
  230. data/lib/jets/rule/base.rb +19 -0
  231. data/lib/jets/rule/dsl.rb +64 -0
  232. data/lib/jets/rule/task.rb +44 -0
  233. data/lib/jets/server.rb +16 -0
  234. data/lib/jets/server/api_gateway.rb +39 -0
  235. data/lib/jets/server/lambda_aws_proxy.rb +122 -0
  236. data/lib/jets/server/route_matcher.rb +96 -0
  237. data/lib/jets/server/timing_middleware.rb +16 -0
  238. data/lib/jets/server/webpacker_setup.rb +7 -0
  239. data/lib/jets/timing.rb +65 -0
  240. data/lib/jets/timing/report.rb +82 -0
  241. data/lib/jets/util.rb +7 -12
  242. data/lib/jets/version.rb +1 -1
  243. data/support/clean +3 -0
  244. data/support/console +3 -0
  245. metadata +473 -76
  246. data/bin/jets +0 -14
  247. data/lib/jets/base_controller.rb +0 -54
  248. data/lib/jets/build.rb +0 -46
  249. data/lib/jets/build/handler_generator.rb +0 -46
  250. data/lib/jets/build/lambda_deducer.rb +0 -23
  251. data/lib/jets/build/templates/handler.js +0 -149
  252. data/lib/jets/build/traveling_ruby.rb +0 -133
  253. data/lib/jets/cfn/base.rb +0 -17
  254. data/lib/jets/cfn/builder.rb +0 -53
  255. data/lib/jets/cfn/namer.rb +0 -30
  256. data/lib/jets/cli/help.rb +0 -19
  257. data/lib/jets/command.rb +0 -25
  258. data/lib/jets/process.rb +0 -18
  259. data/lib/jets/process/base_processor.rb +0 -23
  260. data/lib/jets/process/controller_processor.rb +0 -36
  261. data/lib/jets/process/help.rb +0 -11
  262. data/lib/jets/process/processor_deducer.rb +0 -51
  263. data/lib/jets/project.rb +0 -23
  264. data/notes/design.md +0 -107
  265. data/notes/faq.md +0 -3
  266. data/notes/lambda_ruby_info.md +0 -34
  267. data/notes/traveling-ruby-packaging-jets.md +0 -26
  268. data/notes/traveling-ruby-packaging.md +0 -103
  269. data/notes/traveling-ruby-structure.md +0 -6
  270. data/notes/traveling-ruby.md +0 -82
  271. data/spec/fixtures/classes.rb +0 -5
  272. data/spec/fixtures/project/.gitignore +0 -3
  273. data/spec/fixtures/project/.ruby-version +0 -1
  274. data/spec/fixtures/project/Gemfile +0 -4
  275. data/spec/fixtures/project/Gemfile.lock +0 -23
  276. data/spec/fixtures/project/app/controllers/application_controller.rb +0 -2
  277. data/spec/fixtures/project/app/controllers/posts_controller.rb +0 -12
  278. data/spec/fixtures/project/bin/jets +0 -22
  279. data/spec/fixtures/project/config/routes.rb +0 -6
  280. data/spec/fixtures/project/handlers/controllers/posts.js +0 -212
  281. data/spec/lib/cli_spec.rb +0 -20
  282. data/spec/lib/jets/base_controller_spec.rb +0 -18
  283. data/spec/lib/jets/build/handler_generator_spec.rb +0 -20
  284. data/spec/lib/jets/build/lambda_deducer_spec.rb +0 -15
  285. data/spec/lib/jets/build_spec.rb +0 -34
  286. data/spec/lib/jets/cfn/builder_spec.rb +0 -18
  287. data/spec/lib/jets/cfn/namer_spec.rb +0 -16
  288. data/spec/lib/jets/process/controller_processor_spec.rb +0 -22
  289. data/spec/lib/jets/process/infer_spec.rb +0 -24
  290. data/spec/lib/jets/process_spec.rb +0 -18
  291. data/spec/lib/jets/project_spec.rb +0 -14
  292. data/spec/spec_helper.rb +0 -28
@@ -0,0 +1,38 @@
1
+ class Jets::Cfn::TemplateBuilders
2
+ class ApiGatewayDeploymentBuilder
3
+ include Interface
4
+ include Jets::AwsServices
5
+
6
+ def initialize(options={})
7
+ @options = options
8
+ @template = ActiveSupport::HashWithIndifferentAccess.new(Resources: {})
9
+ end
10
+
11
+ # compose is an interface method
12
+ def compose
13
+ return if @options[:stack_type] == :minimal
14
+
15
+ puts "Building API Gateway Deployment template."
16
+ add_parameter("RestApi", Description: "RestApi")
17
+
18
+ map = Jets::Cfn::TemplateMappers::ApiGatewayDeploymentMapper.new(path=nil,s3_bucket=nil)
19
+ add_resource(map.logical_id, "AWS::ApiGateway::Deployment",
20
+ Description: "Version #{map.timestamp} deployed by jets",
21
+ RestApiId: "!Ref RestApi",
22
+ StageName: map.stage_name,
23
+ )
24
+
25
+ add_output("RestApiUrl", Value: "!Sub 'https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/#{map.stage_name}/'")
26
+ end
27
+
28
+ # template_path is an interface method
29
+ def template_path
30
+ Jets::Naming.api_gateway_deployment_template_path
31
+ end
32
+
33
+ # do not bother writing a template if routes are empty
34
+ def write
35
+ super unless Jets::Router.routes.empty?
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ class Jets::Cfn::TemplateBuilders
2
+ class BaseChildBuilder
3
+ include Interface
4
+
5
+ # The app_klass is can be a controller, job or anonymous function class.
6
+ # IE: PostsController, HardJob
7
+ def initialize(app_klass)
8
+ @app_klass = app_klass
9
+ @template = ActiveSupport::HashWithIndifferentAccess.new(Resources: {})
10
+ end
11
+
12
+ # template_path is an interface method for Interface module
13
+ def template_path
14
+ Jets::Naming.template_path(@app_klass)
15
+ end
16
+
17
+ def add_common_parameters
18
+ add_parameter("IamRole", Description: "Iam Role that Lambda function uses.")
19
+ add_parameter("S3Bucket", Description: "S3 Bucket for source code.")
20
+ end
21
+
22
+ def add_functions
23
+ @app_klass.tasks.each do |task|
24
+ add_function(task)
25
+ end
26
+ end
27
+
28
+ def add_function(task)
29
+ # Examples:
30
+ # FunctionProperties::RubyBuilder
31
+ # FunctionProperties::PythonBuilder
32
+ builder_class = "Jets::Cfn::TemplateBuilders::FunctionProperties::#{task.lang.to_s.classify}Builder".constantize
33
+ builder = builder_class.new(task)
34
+ logical_id = builder.map.logical_id
35
+ add_resource(logical_id, "AWS::Lambda::Function", builder.properties)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,107 @@
1
+ class Jets::Cfn::TemplateBuilders
2
+ class ControllerBuilder < BaseChildBuilder
3
+ # compose is an interface method for Interface module
4
+ def compose
5
+ add_common_parameters
6
+ add_api_gateway_parameters
7
+ add_functions
8
+ add_routes
9
+ end
10
+
11
+ def add_api_gateway_parameters
12
+ return if Jets::Router.routes.empty?
13
+
14
+ add_parameter("RestApi", Description: "RestApi")
15
+ scoped_routes.each do |route|
16
+ map = Jets::Cfn::TemplateMappers::GatewayResourceMapper.new(route.path)
17
+ add_parameter(map.logical_id, Description: map.desc)
18
+ end
19
+ end
20
+
21
+ def add_routes
22
+ scoped_routes.each_with_index do |route, i|
23
+ map = Jets::Cfn::TemplateMappers::GatewayMethodMapper.new(route)
24
+ add_route(route, map)
25
+ add_cors(map)
26
+ add_permission(map)
27
+ end
28
+ end
29
+
30
+ def add_route(route, map)
31
+ # AWS::ApiGateway::Method
32
+ # Example map.logical_id: ApiGatewayMethodPostsControllerIndex
33
+ add_resource(map.logical_id, "AWS::ApiGateway::Method",
34
+ HttpMethod: route.method,
35
+ RequestParameters: {},
36
+ ResourceId: "!Ref #{map.gateway_resource_logical_id}",
37
+ RestApiId: "!Ref RestApi",
38
+ AuthorizationType: "NONE",
39
+ Integration: {
40
+ IntegrationHttpMethod: "POST",
41
+ Type: "AWS_PROXY",
42
+ Uri: "!Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${#{map.lambda_function_logical_id}.Arn}/invocations"
43
+ },
44
+ MethodResponses:[]
45
+ )
46
+ end
47
+
48
+ def add_cors(map)
49
+ # TODO: provide a way to allow specify CORs domains
50
+ return unless Jets.config.cors
51
+
52
+ add_resource(map.cors_logical_id, "AWS::ApiGateway::Method",
53
+ AuthorizationType: "NONE",
54
+ HttpMethod: "OPTIONS",
55
+ MethodResponses: [
56
+ {
57
+ StatusCode: "200",
58
+ ResponseParameters: {
59
+ "method.response.header.Access-Control-AllowOrigin" => true,
60
+ "method.response.header.Access-Control-AllowHeaders" => true,
61
+ "method.response.header.Access-Control-AllowMethods" => true,
62
+ "method.response.header.Access-Control-AllowCredentials" => true
63
+ },
64
+ ResponseModels: {}
65
+ }
66
+ ],
67
+ RequestParameters: {},
68
+ Integration: {
69
+ Type: "MOCK",
70
+ RequestTemplates: {
71
+ "application/json" => "{statusCode:200}"
72
+ },
73
+ IntegrationResponses: [
74
+ {
75
+ StatusCode: "200",
76
+ ResponseParameters: {
77
+ "method.response.header.Access-Control-AllowOrigin" => "'*'",
78
+ "method.response.header.Access-Control-AllowHeaders" => "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'",
79
+ "method.response.header.Access-Control-AllowMethods" => "'OPTIONS,GET'",
80
+ "method.response.header.Access-Control-AllowCredentials" => "'false'"
81
+ },
82
+ ResponseTemplates: {"application/json" => ""}
83
+ }
84
+ ]
85
+ },
86
+ ResourceId: "!Ref #{map.gateway_resource_logical_id}",
87
+ RestApiId: "!Ref RestApi",
88
+ )
89
+ end
90
+
91
+ def add_permission(map)
92
+ add_resource(map.permission_logical_id, "AWS::Lambda::Permission",
93
+ FunctionName: "!GetAtt #{map.lambda_function_logical_id}.Arn",
94
+ Action: "lambda:InvokeFunction",
95
+ Principal: "apigateway.amazonaws.com",
96
+ SourceArn: "!Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${RestApi}/*/*"
97
+ )
98
+ end
99
+
100
+ # routes scoped to this controller template.
101
+ def scoped_routes
102
+ @routes ||= Jets::Router.routes.select do |route|
103
+ route.controller_name == @app_klass.to_s
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,20 @@
1
+ class Jets::Cfn::TemplateBuilders
2
+ class FunctionBuilder < BaseChildBuilder
3
+ # compose is an interface method for Interface module
4
+ def compose
5
+ add_common_parameters
6
+ add_functions
7
+ end
8
+
9
+ # For function stacks, ensure there's a _function.yml at the end of the
10
+ # template_path name for easy identification.
11
+ def template_path
12
+ path = super
13
+ unless path.include?("function.yml")
14
+ path = path.sub(".yml", "_function.yml")
15
+ end
16
+ path
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ module Jets::Cfn::TemplateBuilders::FunctionProperties
2
+ autoload :BaseBuilder, 'jets/cfn/template_builders/function_properties/base_builder'
3
+ autoload :RubyBuilder, 'jets/cfn/template_builders/function_properties/ruby_builder'
4
+ autoload :PythonBuilder, 'jets/cfn/template_builders/function_properties/python_builder'
5
+ autoload :NodeBuilder, 'jets/cfn/template_builders/function_properties/node_builder'
6
+ end
@@ -0,0 +1,106 @@
1
+ # Jets::Cfn::TemplateBuilders does not stick to the TemplateBuilders::Interface.
2
+ # It builds the properties of a function. Usage:
3
+ #
4
+ # builder = FunctionProperties::PythonBuilder.new(task)
5
+ # buider.properties
6
+ # buider.map.logical_id # to access Function's logical id
7
+ #
8
+ module Jets::Cfn::TemplateBuilders::FunctionProperties
9
+ class BaseBuilder
10
+ def initialize(task)
11
+ @task = task
12
+ end
13
+
14
+ def map
15
+ @map ||= Jets::Cfn::TemplateMappers::LambdaFunctionMapper.new(@task)
16
+ end
17
+
18
+ def properties
19
+ props = env_file_properties
20
+ .deep_merge(global_properties)
21
+ .deep_merge(class_properties)
22
+ .deep_merge(function_properties)
23
+ finalize_properties!(props)
24
+ end
25
+
26
+ # Add properties managed by Jets.
27
+ def finalize_properties!(props)
28
+ handler = full_handler(props)
29
+ runtime = get_runtime(props)
30
+ props.merge!(
31
+ "FunctionName" => map.function_name,
32
+ "Handler" => handler,
33
+ "Runtime" => runtime,
34
+ )
35
+ end
36
+
37
+ def get_runtime(props)
38
+ props["Runtime"] || default_runtime
39
+ end
40
+
41
+ # Ensure that the handler path is normalized.
42
+ def full_handler(props)
43
+ if props["Handler"]
44
+ map.handler_value(props["Handler"])
45
+ else
46
+ default_handler
47
+ end
48
+ end
49
+
50
+ # Global properties example:
51
+ # jets defaults are in jets/default/application.rb.
52
+ # Your application's default config/application.rb then get used. Example:
53
+ #
54
+ # Jets.application.configure do
55
+ # config.function = ActiveSupport::OrderedOptions.new
56
+ # config.function.timeout = 10
57
+ # config.function.runtime = "nodejs8.10"
58
+ # config.function.memory_size = 3008
59
+ # end
60
+ def global_properties
61
+ baseline = {
62
+ Code: {
63
+ S3Bucket: {Ref: "S3Bucket"}, # from child stack
64
+ S3Key: map.code_s3_key
65
+ },
66
+ Role: { Ref: "IamRole" },
67
+ Environment: { Variables: map.environment },
68
+ }.deep_stringify_keys
69
+
70
+ app_config_props = Jets.application.config.function.to_h
71
+ app_config_props = Pascalize.pascalize(app_config_props.deep_stringify_keys)
72
+
73
+ baseline.deep_merge(app_config_props)
74
+ end
75
+
76
+ # Class properties example:
77
+ #
78
+ # class PostsController < ApplicationController
79
+ # class_timeout 22
80
+ # ...
81
+ # end
82
+ def class_properties
83
+ # klass is PostsController, HardJob, GameRule, Hello or HelloFunction
84
+ klass = Jets::Klass.from_task(@task)
85
+ class_properties = klass.class_properties
86
+ Pascalize.pascalize(class_properties.deep_stringify_keys)
87
+ end
88
+
89
+ # Function properties example:
90
+ #
91
+ # class PostsController < ApplicationController
92
+ # timeout 18
93
+ # def index
94
+ # ...
95
+ # end
96
+ def function_properties
97
+ Pascalize.pascalize(@task.properties.deep_stringify_keys)
98
+ end
99
+
100
+ def env_file_properties
101
+ env_vars = Jets::Dotenv.load!(true)
102
+ Pascalize.pascalize(environment: { variables: env_vars })
103
+ end
104
+ end
105
+ end
106
+
@@ -0,0 +1,12 @@
1
+ module Jets::Cfn::TemplateBuilders::FunctionProperties
2
+ class NodeBuilder < BaseBuilder
3
+ def default_handler
4
+ @task.full_handler(:handler) # IE: handlers/controllers/posts/show.handler
5
+ end
6
+
7
+ # https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html#SSS-CreateFunction-request-Runtime
8
+ def default_runtime
9
+ "nodejs8.10"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Jets::Cfn::TemplateBuilders::FunctionProperties
2
+ class PythonBuilder < BaseBuilder
3
+ def default_handler
4
+ @task.full_handler(:lambda_handler) # IE: handlers/controllers/posts/show.lambda_handler
5
+ end
6
+
7
+ # https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html#SSS-CreateFunction-request-Runtime
8
+ def default_runtime
9
+ "python3.6"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Jets::Cfn::TemplateBuilders::FunctionProperties
2
+ class RubyBuilder < BaseBuilder
3
+ def default_runtime
4
+ "nodejs8.10" # using node shim for ruby support
5
+ end
6
+
7
+ # Override this in subclasses like PythonBuilder.
8
+ # Dynamically generated handler.
9
+ def default_handler
10
+ map.handler # IE: handlers/controllers/posts_controllers.index
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,91 @@
1
+ # The class including this module should implement these methods:
2
+ #
3
+ # * compose
4
+ # * template_path
5
+ class Jets::Cfn::TemplateBuilders
6
+ module Interface
7
+ def build
8
+ return if @app_klass && @app_klass.tasks.empty? # do not bother building
9
+ #or writing the template unless there are functions defined
10
+
11
+ compose # must be implemented by subclass
12
+ write
13
+ end
14
+
15
+ def write
16
+ FileUtils.mkdir_p(File.dirname(template_path))
17
+ IO.write(template_path, text)
18
+ end
19
+
20
+ def template
21
+ # need the to_hash or the YAML dump has
22
+ # !ruby/hash:ActiveSupport::HashWithIndifferentAccess
23
+ @template.to_hash
24
+ end
25
+
26
+ def text
27
+ text = YAML.dump(template)
28
+ post_process_template(text)
29
+ end
30
+
31
+ # post process the text so that
32
+ # "!Ref IamRole" => !Ref IamRole
33
+ # We strip the surrounding quotes
34
+ def post_process_template(text)
35
+ results = text.split("\n").map do |line|
36
+ if line.include?(': "!') # IE: IamRole: "!Ref IamRole",
37
+ # IamRole: "!Ref IamRole" => IamRole: !Ref IamRole
38
+ line.sub(/: "(.*)"/, ': \1')
39
+ else
40
+ line
41
+ end
42
+ end
43
+ results.join("\n") + "\n"
44
+ end
45
+
46
+ # add_resource handles an options Hash with both only Rroperties
47
+ # and also one with a nested Properties.
48
+
49
+ # Example:
50
+ #
51
+ # Simple options with properties only:
52
+ # add_resource("MyId", "AWS::CloudFormationStack",
53
+ # TemplateURL: "template_url",
54
+ # Parameters: {},
55
+ # )
56
+ #
57
+ # More complicated options:
58
+ # add_resource("MyId", "AWS::ApiGateway::RestApi",
59
+ # Properties: {
60
+ # Name: "my-api"
61
+ # },
62
+ # DependsOn: ["AnotherResource"]
63
+ # )
64
+ def add_resource(logical_id, type, options)
65
+ base = { Type: type }
66
+
67
+ options = if options.include?(:Properties)
68
+ base.merge(options)
69
+ else
70
+ {
71
+ Type: type,
72
+ Properties: options # options are properties
73
+ }
74
+ end
75
+
76
+ @template[:Resources][logical_id] = options
77
+ end
78
+
79
+ def add_parameter(name, options={})
80
+ defaults = { Type: "String" }
81
+ options = defaults.merge(options)
82
+ @template[:Parameters] ||= {}
83
+ @template[:Parameters][name.camelize] = options
84
+ end
85
+
86
+ def add_output(name, options={})
87
+ @template[:Outputs] ||= {}
88
+ @template[:Outputs][name.camelize] = options
89
+ end
90
+ end
91
+ end