jets 1.6.9 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d5b38763f2bc3d91c65b0b75084f98bd8ee7902522fdf6cf70951876f9a4f24
4
- data.tar.gz: d57bfc2a503614d78a8bcfba3418c966a93e72e93f5ee27e59ed5b058878fb1a
3
+ metadata.gz: 6ad0f826d8ec03b2cd129b4c39d1f75daf60138e00f2b3873f4d63d1e626a8c4
4
+ data.tar.gz: c805db282c3e79261599a1b3cd5ab8a38ad4c60f9ea28ab2df001f8d20ac0d33
5
5
  SHA512:
6
- metadata.gz: b383844f584768ec4229921889bc33dc9314f49d873ab9338632930c675c770c5bc0c55ff3116a042a8d10a02d5950cf55797a9fb9d4f635cb5ab8a92b2b2df4
7
- data.tar.gz: ff0a50321768af088978d13a9367285327c568314628c5e5317510e5bb09e89fe0d89f810535ceed44bf531f32cef3a0daf013dca94153f752ef6f35413af49f
6
+ metadata.gz: 26e94165ad32ff3652e026dff7ef0d5ecff841e7ced9c661bf59bd8c6f04080965ca5150112f0121792d1835d31cf5f417093282c36f15adeb154df86154511e
7
+ data.tar.gz: ecf039c2c757df91877f81323bcf94378fe977d795f5103965f03263871190f68fbc9194f5132fd5b7c57f564ff5c6504723fba02010da4d6c89ed19bf82f068
data/CHANGELOG.md CHANGED
@@ -3,6 +3,9 @@
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
+ ## [1.7.0]
7
+ - #188 sqs event support
8
+
6
9
  ## [1.6.9]
7
10
  - #184 improve default cors options request access-control-allow-methods
8
11
 
data/Gemfile.lock CHANGED
@@ -11,7 +11,7 @@ GIT
11
11
  PATH
12
12
  remote: .
13
13
  specs:
14
- jets (1.6.9)
14
+ jets (1.7.0)
15
15
  activerecord (~> 5.2.1)
16
16
  activesupport (~> 5.2.1)
17
17
  aws-sdk-apigateway
data/lib/jets/job/dsl.rb CHANGED
@@ -8,9 +8,12 @@
8
8
  #
9
9
  module Jets::Job::Dsl
10
10
  extend ActiveSupport::Concern
11
+ autoload :EventSourceMapping, "jets/job/dsl/event_source_mapping"
11
12
 
12
13
  included do
13
14
  class << self
15
+ include EventSourceMapping
16
+
14
17
  # Public: Creates CloudWatch Event Rule
15
18
  #
16
19
  # expression - The rate expression.
@@ -0,0 +1,66 @@
1
+ module Jets::Job::Dsl
2
+ module EventSourceMapping
3
+ def declare_queue(props)
4
+ props ||= {} # since options.delete(:queue_properties) can be nil
5
+ r = Jets::Resource::Sqs::Queue.new(props)
6
+ with_resource_options(fresh_properties: true, multiple: true) do
7
+ resource(r.definition) # add associated resources immediately
8
+ end
9
+ end
10
+
11
+ def event_source_mapping(props={})
12
+ r = Jets::Resource::Lambda::EventSourceMapping.new(props)
13
+ with_resource_options(fresh_properties: true, multiple: true) do
14
+ resource(r.definition) # add associated resources immediately
15
+ end
16
+ end
17
+
18
+ def sqs_event(queue_name, options={})
19
+ if queue_name == :generate_queue
20
+ queue_arn = "!GetAtt {namespace}SqsQueue.Arn"
21
+ default_iam_policy = default_sqs_iam_policy('*') # Dont have access to full ARN on initial creation
22
+ declare_queue(options.delete(:queue_properties)) # delete to avoid using them for event_source_mapping
23
+ elsif queue_name.include?('!Ref') # reference shared resource
24
+ queue_arn = queue_name
25
+ default_iam_policy = default_sqs_iam_policy('*') # Dont have access to full ARN on initial creation
26
+ else # short-handle existing queue or full queue arn
27
+ queue_arn = full_queue_arn(queue_name)
28
+ default_iam_policy = default_sqs_iam_policy(queue_arn)
29
+ end
30
+
31
+ # Create iam policy allows access to queue
32
+ # Allow disabling in case use wants to add permission application-wide and not have extra IAM policy
33
+ iam_policy_props = options.delete(:iam_policy) || @iam_policy || default_iam_policy
34
+ iam_policy(iam_policy_props) unless iam_policy_props == :disable
35
+
36
+ props = options # by this time options only has EventSourceMapping properties
37
+ default = {
38
+ event_source_arn: queue_arn
39
+ }
40
+ props = default.merge(props)
41
+
42
+ event_source_mapping(props)
43
+ end
44
+
45
+ # Expands simple queue name to full arn. Example:
46
+ #
47
+ # hello-queue
48
+ # To:
49
+ # arn:aws:sqs:us-west-2:112233445566:hello-queue
50
+ def full_queue_arn(queue_name)
51
+ return queue_name if queue_name.include?("arn:aws:sqs")
52
+
53
+ "arn:aws:sqs:#{Jets.aws.region}:#{Jets.aws.account}:#{queue_name}"
54
+ end
55
+
56
+ def default_sqs_iam_policy(queue_name_arn='*')
57
+ {
58
+ action: ["sqs:ReceiveMessage",
59
+ "sqs:DeleteMessage",
60
+ "sqs:GetQueueAttributes"],
61
+ effect: "Allow",
62
+ resource: queue_name_arn,
63
+ }
64
+ end
65
+ end
66
+ end
@@ -141,13 +141,30 @@ module Jets::Lambda::Dsl
141
141
  @associated_resources || []
