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
@@ -0,0 +1,18 @@
1
+ # Overrides
2
+ # replace_core_values
3
+ module Jets::Resource::Replacer
4
+ class ConfigRule < Base
5
+ def core_replacements
6
+ {
7
+ config_rule_name: config_rule_name
8
+ }
9
+ end
10
+
11
+ # Conventional config rule name
12
+ # Similar logic in Rule::Dsl.managed_rule
13
+ def config_rule_name
14
+ name_without_rule = @app_class.underscore.gsub(/_rule$/,'')
15
+ "#{name_without_rule}_#{@task.meth}".dasherize
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,67 @@
1
+ # Converts a Jets::Route to a CloudFormation resource
2
+ module Jets::Resource
3
+ class Route
4
+ autoload :Attributes, 'jets/resource/route/attributes'
5
+ autoload :Cors, 'jets/resource/route/cors'
6
+
7
+ extend Memoist
8
+
9
+ # route - Jets::Route
10
+ def initialize(route)
11
+ @route = route
12
+ end
13
+
14
+ def attributes
15
+ attributes = {
16
+ "#{method_logical_id}ApiMethod" => {
17
+ type: "AWS::ApiGateway::Method",
18
+ properties: {
19
+ resource_id: "!Ref #{resource_id}",
20
+ rest_api_id: "!Ref RestApi",
21
+ http_method: @route.method,
22
+ request_parameters: {},
23
+ authorization_type: "NONE",
24
+ integration: {
25
+ integration_http_method: "POST",
26
+ type: "AWS_PROXY",
27
+ uri: "!Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${{namespace}LambdaFunction.Arn}/invocations"
28
+ },
29
+ method_responses: []
30
+ }
31
+ }
32
+ }
33
+
34
+ definitions = attributes # to emphasize that its the same thing
35
+ task = Jets::Lambda::Task.new(@route.controller_name, @route.action_name,
36
+ resources: definitions)
37
+ Attributes.new(attributes, task)
38
+ end
39
+ alias_method :resource, :attributes
40
+ memoize :attributes
41
+
42
+ private
43
+ # Similar path_logical_id method in template_mappers/gateway_resource_mapper.rb
44
+ # Example: PostsGet
45
+ def method_logical_id
46
+ path = camelized_path
47
+ path + "#{@route.method.to_s.downcase.camelize}"
48
+ end
49
+
50
+ def resource_id
51
+ @route.path == '' ?
52
+ "RootResourceId" :
53
+ "#{resource_logical_id}ApiResource"
54
+ end
55
+
56
+ # Example: Posts
57
+ def resource_logical_id
58
+ camelized_path
59
+ end
60
+
61
+ def camelized_path
62
+ path = @route.path
63
+ path = "homepage" if path == ''
64
+ path.gsub('/','_').gsub(':','').gsub('*','').camelize
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,8 @@
1
+ class Jets::Resource::Route
2
+ class Attributes < Jets::Resource::Attributes
3
+ def cors(route)
4
+ Cors.new(route)
5
+ end
6
+ memoize :cors
7
+ end
8
+ end
@@ -0,0 +1,60 @@
1
+ class Jets::Resource::Route
2
+ class Cors < Jets::Resource::Route
3
+ def attributes
4
+ attributes = {
5
+ "#{resource_logical_id}CorsApiMethod" => {
6
+ type: "AWS::ApiGateway::Method",
7
+
8
+ properties: {
9
+ resource_id: "!Ref #{resource_id}",
10
+ rest_api_id: "!Ref RestApi",
11
+ authorization_type: "NONE",
12
+ http_method: "OPTIONS",
13
+ method_responses: [{
14
+ status_code: '200',
15
+ response_parameters: {
16
+ "method.response.header.Access-Control-AllowOrigin": true,
17
+ "method.response.header.Access-Control-AllowHeaders": true,
18
+ "method.response.header.Access-Control-AllowMethods": true,
19
+ "method.response.header.Access-Control-AllowCredentials": true,
20
+ },
21
+ response_models: {},
22
+ }],
23
+ request_parameters: {},
24
+ integration: {
25
+ type: "MOCK",
26
+ request_templates: {
27
+ "application/json": "{statusCode:200}",
28
+ },
29
+ integration_responses: [{
30
+ status_code: '200',
31
+ response_parameters: {
32
+ "method.response.header.Access-Control-AllowOrigin": "'#{allow_origin}'",
33
+ "method.response.header.Access-Control-AllowHeaders": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'",
34
+ "method.response.header.Access-Control-AllowMethods": "'OPTIONS,GET'",
35
+ "method.response.header.Access-Control-AllowCredentials": "'false'",
36
+ },
37
+ response_templates: {
38
+ "application/json": '',
39
+ },
40
+ }] # closes integration_responses
41
+ } # closes integration
42
+ } # closes properties
43
+ } # closes logical id
44
+ } # closes attributes
45
+
46
+ definitions = attributes # to emphasize that its the same thing
47
+ task = Jets::Lambda::Task.new(@route.controller_name, @route.action_name,
48
+ resources: definitions)
49
+ Attributes.new(attributes, task)
50
+ end
51
+
52
+ def allow_origin
53
+ if Jets.config.cors == true
54
+ '*'
55
+ elsif Jets.config.cors
56
+ Jets.config.cors
57
+ end
58
+ end
59
+ end
60
+ end
data/lib/jets/rule.rb CHANGED
@@ -1,6 +1,4 @@
1
1
  class Jets::Rule
