jets 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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)