142
142
  else
143
143
  @associated_resources ||= []
144
- @associated_resources << Jets::Resource::Associated.new(definitions)
144
+ associated_resource = Jets::Resource::Associated.new(definitions)
145
+ associated_resource.multiple_resources = @multiple_resources
146
+ @associated_resources << associated_resource
145
147
  @associated_resources.flatten!
146
148
  end
147
149
  end
148
150
  # User-friendly short resource method. Users will use this.
149
151
  alias_method :resource, :associated_resources
150
152
 
153
+ # Using this odd way of setting these properties so we can keep the
154
+ # resource(*definitions) signature simple. Using keyword arguments at the end
155
+ # interfere with being able to pass in any keys for the properties hash at the end.
156
+ #
157
+ # TODO: If there's a cleaner way of doing this, let me know.
158
+ def with_resource_options(fresh_properties: false, multiple_resources: false)
159
+ @associated_properties = nil if fresh_properties # dont use any current associated_properties
160
+ @multiple_resources = multiple_resources
161
+
162
+ yield
163
+
164
+ @multiple_resources = false
165
+ @associated_properties = nil if fresh_properties # reset for next definition, since we're defining eagerly
166
+ end
167
+
151
168
  # Properties belonging to the associated resource
152
169
  def associated_properties(options={})
153
170
  @associated_properties ||= {}
@@ -170,6 +187,14 @@ module Jets::Lambda::Dsl
170
187
  end
171
188
  end
172
189
 
190
+ def add_logical_id_counter?
191
+ return false unless @associated_resources
192
+ # Only takes one associated resource with multiple set to true to return false of this check
193
+ return false if @associated_resources.detect { |associated| associated.multiple_resources }
194
+ # Otherwise check if there is more than 1 @associated_resources
195
+ @associated_resources.size > 1
196
+ end
197
+
173
198
  # Loop back through the resources and add a counter to the end of the id
174
199
  # to handle multiple events.
175
200
  # Then replace @associated_resources entirely
@@ -218,7 +243,7 @@ module Jets::Lambda::Dsl
218
243
 
219
244
  # Unsure why but we have to use @associated_resources vs associated_resources
220
245
  # associated_resources is always nil
221
- if @associated_resources && @associated_resources.size > 1
246
+ if add_logical_id_counter?
222
247
  add_logical_id_counter
223
248
  end
224
249
 
@@ -5,8 +5,19 @@ class Jets::Resource
5
5
  extend Memoist
6
6
 
7
7
  attr_reader :definition
8
+ attr_accessor :multiple_resources
8
9
  def initialize(*definition)
9
10
  @definition = definition.flatten
11
+ # Some associated resources require multiple resources for a single Lambda function. For
12
+ # example `sqs_event` can create a `SQS::Queue` and `Lambda::EventSourceMapping`. We set
13
+ # a `multiple` flag so `add_logical_id_counter` can use it to avoid adding counter ids to
14
+ # these type of resources. The `multiple` flag allows us to handle both:
15
+ #
16
+ # 1. Associated resources that contain multiple resources for a single Lambda function
17
+ # 2. A single Lambda function with multiple events. In this case, a counter is added
18
+ #
19
+ # Setting `multiple` to true means the counter id will not be added.
20
+ @multiple_resources = false
10
21
  end
11
22
 
12
23
  def logical_id
@@ -1,4 +1,5 @@
1
1
  module Jets::Resource::Lambda
2
+ autoload :EventSourceMapping, 'jets/resource/lambda/event_source_mapping'
2
3
  autoload :Function, 'jets/resource/lambda/function'