2
- autoload :AwsManagedRule, "jets/rule/aws_managed_rule"
3
2
  autoload :Base, "jets/rule/base"
4
3
  autoload :Dsl, "jets/rule/dsl"
5
- autoload :Task, "jets/rule/task"
6
4
  end
data/lib/jets/rule/dsl.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  # Jets::Rule::Base < Jets::Lambda::Functions
2
2
  # Both Jets::Rule::Base and Jets::Lambda::Functions have Dsl modules included.
3
3
  # So the Jets::Rule::Dsl overrides some of the Jets::Lambda::Functions behavior.
4
+ #
5
+ # Implements:
6
+ # default_associated_resource: must return @resources
4
7
  module Jets::Rule::Dsl
5
8
  extend ActiveSupport::Concern
6
9
 
@@ -14,59 +17,103 @@ module Jets::Rule::Dsl
14
17
  def scope(value)
15
18
  scope = case value
16
19
  when String
17
- {"ComplianceResourceTypes" => [value]}
20
+ {compliance_resource_types: [value]}
18
21
  when Array
19
- {"ComplianceResourceTypes" => value}
22
+ {compliance_resource_types: value}
20
23
  else # default to hash
21
24
  value
22
25
  end
23
-
24
- config_rule(scope: scope)
26
+ update_properties(scope: scope)
25
27
  end
26
28
 
27
29
  def config_rule_name(value)
28
- config_rule(config_rule_name: value)
30
+ update_properties(config_rule_name: value)
29
31
  end
30
32
 
31
33
  def description(value)
32
- config_rule(description: value)
34
+ update_properties(description: value)
33
35
  end
34
36
  alias_method :desc, :description
35
37
 
36
38
  def input_parameters(value)
37
- config_rule(input_parameters: value)
39
+ update_properties(input_parameters: value)
38
40
  end
39
41
 
40
42
  def maximum_execution_frequency(value)
41
- config_rule(maximum_execution_frequency: value)
43
+ update_properties(maximum_execution_frequency: value)
42
44
  end
43
45
 
44
46
  def source(value)
45
- config_rule(source: value)
47
+ update_properties(source: value)
46
48
  end
47
49
 
48
- def config_rule(options={})
49
- @config_rule ||= {}
50
- @config_rule.deep_merge!(options)
50
+ def default_associated_resource
51
+ config_rule
51
52
  end
52
53
 
