jets 0.7.1 → 0.8.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile.lock +1 -1
  4. data/lib/jets.rb +2 -0
  5. data/lib/jets/cfn/ship.rb +2 -0
  6. data/lib/jets/cfn/template_builders/base_child_builder.rb +14 -0
  7. data/lib/jets/cfn/template_builders/controller_builder.rb +4 -74
  8. data/lib/jets/cfn/template_builders/interface.rb +5 -0
  9. data/lib/jets/cfn/template_builders/job_builder.rb +1 -55
  10. data/lib/jets/cfn/template_builders/rule_builder.rb +7 -58
  11. data/lib/jets/cfn/template_mappers.rb +1 -4
  12. data/lib/jets/cfn/template_mappers/child_mapper.rb +1 -1
  13. data/lib/jets/cfn/template_mappers/gateway_resource_mapper.rb +5 -4
  14. data/lib/jets/commands/build.rb +2 -2
  15. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +4 -1
  16. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +2 -2
  17. data/lib/jets/job.rb +0 -1
  18. data/lib/jets/job/dsl.rb +52 -34
  19. data/lib/jets/lambda/dsl.rb +43 -1
  20. data/lib/jets/lambda/task.rb +2 -1
  21. data/lib/jets/pascalize.rb +26 -8
  22. data/lib/jets/resource.rb +7 -0
  23. data/lib/jets/resource/attributes.rb +46 -0
  24. data/lib/jets/resource/creator.rb +17 -0
  25. data/lib/jets/resource/permission.rb +43 -0
  26. data/lib/jets/resource/replacer.rb +40 -0
  27. data/lib/jets/resource/replacer/base.rb +98 -0
  28. data/lib/jets/resource/replacer/config_rule.rb +18 -0
  29. data/lib/jets/resource/route.rb +67 -0
  30. data/lib/jets/resource/route/attributes.rb +8 -0
  31. data/lib/jets/resource/route/cors.rb +60 -0
  32. data/lib/jets/rule.rb +0 -2
  33. data/lib/jets/rule/dsl.rb +71 -31
  34. data/lib/jets/version.rb +1 -1
  35. metadata +12 -8
  36. data/lib/jets/cfn/template_mappers/config_rule_mapper.rb +0 -34
  37. data/lib/jets/cfn/template_mappers/events_rule_mapper.rb +0 -40
  38. data/lib/jets/cfn/template_mappers/gateway_method_mapper.rb +0 -56
  39. data/lib/jets/job/task.rb +0 -17
  40. data/lib/jets/rule/aws_managed_rule.rb +0 -12
  41. data/lib/jets/rule/task.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16cdf110e35fa56fc847cdd8e6a6941a2fba176a407916f089e25d5b82ac1259
4
- data.tar.gz: 485c1e5b430899c6335c7d62709993ed8d837155864ae2cda36ad73db0097857
3
+ metadata.gz: 1428541d12995e263e9e59799ac44ddad7aaa4c1edbec777efe3a9ea346f605c
4
+ data.tar.gz: 1a31efb43f051e6edb9e02fc644b784cabccc73d9a9b52e2d95c83f6dfe7cd9c
5
5
  SHA512:
6
- metadata.gz: 27e0359780451354ecacfe9a65ae4fd0cc3498b855d1cda2d2956699f93dd0c0df7aeda611fce6d77023b7c18b94b99f56a109e667d5c7e24686aac6e061e7ce
7
- data.tar.gz: 898c00749dea09e1962e7a5a178398e98e1035249e6f3cb9b65b93e44fdecba376b2445f54e67d6b8a73294f1282b2f3aa0f59f6771dc336fb59767a6358d2ac
6
+ metadata.gz: aa853515fa883f4c731cb34b52cbe4a24f2885330d4efe0c8db19cd6688c52cf19b26bb35f2eb8e7aac528aaa2fe9e5f380f99d85371113bdabe526c5dbbb521
7
+ data.tar.gz: 66c0ea47767db050eaf5481614cf53d2c63ab5ac44edb2eb9171d759a2d4b91a3e5052a4aa8f619e04eed0f36e5e9c56e681ad34a677e9ba979c4e2fd0d8c6be
data/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.8.0]
7
+ - Introduce core resource, pull request #20
8
+ - Future template generation will lead to core resource. Start the move away from the older cfn template generator logic.
9
+ - Allows for more control and customization of the associated resources with the lambda functions.
10
+ - Allows multiple associated resources to be connected to a lambda function.
11
+ - Support for CloudWatch event patterns, not just scheduled expression
12
+
6
13
  ## [0.7.1]
