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.
- checksums.yaml +5 -5
- data/.circleci/bin/commit_docs.sh +26 -0
- data/.circleci/config.yml +126 -0
- data/.codebuild/README.md +57 -0
- data/.codebuild/bin/jets +3 -0
- data/.codebuild/buildspec-base.yml +14 -0
- data/.codebuild/integration.sh +54 -0
- data/.codebuild/jets.postman_collection.json +323 -0
- data/.codebuild/scripts/install-docker.sh +12 -0
- data/.codebuild/scripts/install-dynamodb-local.sh +22 -0
- data/.codebuild/scripts/install-java.sh +20 -0
- data/.codebuild/scripts/install-node.sh +4 -0
- data/.gitignore +3 -0
- data/.gitmodules +9 -0
- data/.python-version +1 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +3 -0
- data/Dockerfile +16 -0
- data/Dockerfile.base +53 -0
- data/Gemfile +8 -1
- data/Gemfile.lock +132 -28
- data/LICENSE.txt +1 -1
- data/Procfile +2 -0
- data/README.md +116 -17
- data/Rakefile +6 -0
- data/buildspec.yml +18 -0
- data/exe/jets +14 -0
- data/jets.gemspec +31 -3
- data/lib/jets.rb +56 -8
- data/lib/jets/application.rb +121 -0
- data/lib/jets/application/middleware.rb +23 -0
- data/lib/jets/aws_services.rb +71 -0
- data/lib/jets/booter.rb +95 -0
- data/lib/jets/builders.rb +6 -0
- data/lib/jets/builders/code_builder.rb +431 -0
- data/lib/jets/builders/deducer.rb +73 -0
- data/lib/jets/builders/gem_replacer.rb +154 -0
- data/lib/jets/builders/handler_generator.rb +76 -0
- data/lib/jets/builders/node-hello.js +73 -0
- data/lib/jets/builders/node-shim.js +151 -0
- data/lib/jets/cfn.rb +5 -4
- data/lib/jets/cfn/ship.rb +178 -0
- data/lib/jets/cfn/status.rb +208 -0
- data/lib/jets/cfn/template_builders.rb +21 -0
- data/lib/jets/cfn/template_builders/api_gateway_builder.rb +73 -0
- data/lib/jets/cfn/template_builders/api_gateway_deployment_builder.rb +38 -0
- data/lib/jets/cfn/template_builders/base_child_builder.rb +38 -0
- data/lib/jets/cfn/template_builders/controller_builder.rb +107 -0
- data/lib/jets/cfn/template_builders/function_builder.rb +20 -0
- data/lib/jets/cfn/template_builders/function_properties.rb +6 -0
- data/lib/jets/cfn/template_builders/function_properties/base_builder.rb +106 -0
- data/lib/jets/cfn/template_builders/function_properties/node_builder.rb +12 -0
- data/lib/jets/cfn/template_builders/function_properties/python_builder.rb +12 -0
- data/lib/jets/cfn/template_builders/function_properties/ruby_builder.rb +13 -0
- data/lib/jets/cfn/template_builders/interface.rb +91 -0
- data/lib/jets/cfn/template_builders/job_builder.rb +63 -0
- data/lib/jets/cfn/template_builders/parent_builder.rb +97 -0
- data/lib/jets/cfn/template_builders/rule_builder.rb +55 -0
- data/lib/jets/cfn/template_builders/templates/minimal-stack.yml +45 -0
- data/lib/jets/cfn/template_mappers.rb +23 -0
- data/lib/jets/cfn/template_mappers/api_gateway_deployment_mapper.rb +48 -0
- data/lib/jets/cfn/template_mappers/api_gateway_mapper.rb +4 -0
- data/lib/jets/cfn/template_mappers/child_mapper.rb +41 -0
- data/lib/jets/cfn/template_mappers/config_rule_mapper.rb +34 -0
- data/lib/jets/cfn/template_mappers/controller_mapper.rb +36 -0
- data/lib/jets/cfn/template_mappers/events_rule_mapper.rb +40 -0
- data/lib/jets/cfn/template_mappers/function_mapper.rb +4 -0
- data/lib/jets/cfn/template_mappers/gateway_method_mapper.rb +56 -0
- data/lib/jets/cfn/template_mappers/gateway_resource_mapper.rb +62 -0
- data/lib/jets/cfn/template_mappers/job_mapper.rb +4 -0
- data/lib/jets/cfn/template_mappers/lambda_function_mapper.rb +50 -0
- data/lib/jets/cfn/template_mappers/rule_mapper.rb +5 -0
- data/lib/jets/cli.rb +180 -15
- data/lib/jets/commands.rb +22 -0
- data/lib/jets/commands/base.rb +151 -0
- data/lib/jets/commands/build.rb +186 -0
- data/lib/jets/commands/call.rb +175 -0
- data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
- data/lib/jets/commands/call/autoload_guesser.rb +112 -0
- data/lib/jets/commands/call/base_guesser.rb +33 -0
- data/lib/jets/commands/call/guesser.rb +51 -0
- data/lib/jets/commands/console.rb +12 -0
- data/lib/jets/commands/db.rb +15 -0
- data/lib/jets/commands/db/environment-task.rake +3 -0
- data/lib/jets/commands/db/tasks.rb +30 -0
- data/lib/jets/commands/dbconsole.rb +131 -0
- data/lib/jets/commands/delete.rb +119 -0
- data/lib/jets/commands/deploy.rb +53 -0
- data/lib/jets/commands/dynamodb.rb +22 -0
- data/lib/jets/commands/dynamodb/migrate.rb +9 -0
- data/lib/jets/commands/dynamodb/migrator.rb +36 -0
- data/lib/jets/commands/help.rb +9 -0
- data/lib/jets/commands/help/build.md +1 -0
- data/lib/jets/commands/help/call.md +55 -0
- data/lib/jets/commands/help/console.md +4 -0
- data/lib/jets/commands/help/db/generate.md +8 -0
- data/lib/jets/commands/help/dbconsole.md +5 -0
- data/lib/jets/commands/help/delete.md +9 -0
- data/lib/jets/commands/help/deploy.md +5 -0
- data/lib/jets/commands/help/dynamodb/generate.md +50 -0
- data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
- data/lib/jets/commands/help/generate.md +5 -0
- data/lib/jets/commands/help/new.md +9 -0
- data/lib/jets/commands/help/process/controller.md +6 -0
- data/lib/jets/commands/help/process/function.md +5 -0
- data/lib/jets/commands/help/process/job.md +5 -0
- data/lib/jets/commands/help/process/rule.md +5 -0
- data/lib/jets/commands/help/routes.md +3 -0
- data/lib/jets/commands/help/server.md +6 -0
- data/lib/jets/commands/help/status.md +1 -0
- data/lib/jets/commands/help/url.md +5 -0
- data/lib/jets/commands/main.rb +111 -0
- data/lib/jets/commands/markdown.rb +8 -0
- data/lib/jets/commands/markdown/creator.rb +58 -0
- data/lib/jets/commands/markdown/index.rb +27 -0
- data/lib/jets/commands/markdown/page.rb +125 -0
- data/lib/jets/commands/markdown/shell.rb +11 -0
- data/lib/jets/commands/new.rb +110 -0
- data/lib/jets/commands/rake_command.rb +61 -0
- data/lib/jets/commands/rake_tasks.rb +45 -0
- data/lib/jets/commands/sequence.rb +44 -0
- data/lib/jets/commands/stack_info.rb +30 -0
- data/lib/jets/commands/templates/skeleton/.env +2 -0
- data/lib/jets/commands/templates/skeleton/.env.development.tt +3 -0
- data/lib/jets/commands/templates/skeleton/.env.test +3 -0
- data/lib/jets/commands/templates/skeleton/.gitignore +14 -0
- data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
- data/lib/jets/commands/templates/skeleton/Gemfile.tt +27 -0
- data/lib/jets/commands/templates/skeleton/Procfile +7 -0
- data/lib/jets/commands/templates/skeleton/README.md +4 -0
- data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
- data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
- data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
- data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +2 -0
- data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
- data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
- data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +24 -0
- data/lib/jets/commands/templates/skeleton/bin/ruby_server +18 -0
- data/lib/jets/commands/templates/skeleton/bin/ruby_server.rb +2 -0
- data/lib/jets/commands/templates/skeleton/config.ru +4 -0
- data/lib/jets/commands/templates/skeleton/config/application.rb.tt +26 -0
- data/lib/jets/commands/templates/skeleton/config/database.yml.tt +27 -0
- data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +25 -0
- data/lib/jets/commands/templates/skeleton/config/routes.rb +8 -0
- data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
- data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
- data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
- data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
- data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
- data/lib/jets/commands/templates/skeleton/public/index.html.tt +79 -0
- data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +18 -0
- data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
- data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
- data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +27 -0
- data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +14 -0
- data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
- data/lib/jets/commands/templates/webpacker/app/javascript/src/jets/crud.js +87 -0
- data/lib/jets/commands/url.rb +45 -0
- data/lib/jets/commands/webpacker_template.rb +19 -0
- data/lib/jets/controller.rb +9 -0
- data/lib/jets/controller/base.rb +50 -0
- data/lib/jets/controller/callbacks.rb +43 -0
- data/lib/jets/controller/layout.rb +17 -0
- data/lib/jets/controller/params.rb +53 -0
- data/lib/jets/controller/redirection.rb +55 -0
- data/lib/jets/controller/renderers.rb +5 -0
- data/lib/jets/controller/renderers/aws_proxy_renderer.rb +69 -0
- data/lib/jets/controller/renderers/base_renderer.rb +16 -0
- data/lib/jets/controller/renderers/template_renderer.rb +107 -0
- data/lib/jets/controller/rendering.rb +80 -0
- data/lib/jets/controller/request.rb +55 -0
- data/lib/jets/core.rb +81 -0
- data/lib/jets/default/application.rb +20 -0
- data/lib/jets/dotenv.rb +37 -0
- data/lib/jets/erb.rb +51 -0
- data/lib/jets/generator.rb +40 -0
- data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
- data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +39 -0
- data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
- data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
- data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
- data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
- data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
- data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
- data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
- data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
- data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
- data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
- data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +71 -0
- data/lib/jets/internal/app/controllers/jets/public_controller.rb +30 -0
- data/lib/jets/internal/app/controllers/jets/public_controller/python/show.py +47 -0
- data/lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc +0 -0
- data/lib/jets/internal/app/controllers/jets/welcome_controller.rb +22 -0
- data/lib/jets/internal/app/controllers/jets/welcome_controller/python/index.py +24 -0
- data/lib/jets/internal/app/jobs/jets/preheat_job.rb +52 -0
- data/lib/jets/job.rb +5 -0
- data/lib/jets/job/base.rb +29 -0
- data/lib/jets/job/dsl.rb +58 -0
- data/lib/jets/job/task.rb +17 -0
- data/lib/jets/klass.rb +71 -0
- data/lib/jets/lambda.rb +18 -0
- data/lib/jets/lambda/dsl.rb +153 -0
- data/lib/jets/lambda/function.rb +29 -0
- data/lib/jets/lambda/function_constructor.rb +60 -0
- data/lib/jets/lambda/functions.rb +22 -0
- data/lib/jets/lambda/task.rb +77 -0
- data/lib/jets/naming.rb +61 -0
- data/lib/jets/pascalize.rb +30 -0
- data/lib/jets/poly_fun.rb +61 -0
- data/lib/jets/poly_fun/base_executor.rb +129 -0
- data/lib/jets/poly_fun/lambda_executor.rb +16 -0
- data/lib/jets/poly_fun/node_error.rb +8 -0
- data/lib/jets/poly_fun/node_executor.rb +54 -0
- data/lib/jets/poly_fun/python_error.rb +8 -0
- data/lib/jets/poly_fun/python_executor.rb +23 -0
- data/lib/jets/preheat.rb +72 -0
- data/lib/jets/processors.rb +4 -0
- data/lib/jets/processors/deducer.rb +54 -0
- data/lib/jets/processors/main_processor.rb +57 -0
- data/lib/jets/rails_overrides.rb +4 -0
- data/lib/jets/rails_overrides/asset_tag_helper.rb +41 -0
- data/lib/jets/rails_overrides/common_methods.rb +13 -0
- data/lib/jets/rails_overrides/rendering_helper.rb +26 -0
- data/lib/jets/rails_overrides/url_helper.rb +26 -0
- data/lib/jets/route.rb +145 -0
- data/lib/jets/router.rb +115 -0
- data/lib/jets/ruby_server.rb +91 -0
- data/lib/jets/rule.rb +5 -0
- data/lib/jets/rule/base.rb +19 -0
- data/lib/jets/rule/dsl.rb +64 -0
- data/lib/jets/rule/task.rb +44 -0
- data/lib/jets/server.rb +16 -0
- data/lib/jets/server/api_gateway.rb +39 -0
- data/lib/jets/server/lambda_aws_proxy.rb +122 -0
- data/lib/jets/server/route_matcher.rb +96 -0
- data/lib/jets/server/timing_middleware.rb +16 -0
- data/lib/jets/server/webpacker_setup.rb +7 -0
- data/lib/jets/timing.rb +65 -0
- data/lib/jets/timing/report.rb +82 -0
- data/lib/jets/util.rb +7 -12
- data/lib/jets/version.rb +1 -1
- data/support/clean +3 -0
- data/support/console +3 -0
- metadata +473 -76
- data/bin/jets +0 -14
- data/lib/jets/base_controller.rb +0 -54
- data/lib/jets/build.rb +0 -46
- data/lib/jets/build/handler_generator.rb +0 -46
- data/lib/jets/build/lambda_deducer.rb +0 -23
- data/lib/jets/build/templates/handler.js +0 -149
- data/lib/jets/build/traveling_ruby.rb +0 -133
- data/lib/jets/cfn/base.rb +0 -17
- data/lib/jets/cfn/builder.rb +0 -53
- data/lib/jets/cfn/namer.rb +0 -30
- data/lib/jets/cli/help.rb +0 -19
- data/lib/jets/command.rb +0 -25
- data/lib/jets/process.rb +0 -18
- data/lib/jets/process/base_processor.rb +0 -23
- data/lib/jets/process/controller_processor.rb +0 -36
- data/lib/jets/process/help.rb +0 -11
- data/lib/jets/process/processor_deducer.rb +0 -51
- data/lib/jets/project.rb +0 -23
- data/notes/design.md +0 -107
- data/notes/faq.md +0 -3
- data/notes/lambda_ruby_info.md +0 -34
- data/notes/traveling-ruby-packaging-jets.md +0 -26
- data/notes/traveling-ruby-packaging.md +0 -103
- data/notes/traveling-ruby-structure.md +0 -6
- data/notes/traveling-ruby.md +0 -82
- data/spec/fixtures/classes.rb +0 -5
- data/spec/fixtures/project/.gitignore +0 -3
- data/spec/fixtures/project/.ruby-version +0 -1
- data/spec/fixtures/project/Gemfile +0 -4
- data/spec/fixtures/project/Gemfile.lock +0 -23
- data/spec/fixtures/project/app/controllers/application_controller.rb +0 -2
- data/spec/fixtures/project/app/controllers/posts_controller.rb +0 -12
- data/spec/fixtures/project/bin/jets +0 -22
- data/spec/fixtures/project/config/routes.rb +0 -6
- data/spec/fixtures/project/handlers/controllers/posts.js +0 -212
- data/spec/lib/cli_spec.rb +0 -20
- data/spec/lib/jets/base_controller_spec.rb +0 -18
- data/spec/lib/jets/build/handler_generator_spec.rb +0 -20
- data/spec/lib/jets/build/lambda_deducer_spec.rb +0 -15
- data/spec/lib/jets/build_spec.rb +0 -34
- data/spec/lib/jets/cfn/builder_spec.rb +0 -18
- data/spec/lib/jets/cfn/namer_spec.rb +0 -16
- data/spec/lib/jets/process/controller_processor_spec.rb +0 -22
- data/spec/lib/jets/process/infer_spec.rb +0 -24
- data/spec/lib/jets/process_spec.rb +0 -18
- data/spec/lib/jets/project_spec.rb +0 -14
- data/spec/spec_helper.rb +0 -28
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
# Jets::Lambda::Functions represents a collection of Lambda functions.
|
|
4
|
+
#
|
|
5
|
+
# Jets::Lambda::Functions is the superclass of:
|
|
6
|
+
# Jets::Controller::Base
|
|
7
|
+
# Jets::Job::Base
|
|
8
|
+
module Jets::Lambda
|
|
9
|
+
class Functions
|
|
10
|
+
attr_reader :event, :context, :meth
|
|
11
|
+
def initialize(event, context, meth)
|
|
12
|
+
@event = event # Hash, JSON.parse(event) ran BaseProcessor
|
|
13
|
+
@context = context # Hash. JSON.parse(context) ran in BaseProcessor
|
|
14
|
+
@meth = meth
|
|
15
|
+
# store meth because it is useful to for identifying the which template
|
|
16
|
+
# to use later.
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
include Dsl # At the end so methods like event, context and method
|
|
20
|
+
# do not trigger method_added
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
class Jets::Lambda::Task
|
|
2
|
+
attr_accessor :class_name, :type
|
|
3
|
+
attr_reader :meth, :properties, :lang
|
|
4
|
+
def initialize(class_name, meth, options={})
|
|
5
|
+
@class_name = class_name.to_s # use at EventsRuleMapper#full_task_name
|
|
6
|
+
@meth = meth
|
|
7
|
+
@options = options
|
|
8
|
+
@type = options[:type] || get_type # controller, job, or function
|
|
9
|
+
@properties = options[:properties] || {}
|
|
10
|
+
@lang = options[:lang] || :ruby
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def name
|
|
14
|
+
@meth
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@@lang_exts = {
|
|
18
|
+
ruby: '.rb',
|
|
19
|
+
python: '.py',
|
|
20
|
+
node: '.js',
|
|
21
|
+
}
|
|
22
|
+
def lang_ext
|
|
23
|
+
@@lang_exts[@lang]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# The get_type method works for controller and job classes.
|
|
27
|
+
#
|
|
28
|
+
# Usually able to get the type from the class name. Examples:
|
|
29
|
+
#
|
|
30
|
+
# PostsController => controller
|
|
31
|
+
# HardJob => job
|
|
32
|
+
#
|
|
33
|
+
# However, for function types, we are not able to get the type for multiple of
|
|
34
|
+
# reasons. First, function types are allowed to be named with or without
|
|
35
|
+
# _function. Examples:
|
|
36
|
+
#
|
|
37
|
+
# path => class => type
|
|
38
|
+
# app/functions/hello.rb => Hello => function
|
|
39
|
+
# app/functions/hello_function.rb => HelloFunction => function
|
|
40
|
+
#
|
|
41
|
+
# The second reason is that functions are not regular ruby classes. Instead they
|
|
42
|
+
# are anonymous classes created with Class.new. When classes are created with
|
|
43
|
+
# Class.new the method_added hook has "" (blank string) as the self class name.
|
|
44
|
+
# We add the class_type to the task later on as we are constructing the class
|
|
45
|
+
# as part of the Class.new logic.
|
|
46
|
+
#
|
|
47
|
+
# For controller and job standard ruby classes though it can easily be
|
|
48
|
+
# determinated as part of initialization. So we get the type for convenience then.
|
|
49
|
+
#
|
|
50
|
+
# For anonymous function classes, we just set to nil and will later fix in
|
|
51
|
+
# FunctionConstructor.
|
|
52
|
+
#
|
|
53
|
+
# Returns: "controller", "job" or nil
|
|
54
|
+
def get_type
|
|
55
|
+
unless @class_name.empty? # when anonymous class is created with Class.new
|
|
56
|
+
@class_name.underscore.split('_').last # controller, job or rule
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def full_handler(handler_function)
|
|
61
|
+
"#{handler_base}.#{handler_function}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def handler_path
|
|
65
|
+
"#{handler_base}#{lang_ext}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def handler_base
|
|
69
|
+
base = "handlers/#{@type.pluralize}/#{@class_name.underscore}"
|
|
70
|
+
base += "/#{@lang}" if @lang != :ruby
|
|
71
|
+
base += "/#{@meth}"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def poly_src_path
|
|
75
|
+
handler_path.sub("handlers/", "app/")
|
|
76
|
+
end
|
|
77
|
+
end
|
data/lib/jets/naming.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# This class groups the naming in one place.
|
|
2
|
+
# Some naming is for CloudFormation
|
|
3
|
+
# Some are for the Build process
|
|
4
|
+
class Jets::Naming
|
|
5
|
+
# Mainly used by build.rb
|
|
6
|
+
class << self
|
|
7
|
+
def template_path(app_class)
|
|
8
|
+
underscored = app_class.to_s.underscore.gsub('/','-')
|
|
9
|
+
"#{template_path_prefix}-#{underscored}.yml"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def template_path_prefix
|
|
13
|
+
"#{Jets.build_root}/templates/#{Jets.config.project_namespace}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# consider moving these methods into cfn/builder/helpers.rb or that area.
|
|
17
|
+
def parent_template_path
|
|
18
|
+
"#{template_path_prefix}.yml"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# consider moving these methods into cfn/builder/helpers.rb or that area.
|
|
22
|
+
def api_gateway_template_path
|
|
23
|
+
"#{template_path_prefix}-api-gateway.yml"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def api_gateway_deployment_template_path
|
|
27
|
+
"#{template_path_prefix}-api-gateway-deployment.yml"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def parent_stack_name
|
|
31
|
+
File.basename(parent_template_path, ".yml")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def gateway_api_name
|
|
35
|
+
"#{Jets.config.project_namespace}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def code_s3_key
|
|
39
|
+
md5_zipfile = File.basename(md5_code_zipfile)
|
|
40
|
+
"jets/code/#{md5_zipfile}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# build was already ran and that a file that contains the md5 path exists
|
|
44
|
+
# at Jets.build_root/code/current-md5-filename.txt
|
|
45
|
+
#
|
|
46
|
+
# md5_code_zipfile: /tmp/jets/demo/code/code-2e0e18f6.zip
|
|
47
|
+
def md5_code_zipfile
|
|
48
|
+
path = "#{Jets.build_root}/code/current-md5-filename.txt"
|
|
49
|
+
File.exist?(path) ? IO.read(path) : "current-md5-filename-doesnt-exist"
|
|
50
|
+
end
|
|
51
|
+
# The current-md5-filename.txt gets created as a part of CodeBuilder's build
|
|
52
|
+
# process.
|
|
53
|
+
# And is required to be used much later for cfn/ship and base_child_builder
|
|
54
|
+
# They need set an s3_key which requires the md5_zip_dest.
|
|
55
|
+
# It is a pain to pass this all the way up from the
|
|
56
|
+
# CodeBuilder class.
|
|
57
|
+
# We store the "/tmp/jets/demo/code/code-a8a604aa.zip" into a
|
|
58
|
+
# file that can be read from any places where this is needed.
|
|
59
|
+
# Can also just generate a "fake file" for specs
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class Pascalize
|
|
2
|
+
class << self
|
|
3
|
+
# Specialized pascalize that will not pascalize keys under the
|
|
4
|
+
# Variables part of the hash structure.
|
|
5
|
+
# Based on: https://stackoverflow.com/questions/8706930/converting-nested-hash-keys-from-camelcase-to-snake-case-in-ruby
|
|
6
|
+
def pascalize(value, parent_key=nil)
|
|
7
|
+
case value
|
|
8
|
+
when Array
|
|
9
|
+
value.map { |v| pascalize(v) }
|
|
10
|
+
when Hash
|
|
11
|
+
initializer = value.map do |k, v|
|
|
12
|
+
new_key = pascal_key(k, parent_key)
|
|
13
|
+
[new_key, pascalize(v, new_key)]
|
|
14
|
+
end
|
|
15
|
+
Hash[initializer]
|
|
16
|
+
else
|
|
17
|
+
value
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def pascal_key(k, parent_key=nil)
|
|
22
|
+
if parent_key == "Variables" # do not pascalize keys anything under Variables
|
|
23
|
+
k
|
|
24
|
+
else
|
|
25
|
+
k = k.to_s.camelize
|
|
26
|
+
k.slice(0,1).capitalize + k.slice(1..-1) # capitalize first letter only
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Jets
|
|
2
|
+
class PolyFun
|
|
3
|
+
autoload :LambdaExecutor, 'jets/poly_fun/lambda_executor' # main class delegates to other classes
|
|
4
|
+
|
|
5
|
+
autoload :BaseExecutor, 'jets/poly_fun/base_executor'
|
|
6
|
+
autoload :PythonExecutor, 'jets/poly_fun/python_executor'
|
|
7
|
+
autoload :NodeExecutor, 'jets/poly_fun/node_executor'
|
|
8
|
+
|
|
9
|
+
autoload :PythonError, 'jets/poly_fun/python_error'
|
|
10
|
+
autoload :NodeError, 'jets/poly_fun/node_error'
|
|
11
|
+
|
|
12
|
+
extend Memoist
|
|
13
|
+
|
|
14
|
+
def initialize(app_class, app_meth)
|
|
15
|
+
@app_class = app_class # already a Constant, IE: PostController
|
|
16
|
+
@app_meth = app_meth.to_sym
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run(event, context={})
|
|
20
|
+
if task.lang == :ruby
|
|
21
|
+
# controller = PostsController.new(event, content)
|
|
22
|
+
# resp = controller.edit
|
|
23
|
+
@app_class.process(event, context, @app_meth)
|
|
24
|
+
else
|
|
25
|
+
executor = LambdaExecutor.new(task)
|
|
26
|
+
resp = executor.run(event, context)
|
|
27
|
+
if resp["errorMessage"]
|
|
28
|
+
raise_error(resp)
|
|
29
|
+
end
|
|
30
|
+
resp
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def raise_error(resp)
|
|
35
|
+
backtrace = resp["stackTrace"] + caller
|
|
36
|
+
backtrace = backtrace.map { |l| l.sub(/^\s+/,'') }
|
|
37
|
+
# Adjust the paths from the tmp path to the app path to improve user debugging
|
|
38
|
+
# experience. Example:
|
|
39
|
+
# From:
|
|
40
|
+
# File "/tmp/jets/lite/executor/20180917-16777-43a9e48/app/controllers/jets/public_controller/python/show.py", line 32
|
|
41
|
+
# To:
|
|
42
|
+
# File "app/controllers/jets/public_controller/python/show.py", line 32 backtrace =
|
|
43
|
+
backtrace = backtrace.map do |l|
|
|
44
|
+
if l.include?(Jets.build_root) && !l.include?("lambda_executor.")
|
|
45
|
+
l.sub(/\/tmp\/jets.*executor\/\d{8}-+.*?\//, '')
|
|
46
|
+
else
|
|
47
|
+
l
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# IE: Jets::PolyFun::PythonError
|
|
52
|
+
error_class = "Jets::PolyFun::#{task.lang.to_s.classify}Error".constantize
|
|
53
|
+
raise error_class.new(resp["errorMessage"], backtrace)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def task
|
|
57
|
+
@app_class.all_tasks[@app_meth]
|
|
58
|
+
end
|
|
59
|
+
memoize :task
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require 'open3'
|
|
2
|
+
require 'tmpdir'
|
|
3
|
+
|
|
4
|
+
class Jets::PolyFun
|
|
5
|
+
class BaseExecutor
|
|
6
|
+
extend Memoist
|
|
7
|
+
|
|
8
|
+
def initialize(task)
|
|
9
|
+
@task = task
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Handler is in properties:
|
|
13
|
+
# 1. copy lambda function into tmp folder
|
|
14
|
+
# 2. generate Lang wrapper script
|
|
15
|
+
# 3. call wrapper script from ruby. Handle stdout and stderr and result. Pass info back to ruby
|
|
16
|
+
def run(event, context)
|
|
17
|
+
@temp_dir = create_tmpdir
|
|
18
|
+
copy_src_to_temp
|
|
19
|
+
write(code)
|
|
20
|
+
result = run_lambda_executor(event, context)
|
|
21
|
+
cleanup
|
|
22
|
+
result
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def write(code)
|
|
26
|
+
puts "lambda_executor_script #{lambda_executor_script}" if ENV['KEEP_LAMBDA_WRAPPER']
|
|
27
|
+
IO.write(lambda_executor_script, code)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Mimic Dir.mktmpdir randomness, not using Dir.mktmpdir because that generates
|
|
31
|
+
# the folder at the /tmp level only.
|
|
32
|
+
def create_tmpdir
|
|
33
|
+
random = "#{Time.now.strftime("%Y%d%H")}-#{Process.pid}-#{SecureRandom.hex[0..6]}"
|
|
34
|
+
tmpdir = "#{Jets.build_root}/executor/#{random}"
|
|
35
|
+
FileUtils.mkdir_p(tmpdir)
|
|
36
|
+
tmpdir
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def copy_src_to_temp
|
|
40
|
+
app_class = @task.class_name.constantize
|
|
41
|
+
internal = app_class.respond_to?(:internal) && app_class.internal
|
|
42
|
+
src = internal ?
|
|
43
|
+
"#{File.expand_path("../internal", File.dirname(__FILE__))}/#{@task.poly_src_path}" :
|
|
44
|
+
"#{Jets.root}#{@task.poly_src_path}"
|
|
45
|
+
dest = "#{@temp_dir}/#{@task.poly_src_path}"
|
|
46
|
+
|
|
47
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
48
|
+
FileUtils.cp(src, dest)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def lambda_executor_script
|
|
52
|
+
File.dirname("#{@temp_dir}/#{@task.poly_src_path}") + "/lambda_executor" + @task.lang_ext
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# When polymorphic method errors, this method reproduces an error in the lambda format
|
|
56
|
+
# Here's some examples to help example:
|
|
57
|
+
#
|
|
58
|
+
# Example of what the raw python prints out to stderr:
|
|
59
|
+
#
|
|
60
|
+
# Traceback (most recent call last):
|
|
61
|
+
# File "/tmp/jets/lite/executor/20180804-10727-mcs6qk/lambda_executor.py", line 6, in <module>
|
|
62
|
+
# resp = handle(event, context)
|
|
63
|
+
# File "/tmp/jets/lite/executor/20180804-10727-mcs6qk/index.py", line 22, in handle
|
|
64
|
+
# return response({'message': e.message}, 400)
|
|
65
|
+
# File "/tmp/jets/lite/executor/20180804-10727-mcs6qk/index.py", line 5, in response
|
|
66
|
+
# badcode
|
|
67
|
+
# NameError: global name 'badcode' is not defined
|
|
68
|
+
#
|
|
69
|
+
# So last line has the error summary info. Other lines have stack trace after the Traceback indicator.
|
|
70
|
+
#
|
|
71
|
+
# Example of the reproduced lambda error format:
|
|
72
|
+
#
|
|
73
|
+
# {
|
|
74
|
+
# "errorMessage": "'NameError' object has no attribute 'message'",
|
|
75
|
+
# "errorType": "AttributeError",
|
|
76
|
+
# "stackTrace": [
|
|
77
|
+
# [
|
|
78
|
+
# "/var/task/handlers/controllers/posts_controller/python/index.py",
|
|
79
|
+
# 22,
|
|
80
|
+
# "handle",
|
|
81
|
+
# "return response({'message': e.message}, 400)"
|
|
82
|
+
# ]
|
|
83
|
+
# ]
|
|
84
|
+
# }
|
|
85
|
+
#
|
|
86
|
+
def run_lambda_executor(event, context)
|
|
87
|
+
interpreter = @task.lang
|
|
88
|
+
command = %Q|#{interpreter} #{lambda_executor_script} '#{JSON.dump(event)}' '#{JSON.dump(context)}'|
|
|
89
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
90
|
+
# puts "=> #{command}".colorize(:green)
|
|
91
|
+
# puts "stdout #{stdout}"
|
|
92
|
+
# puts "stderr #{stderr}"
|
|
93
|
+
# puts "status #{status}"
|
|
94
|
+
if status.success?
|
|
95
|
+
stdout
|
|
96
|
+
else
|
|
97
|
+
# We'll mimic the way lambda displays an error.
|
|
98
|
+
# $stderr.puts(stderr) # uncomment to debug
|
|
99
|
+
error_lines = stderr.split("\n")
|
|
100
|
+
error_message = error_lines.pop
|
|
101
|
+
error_type = error_message.split(':').first
|
|
102
|
+
error_lines.shift # remove first line that has the Traceback
|
|
103
|
+
stack_trace = error_lines.reverse # python shows stack trace in opposite order from ruby
|
|
104
|
+
JSON.dump(
|
|
105
|
+
"errorMessage" => error_message,
|
|
106
|
+
"errorType" => error_type, # hardcode
|
|
107
|
+
"stackTrace" => stack_trace
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def cleanup
|
|
113
|
+
FileUtils.rm_rf(@temp_dir) unless ENV['KEEP_LAMBDA_WRAPPER']
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def handler
|
|
117
|
+
# Must use FunctionProperties to get the handler because that the class that combines
|
|
118
|
+
# the mutiple sources of how the handler can get set.
|
|
119
|
+
# puts "handler path #{@task.handler_path}"
|
|
120
|
+
#
|
|
121
|
+
# IE: Jets::Cfn::TemplateBuilders::FunctionProperties::PythonBuilder
|
|
122
|
+
builder_class = "Jets::Cfn::TemplateBuilders::FunctionProperties::#{@task.lang.to_s.classify}Builder".constantize
|
|
123
|
+
builder = builder_class.new(@task)
|
|
124
|
+
full_handler = builder.properties["Handler"] # full handler here
|
|
125
|
+
File.extname(full_handler).sub(/^./,'') # the extension of the full handler is the handler
|
|
126
|
+
end
|
|
127
|
+
memoize :handler
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
class Jets::PolyFun
|
|
4
|
+
class LambdaExecutor
|
|
5
|
+
def initialize(task)
|
|
6
|
+
@task = task
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def run(event, context)
|
|
10
|
+
executor_class = "Jets::PolyFun::#{@task.lang.capitalize}Executor".constantize
|
|
11
|
+
executor = executor_class.new(@task)
|
|
12
|
+
text = executor.run(event, context)
|
|
13
|
+
JSON.load(text)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class Jets::PolyFun
|
|
2
|
+
class NodeExecutor < BaseExecutor
|
|
3
|
+
# Code for wrapper script that mimics lambda execution. Wrapper script usage:
|
|
4
|
+
#
|
|
5
|
+
# node WRAPPER_SCRIPT EVENT
|
|
6
|
+
#
|
|
7
|
+
# Example:
|
|
8
|
+
#
|
|
9
|
+
# node /tmp/jets/demo/executor/20180804-12816-imqb9/lambda_executor.js '{}'
|
|
10
|
+
#
|
|
11
|
+
def code
|
|
12
|
+
if async_syntax?
|
|
13
|
+
async_code
|
|
14
|
+
else
|
|
15
|
+
callback_code
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html
|
|
20
|
+
def async_syntax?
|
|
21
|
+
app_path = Jets.root + @task.handler_path.sub('handlers/', 'app/')
|
|
22
|
+
source_code = IO.read(app_path)
|
|
23
|
+
source_code.match(/=\s*async.*\(/)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def async_code
|
|
27
|
+
<<-EOL
|
|
28
|
+
var event = process.argv[2]
|
|
29
|
+
event = JSON.parse(event)
|
|
30
|
+
var context = {}
|
|
31
|
+
|
|
32
|
+
var app = require("./#{@task.meth}.js")
|
|
33
|
+
app.#{handler}(event, context).then(resp => console.log(JSON.stringify(resp)))
|
|
34
|
+
EOL
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def callback_code
|
|
39
|
+
<<-EOL
|
|
40
|
+
function callback(error, response) {
|
|
41
|
+
var text = JSON.stringify(response)
|
|
42
|
+
console.log(text)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
var event = process.argv[2]
|
|
46
|
+
event = JSON.parse(event)
|
|
47
|
+
var context = {}
|
|
48
|
+
|
|
49
|
+
var app = require("./#{@task.meth}.js")
|
|
50
|
+
var resp = app.#{handler}(event, context, callback)
|
|
51
|
+
EOL
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|