53
- # Override register_task.
54
- # Creates instances of Rule::Task instead of a Lambda::Task
55
- # Also adds the config_rule option that is specific to Rule classes
56
- def register_task(meth, lang=:ruby)
57
- all_tasks[meth] = Jets::Rule::Task.new(self.name, meth,
58
- properties: @properties, config_rule: @config_rule, lang: lang)
59
- clear_properties
60
- true
54
+ def config_rule(props={})
55
+ default_props = {
56
+ config_rule_name: "{config_rule_name}",
57
+ source: {
58
+ owner: "CUSTOM_LAMBDA",
59
+ source_identifier: "{namespace}LambdaFunction.Arn",
60
+ source_details: [
61
+ {
62
+ event_source: "aws.config",
63
+ message_type: "ConfigurationItemChangeNotification"
64
+ },
65
+ {
66
+ event_source: "aws.config",
67
+ message_type: "OversizedConfigurationItemChangeNotification"
68
+ }
69
+ ]
70
+ }
71
+ }
72
+ properties = default_props.deep_merge(props)
73
+
74
+ resource("{namespace}ConfigRule" => {
75
+ type: "AWS::Config::ConfigRule",
76
+ properties: properties
77
+ })
78
+ @resources # must return @resoures for update_properties
61
79
  end
62
80
 
63
- def clear_properties
64
- super
65
- @config_rule = nil
81
+ def managed_rule(name, props={})
82
+ name = name.to_s
83
+
84
+ # Similar logic in Replacer::ConfigRule#config_rule_name
85
+ name_without_rule = self.name.underscore.gsub(/_rule$/,'')
86
+ config_rule_name = "#{name_without_rule}_#{name}".dasherize
87
+ source_identifier = name.upcase
88
+
89
+ default_props = {
90
+ config_rule_name: config_rule_name,
91
+ source: {
92
+ owner: "AWS",
93
+ source_identifier: source_identifier,
94
+ }
95
+ }
96
+ properties = default_props.deep_merge(props)
97
+ # The key is to use update_properties to update the current resource and maintain
98
+ # the added properties from the convenience methods like scope and description.
99
+ # At the same time, we do not register the task to all_tasks to avoid creating a Lambda function.
100
+ # Instead we store it in all_managed_rules.
101
+ update_properties(properties)
102
+ definition = @resources.first
103
+
104
+ register_managed_rule(name, definition)
66
105
  end
67
106
 
68
- ## aws managed rules work different enough to merit their own storage
107
+ # Creates a task but registers it to all_managed_rules instead of all_tasks
108
+ # because we do not want Lambda functions to be created.
109
+ def register_managed_rule(name, definition)
110
+ # A task object is needed to build {namespace} for later replacing.
111
+ task = Jets::Lambda::Task.new(self.name, name, resources: @resources)
112
+ all_managed_rules[name] = { definition: definition, task: task }
113
+ clear_properties
114
+ end
69
115
 
116
+ # AWS managed rules are not actual Lambda functions and require their own storage.
70
117
  def all_managed_rules
71
118
  @all_managed_rules ||= ActiveSupport::OrderedHash.new
72
119
  end
@@ -75,13 +122,6 @@ module Jets::Rule::Dsl
75
122
  all_managed_rules.values
76
123
  end
77
124
 
78
- def managed_rule(meth)
79
- all_managed_rules[meth] = Jets::Rule::AwsManagedRule.new(self.name, meth,
80
- properties: @properties, config_rule: @config_rule)
81
- clear_properties
82
- true
83
- end
84
-
85
125
  # Override Lambda::Dsl.build? to account of possible managed_rules
86
126
  def build?
87
127
  !tasks.empty? || !managed_rules.empty?
data/lib/jets/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Jets
2
- VERSION = "0.7.1"
2
+ VERSION = "0.8.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-30 00:00:00.000000000 Z
11
+ date: 2018-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -458,11 +458,8 @@ files:
458
458
  - lib/jets/cfn/template_mappers/api_gateway_deployment_mapper.rb
459
459
  - lib/jets/cfn/template_mappers/api_gateway_mapper.rb
460
460
  - lib/jets/cfn/template_mappers/child_mapper.rb
461
- - lib/jets/cfn/template_mappers/config_rule_mapper.rb
462
461
  - lib/jets/cfn/template_mappers/controller_mapper.rb
463
- - lib/jets/cfn/template_mappers/events_rule_mapper.rb
464
462
  - lib/jets/cfn/template_mappers/function_mapper.rb
465
- - lib/jets/cfn/template_mappers/gateway_method_mapper.rb
466
463
  - lib/jets/cfn/template_mappers/gateway_resource_mapper.rb
467
464
  - lib/jets/cfn/template_mappers/iam_policy.rb
468
465
  - lib/jets/cfn/template_mappers/iam_policy/application_policy_mapper.rb