7
14
  - fix application-wide config.iam_policy ability
8
15
 
data/Gemfile.lock CHANGED
@@ -11,7 +11,7 @@ GIT
11
11
  PATH
12
12
  remote: .
13
13
  specs:
14
- jets (0.7.1)
14
+ jets (0.8.0)
15
15
  actionpack (>= 5.2.1)
16
16
  actionview (>= 5.2.1)
17
17
  activerecord (>= 5.2.1)
data/lib/jets.rb CHANGED
@@ -46,6 +46,8 @@ module Jets
46
46
  autoload :RubyServer, "jets/ruby_server"
47
47
  autoload :IO, "jets/io"
48
48
  autoload :Logger, "jets/logger"
49
+
50
+ autoload :Resource, "jets/resource"
49
51
  end
50
52
 
51
53
  require "jets/core_ext/kernel"
data/lib/jets/cfn/ship.rb CHANGED
@@ -97,6 +97,8 @@ class Jets::Cfn
97
97
  def show_api_endpoint
98
98
  return unless @options[:stack_type] == :full # s3 bucket is available
99
99
  return if Jets::Router.routes.empty?
100
+ resp, status = stack_status
101
+ return if status.include?("ROLLBACK")
100
102
 
101
103
  resp = cfn.describe_stack_resources(stack_name: @parent_stack_name)
102
104
  resources = resp.stack_resources
@@ -54,5 +54,19 @@ class Jets::Cfn::TemplateBuilders
54
54
  properties = map.properties
55
55
  add_resource(logical_id, "AWS::IAM::Role", properties)
56
56
  end
57
+
58
+ def add_associated_resources
59
+ @app_klass.tasks.each do |task|
60
+ task.resources.each do |definition|
61
+ creator = Jets::Resource::Creator.new(definition, task)
62
+ add_associated_resource(creator.resource)
63
+ add_associated_resource(creator.resource.permission.attributes)
64
+ end
65
+ end
66
+ end
67
+
68
+ def add_associated_resource(resource)
69
+ add_resource(resource.logical_id, resource.type, resource.properties)
70
+ end
57
71
  end
58
72
  end
@@ -20,83 +20,13 @@ class Jets::Cfn::TemplateBuilders
20
20
 
21
21
  def add_routes
22
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)
23
+ resource_route = Jets::Resource::Route.new(route)
24
+ add_associated_resource(resource_route.resource)
25
+ add_associated_resource(resource_route.resource.permission.attributes)
26
+ add_associated_resource(resource_route.resource.cors(route).attributes) if Jets.config.cors
27
27
  end
28
28
  end
29
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
30
  # routes scoped to this controller template.
101
31
  def scoped_routes
102
32
  @routes ||= Jets::Router.routes.select do |route|
@@ -4,6 +4,8 @@
4
4
  # * template_path
5
5
  class Jets::Cfn::TemplateBuilders
6
6
  module Interface
7
+ extend Memoist
8
+
7
9
  def build
8
10
  # Do not bother building
9
11
  # or writing the template unless there are functions defined
@@ -37,6 +39,9 @@ class Jets::Cfn::TemplateBuilders
37
39
  if line.include?(': "!') # IE: IamRole: "!Ref IamRole",
38
40
  # IamRole: "!Ref IamRole" => IamRole: !Ref IamRole
39
41
  line.sub(/: "(.*)"/, ': \1')