3
4
  autoload :GemLayer, 'jets/resource/lambda/gem_layer'
4
5
  autoload :LayerVersion, 'jets/resource/lambda/layer_version'
@@ -0,0 +1,31 @@
1
+ # Note the Lambda function timeout must be less than or equal to the sqs queue default timeout.
2
+ module Jets::Resource::Lambda
3
+ class EventSourceMapping < Jets::Resource::Base
4
+ def initialize(props)
5
+ @props = props # associated_properties from dsl.rb
6
+ end
7
+
8
+ def definition
9
+ # CloudFormation Docs: https://amzn.to/2WM6165
10
+ properties = {
11
+ # batch_size: 10, # Defaults: Kinesis 100, DynamoDB Streams: 100, SQS: 10
12
+ # enabled: boolean,
13
+ # event_source_arn: string, # required
14
+ function_name: "!Ref {namespace}LambdaFunction",
15
+ # starting_position: string # reqiured for Required for Amazon Kinesis and Amazon DynamoDB Streams sources
16
+ }
17
+ properties.merge!(@props)
18
+
19
+ {
20
+ event_source_mapping_logical_id => {
21
+ type: "AWS::Lambda::EventSourceMapping",
22
+ properties: properties
23
+ }
24
+ }
25
+ end
26
+
27
+ def event_source_mapping_logical_id
28
+ "{namespace}EventSourceMapping"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ # CloudFormation SQS Queue docs: https://amzn.to/2MVWk0j
2
+ module Jets::Resource::Sqs
3
+ class Queue < Jets::Resource::Base
4
+ def initialize(props)
5
+ @props = props # associated_properties from dsl.rb
6
+ end
7
+
8
+ def definition
9
+ {
10
+ queue_logical_id => {
11
+ type: "AWS::SQS::Queue",
12
+ properties: @props,
13
+ }
14
+ }
15
+ end
16
+
17
+ def queue_logical_id
18
+ "{namespace}_sqs_queue"
19
+ end
20
+ end
21
+ end
@@ -4,6 +4,10 @@ module Jets::Stack::Main::Dsl
4
4
  "!Ref #{value.to_s.camelize}"
5
5
  end
6
6
 
7
+ def getatt(value, attribute=:arn)
8
+ "!GetAtt #{value.to_s.camelize}.#{attribute.to_s.camelize}"
9
+ end
10
+
7
11
  def logical_id(value)
8
12
  value.to_s.camelize
9
13
  end
@@ -1,8 +1,10 @@
1
1
  module Jets::Stack::Main::Dsl
2
2
  module Sqs
3
3
  def sqs_queue(id, props={})
4
- resource(id, "AWS::SNS::Topic", props)
5
- output(id)
4
+ # props[:queue_name] ||= id.to_s # comment out to allow CloudFormation to generate name
5
+ resource(id, "AWS::SQS::Queue", props)
6
+ # output(id) # normal !Ref returns the sqs url the ARN is more useful
7
+ output(id, getatt(id, :arn))
6
8
  end
7
9
  end
8
10
  end
data/lib/jets/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Jets
2
- VERSION = "1.6.9"
2
+ VERSION = "1.7.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: 1.6.9
4
+ version: 1.7.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: 2019-02-05 00:00:00.000000000 Z
11
+ date: 2019-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -652,6 +652,7 @@ files:
652
652
  - lib/jets/job.rb
653
653
  - lib/jets/job/base.rb
654
654
  - lib/jets/job/dsl.rb
655
+ - lib/jets/job/dsl/event_source_mapping.rb
655
656
  - lib/jets/klass.rb
656
657
  - lib/jets/lambda.rb
657
658
  - lib/jets/lambda/dsl.rb
@@ -732,6 +733,7 @@ files:
732
733
  - lib/jets/resource/iam/managed_policy.rb
733
734
  - lib/jets/resource/iam/policy_document.rb
734
735
  - lib/jets/resource/lambda.rb
736
+ - lib/jets/resource/lambda/event_source_mapping.rb
735
737
  - lib/jets/resource/lambda/function.rb
736
738
  - lib/jets/resource/lambda/function/environment.rb
737
739
  - lib/jets/resource/lambda/gem_layer.rb
@@ -743,6 +745,7 @@ files:
743
745
  - lib/jets/resource/s3.rb
744
746
  - lib/jets/resource/sns.rb
745
747
  - lib/jets/resource/sqs.rb
748
+ - lib/jets/resource/sqs/queue.rb
746
749
  - lib/jets/resource/standardizer.rb
747
750
  - lib/jets/route.rb
748
751
  - lib/jets/router.rb