@@ -602,7 +599,6 @@ files:
602
599
  - lib/jets/job.rb
603
600
  - lib/jets/job/base.rb
604
601
  - lib/jets/job/dsl.rb
605
- - lib/jets/job/task.rb
606
602
  - lib/jets/klass.rb
607
603
  - lib/jets/lambda.rb
608
604
  - lib/jets/lambda/dsl.rb
@@ -629,14 +625,22 @@ files:
629
625
  - lib/jets/rails_overrides/common_methods.rb
630
626
  - lib/jets/rails_overrides/rendering_helper.rb
631
627
  - lib/jets/rails_overrides/url_helper.rb
628
+ - lib/jets/resource.rb
629
+ - lib/jets/resource/attributes.rb
630
+ - lib/jets/resource/creator.rb
631
+ - lib/jets/resource/permission.rb
632
+ - lib/jets/resource/replacer.rb
633
+ - lib/jets/resource/replacer/base.rb
634
+ - lib/jets/resource/replacer/config_rule.rb
635
+ - lib/jets/resource/route.rb
636
+ - lib/jets/resource/route/attributes.rb
637
+ - lib/jets/resource/route/cors.rb
632
638
  - lib/jets/route.rb
633
639
  - lib/jets/router.rb
634
640
  - lib/jets/ruby_server.rb
635
641
  - lib/jets/rule.rb
636
- - lib/jets/rule/aws_managed_rule.rb
637
642
  - lib/jets/rule/base.rb
638
643
  - lib/jets/rule/dsl.rb
639
- - lib/jets/rule/task.rb
640
644
  - lib/jets/server.rb
641
645
  - lib/jets/server/api_gateway.rb
642
646
  - lib/jets/server/lambda_aws_proxy.rb
@@ -1,34 +0,0 @@
1
- # Used in cfn/template_builders/rule_builder.rb to build AWS::Config::ConfigRule
2
- class Jets::Cfn::TemplateMappers
3
- class ConfigRuleMapper
4
- # task is a Jets::Job::Task
5
- def initialize(task)
6
- @task = task
7
- end
8
-
9
- # Example: "ConfigRuleGameRuleProtect"
10
- def logical_id
11
- "#{full_task_name}ConfigRule"
12
- end
13
-
14
- # Example: "GameRuleProtectLambdaFunction"
15
- def lambda_function_logical_id
16
- "#{full_task_name}LambdaFunction"
17
- end
18
-
19
- # Example: GameRuleProtectConfigRulePermission
20
- def permission_logical_id
21
- "#{full_task_name}ConfigRulePermission"
22
- end
23
-
24
- private
25
- # Full camelized task name including the class
26
- # Example: GameRuleProtect
27
- def full_task_name
28
- class_name = @task.class_name
29
- task_name = @task.meth.to_s.camelize
30
- "#{class_name}#{task_name}"
31
- end
32
- end
33
- end
34
-
@@ -1,40 +0,0 @@
1
- class Jets::Cfn::TemplateMappers
2
- class EventsRuleMapper
3
- # task is a Jets::Job::Task
4
- def initialize(task)
5
- @task = task
6
- end
7
-
8
- # Example: "HardJobDigScheduledEvent"
9
- def logical_id
10
- "#{full_task_name}ScheduledEvent"
11
- end
12
-
13
- # Example: "HardJobDigLambdaFunction"
14
- def lambda_function_logical_id
15
- "#{full_task_name}LambdaFunction"
16
- end
17
-
18
- # Target Id: A unique, user-defined identifier for the target. Acceptable values include alphanumeric characters, periods (.), hyphens (-), and underscores (_).
19
- #
20
- # Example: RuleTargetHardJobDig
21
- def rule_target_id
22
- "#{full_task_name}RuleTarget"
23
- end
24
-
25
- # Example: HardJobDigEventsRulePermission
26
- def permission_logical_id
27
- "#{full_task_name}EventsRulePermission"
28
- end
29
-
30
- private
31
- # Full camelized task name including the class
32
- # Example: HardJobDig
33
- def full_task_name
34
- class_name = @task.class_name.gsub('::','')
35
- task_name = @task.meth.to_s.camelize
36
- "#{class_name}#{task_name}"
37
- end
38
- end
39
- end
40
-