42
+ elsif line.include?('- "!') # IE: - "!GetAtt Foo.Arn"
43
+ # IamRole: - "!GetAtt Foo.Arn" => - !GetAtt Foo.Arn
44
+ line.sub(/- "(.*)"/, '- \1')
40
45
  else
41
46
  line
42
47
  end
@@ -3,61 +3,7 @@ class Jets::Cfn::TemplateBuilders
3
3
  def compose
4
4
  add_common_parameters
5
5
  add_functions
6
- add_scheduled_tasks
7
- end
8
-
9
- def add_scheduled_tasks
10
- # @app_klass is PostsController, HardJob, Hello, or HelloFunction
11
- @app_klass.tasks.each do |task|
12
- map = Jets::Cfn::TemplateMappers::EventsRuleMapper.new(task)
13
-
14
- # If there's no scheduled expression dont add a scheduled Events::Rule
15
- if task.schedule_expression
16
- add_event_rule(task, map)
17
- add_permission(map)
18
- end
19
- end
20
- end
21
-
22
- def add_event_rule(task, map)
23
- add_resource(map.logical_id, "AWS::Events::Rule",
24
- ScheduleExpression: task.schedule_expression,
25
- State: task.state,
26
- Targets: [
27
- {
28
- Arn: "!GetAtt #{map.lambda_function_logical_id}.Arn",
29
- Id: map.rule_target_id
30
- }
31
- ]
32
- )
33
- # Example:
34
- # add_resource("HardJobDigScheduledEvent", "AWS::Events::Rule",
35
- # ScheduleExpression: "rate(1 minute)",
36
- # State: "ENABLED",
37
- # Targets: [
38
- # {
39
- # Arn: "!GetAtt HardJobDigLambdaFunction.Arn",
40
- # Id: "RuleTargetHardJobDig"
41
- # }
42
- # ]
43
- # )
44
- end
45
-
46
- def add_permission(map)
47
- add_resource(map.permission_logical_id, "AWS::Lambda::Permission",
48
- FunctionName: "!GetAtt #{map.lambda_function_logical_id}.Arn",
49
- Action: "lambda:InvokeFunction",
50
- Principal: "events.amazonaws.com",
51
- SourceArn: "!GetAtt #{map.logical_id}.Arn"
52
- )
53
- # Example:
54
- # add_resource("HardJobDigEventsRulePermission", "AWS::Lambda::Permission",
55
- # FunctionName: "!GetAtt HardJobDigLambdaFunction.Arn",
56
- # Action: "lambda:InvokeFunction",
57
- # Principal: "events.amazonaws.com",
58
- # SourceArn: "!GetAtt HardJobDigScheduledEvent.Arn"
59
- # )
6
+ add_associated_resources
60
7
  end
61
8
  end
62
9
  end
63
-
@@ -3,69 +3,18 @@ class Jets::Cfn::TemplateBuilders
3
3
  def compose
4
4
  add_common_parameters
5
5
  add_functions
6
- add_config_rules
6
+ add_associated_resources
7
+ add_managed_rules
7
8
  end
8
9
 
9
- def add_config_rules
10
- # Handle config_rules associated with lambda functions.
11
- # @app_klass is PostsController, HardRule, Hello, or HelloFunction, or GameRule
12
- @app_klass.tasks.each do |task|
13
- map = Jets::Cfn::TemplateMappers::ConfigRuleMapper.new(task)
14
-
15
- add_config_rule(task, map)
16
- add_permission(map)
17
- end
18
-
19
- # Handle config_rules associated with aws managed rules.
20
- # List of AWS Config Managed Rules: https://amzn.to/2BOt9KN
10
+ # Handle config_rules associated with aws managed rules.
11
+ # List of AWS Config Managed Rules: https://amzn.to/2BOt9KN
12
+ def add_managed_rules
21
13
  @app_klass.managed_rules.each do |rule|
22
- map = Jets::Cfn::TemplateMappers::ConfigRuleMapper.new(rule)
23
- add_aws_managed_rule(rule, map)
14
+ creator = Jets::Resource::Creator.new(rule[:definition], rule[:task])
15
+ add_associated_resource(creator.resource)
24
16
  end
25
17
  end
26
-
27
- def add_aws_managed_rule(rule, map)
28
- # Usually we build the properties with the mappers but in the case for
29
- # a config_rule it makes more sense to grab properties from the task
30
- # using config_rule_properties
31
- add_resource(map.logical_id, "AWS::Config::ConfigRule",
32
- Properties: rule.config_rule_properties
33
- )
34
- end
35
-
36
- def add_config_rule(task, map)
37
- # Usually we build the properties with the mappers but in the case for
38
- # a config_rule it makes more sense to grab properties from the task
39
- # using config_rule_properties
40
- add_resource(map.logical_id, "AWS::Config::ConfigRule",
41
- Properties: task.config_rule_properties,
42
- DependsOn: map.permission_logical_id
43
- )
44
- # Example:
45
- # add_resource("GameRuleProtectConfigRule", "AWS::Config::ConfigRule",
46
- # "ConfigRuleName" : String,
47
- # "Description" : String,
48
- # "InputParameters" : { ParameterName : Value },
49
- # "MaximumExecutionFrequency" : String,
50
- # "Scope" : Scope,
51
- # "Source" : Source
52
- # )
53
- end
54
-
55
- def add_permission(map)
56
- add_resource(map.permission_logical_id, "AWS::Lambda::Permission",
57
- FunctionName: "!GetAtt #{map.lambda_function_logical_id}.Arn",
58
- Action: "lambda:InvokeFunction",
59
- Principal: "config.amazonaws.com"
60
- )
61
- # Example:
62
- # add_resource("GameRuleProtectConfigRulePermission", "AWS::Lambda::Permission",
63
- # FunctionName: "!GetAtt GameRuleProtectLambdaFunction.Arn",
64
- # Action: "lambda:InvokeFunction",
65
- # Principal: "config.amazonaws.com",
66
- # SourceArn: "!GetAtt ScheduledEventHardRuleDig.Arn"
67
- # )
68
- end
69
18
  end
70
19
  end
71
20
 
@@ -6,8 +6,8 @@ class Jets::Cfn
6
6
  # used in the parent_template.rb
7
7
  autoload :ChildMapper, "jets/cfn/template_mappers/child_mapper"
8
8
  autoload :ControllerMapper, "jets/cfn/template_mappers/controller_mapper"
9
- autoload :JobMapper, "jets/cfn/template_mappers/job_mapper"
10
9
  autoload :FunctionMapper, "jets/cfn/template_mappers/function_mapper"
10
+ autoload :JobMapper, "jets/cfn/template_mappers/job_mapper"
11
11
  autoload :RuleMapper, "jets/cfn/template_mappers/rule_mapper"
12
12
 
13
13
  autoload :ApiGatewayMapper, "jets/cfn/template_mappers/api_gateway_mapper"
@@ -17,9 +17,6 @@ class Jets::Cfn
17
17
  autoload :GatewayResourceMapper, "jets/cfn/template_mappers/gateway_resource_mapper"
18
18
  autoload :LambdaFunctionMapper, "jets/cfn/template_mappers/lambda_function_mapper"
19
19
 
20
- autoload :EventsRuleMapper, "jets/cfn/template_mappers/events_rule_mapper"
21
- autoload :ConfigRuleMapper, "jets/cfn/template_mappers/config_rule_mapper"
22
-
23
20
  autoload :IamPolicy, "jets/cfn/template_mappers/iam_policy"
24
21
  end
25
22
  end
@@ -9,7 +9,7 @@ class Jets::Cfn::TemplateMappers
9
9
 
10
10
  # common parameters to all child stacks
11
11
  def parameters
12
- parameters = {
12
+ {
13
13
  # YAML.dump converts it to a string
14
14
  # !GetAtt Base.Outputs.IamRole => "!GetAtt Base.Outputs.IamRole"
15
15
  # But post processing of the template fixes this
@@ -4,18 +4,18 @@ class Jets::Cfn::TemplateMappers
4
4
  @path = path # Examples: "posts/:id/edit" or "posts"
5
5
  end
6
6
 
7
- # Returns: "ApiGatewayResourcePostsController"
7
+ # Returns: "ApiResourcePostsController"
8
8
  def logical_id
9
9
  homepage = @path == ''
10
10
  if homepage
11
11
  "RootResourceId"
12
12
  else
13
- "#{path_logical_id(@path)}ApiGatewayResource"
13
+ "#{path_logical_id(@path)}ApiResource"
14
14
  end
15
15
  end
16
16
 
17
17
  def cors_logical_id
18
- "#{path_logical_id(@path)}CorsApiGatewayResource"
18
+ "#{path_logical_id(@path)}CorsApiResource"
19
19
  end
20
20
 
21
21
  # Modify the path to conform to API Gateway capture expressions
@@ -43,7 +43,7 @@ class Jets::Cfn::TemplateMappers
43
43
  if @path.include?('/') # posts/:id or posts/:id/edit
44
44
  parent_path = @path.split('/')[0..-2].join('/')
45
45
  parent_logical_id = path_logical_id(parent_path)
46
- "!Ref #{parent_logical_id}ApiGatewayResource"
46
+ "!Ref #{parent_logical_id}ApiResource"
47
47
  else
48
48
  "!GetAtt RestApi.RootResourceId"
49
49
  end
@@ -55,6 +55,7 @@ class Jets::Cfn::TemplateMappers
55
55
  end
56
56
 
57
57
  private
58
+ # Similar path_logical_id method in resource/route.rb
58
59
  def path_logical_id(path)
59
60
  path.gsub('/','_').gsub(':','').gsub('*','').camelize
60
61
  end
@@ -147,10 +147,10 @@ module Jets::Commands
147
147
  controllers = File.expand_path("../../internal/app/controllers/jets", __FILE__)
148
148
 
149
149
  welcome = Jets::Router.has_controller?("Jets::WelcomeController")
150
- paths << "#{controllers}/public_controller.rb" if welcome
150
+ paths << "#{controllers}/welcome_controller.rb" if welcome
151
151
 
152
152
  public_catchall = Jets::Router.has_controller?("Jets::PublicController")
153
- paths << "#{controllers}/welcome_controller.rb" if public_catchall
153
+ paths << "#{controllers}/public_controller.rb" if public_catchall
154
154
 
155
155
  jobs = File.expand_path("../../internal/app/jobs/jets", __FILE__)
156
156
  paths << "#{jobs}/preheat_job.rb"
@@ -6,10 +6,13 @@ Jets.application.configure do
6
6
  # config.env_extra = 2 # can also set this with JETS_ENV_EXTRA
7
7
  # config.extra_autoload_paths = []
8
8
 
9
+ config.cors = true # for '*''
10
+ # config.cors = '*.mydomain.com' # for specific domain
11
+
9
12
  config.function.timeout = 10
10
13
  # config.function.role = "arn:aws:iam::#{Jets.aws.account}:role/service-role/pre-created"
11
14
  # config.function.memory_size= 1536
12
- # config.function.cors = true
15
+
13
16
  config.function.environment = {
14
17
  global_app_key1: "global_app_value1",
15
18
  global_app_key2: "global_app_value2",
@@ -23,7 +23,7 @@ class Jets::PreheatJob < ApplicationJob
23
23
  )
24
24
 
25
25
  unless Jets::Commands::Build.poly_only?
26
- torching ? rate(PREWARM_RATE) : disable(true)
26
+ rate(PREWARM_RATE) if torching
27
27
  def torch
28
28
  threads = []
29
29
  CONCURRENCY.times do
@@ -42,7 +42,7 @@ class Jets::PreheatJob < ApplicationJob
42
42
  "Finished prewarming your application with a concurrency of #{CONCURRENCY}."
43
43
  end
44
44
 
45
- warming ? rate(PREWARM_RATE) : disable(true)
45
+ rate(PREWARM_RATE) if warming
46
46
  def warm
47
47
  options = call_options(event[:quiet])
48
48
  Jets::Preheat.warm_all(options)