cfn-model 0.4.14 → 0.4.15

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: 6e6d251d26bd76ce4b94e2419cbfd2b3966f00621e0d58a179306658c774236e
4
- data.tar.gz: 0d52bd32ef330e7767bcd8cacc7a605233bb63b30ebc7506ec7638488bb0c05a
3
+ metadata.gz: 4ea0ce4fe023541429f2281bf73a25427e4f7f8e38699d813538c94fd9eb7f99
4
+ data.tar.gz: ccc58faba8de9f7a2888aa77193416866cfd0cecd1e1e9facb4a84aa221ae42a
5
5
  SHA512:
6
- metadata.gz: 34eaebd11a7fe8c98472cd2d50f2e51b81c96730ec6057a0fe71fc14f1bba2408a01983349fbb8c91a92bbf93766b1ed655253313e2787c9c4df0bb397cb8b8e
7
- data.tar.gz: 0be2f0d6652bec14496af02c71f07c8974cb4ec115c30454404b7a89efe0cbb76b743472305a577aab77354502ab6ad47b19ee231f60a6d87114bb99c0b69754
6
+ metadata.gz: 6edea6eae9a57f283b7915af1d3d74632990c210a95e403a9a4551eb30fd05be1613a6d8cdb83bcbb683de706150b86776d22c14cbe455b43770e38c79a250c7
7
+ data.tar.gz: 10dad014790492293112026e502741e81fb575cbd19a9f4735757ad6b9077532c3a8bef0eafbc55af32aa585cd646f7f6ef3f5fac3de83997ffe1e6e9623e574
@@ -60,10 +60,27 @@ class CfnModel
60
60
  end
61
61
  end
62
62
 
63
+ def resource_by_id(resource_id)
64
+ @resources.values.find { |resource| resource.logical_resource_id == resource_id }
65
+ end
66
+
63
67
  def resources_by_type(resource_type)
64
68
  @resources.values.select { |resource| resource.resource_type == resource_type }
65
69
  end
66
70
 
71
+ def resource_by_ref(reference, attr = nil)
72
+ # If reference is a String, look for a matching object as is (best effort)
73
+ # Although, the caller could just use resource_by_id on this value, since it
74
+ # would be the logical_resource_id.
75
+ logical_resource_id = reference if reference.is_a? String
76
+
77
+ # Otherwise, obtain logical_resource_id from References class
78
+ logical_resource_id ||= References.resolve_resource_id reference, attr
79
+
80
+ # Search resources for a matching ID
81
+ resource_by_id logical_resource_id
82
+ end
83
+
67
84
  def find_security_group_by_group_id(security_group_reference)
68
85
  security_group_id = References.resolve_security_group_id(security_group_reference)
69
86
  if security_group_id.nil?
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'model_element'
4
+
5
+ # Explicitly creating this element in order
6
+ # to compute the role ID if not a string
7
+ class AWS::Lambda::Function < ModelElement
8
+ attr_accessor :role_object
9
+
10
+ def initialize(cfn_model)
11
+ super
12
+ @role_object = nil
13
+ @resource_type = 'AWS::Lambda::Function'
14
+ end
15
+ end
@@ -7,6 +7,10 @@ module AWS
7
7
 
8
8
  end
9
9
 
10
+ module CloudFront
11
+
12
+ end
13
+
10
14
  module EC2
11
15
 
12
16
  end
@@ -27,23 +31,19 @@ module AWS
27
31
 
28
32
  end
29
33
 
30
- module S3
31
-
32
- end
33
-
34
- module SNS
34
+ module Lambda
35
35
 
36
36
  end
37
37
 
38
- module SQS
38
+ module S3
39
39
 
40
40
  end
41
41
 
42
- module Lambda
42
+ module SNS
43
43
 
44
44
  end
45
45
 
46
- module CloudFront
46
+ module SQS
47
47
 
48
48
  end
49
49
  end
@@ -29,33 +29,35 @@ module References
29
29
  end
30
30
  end
31
31
 
32
+ def self.resolve_resource_id(reference, attr = nil)
33
+ return nil if reference.is_a? String
34
+
35
+ # an imported value can only yield a literal to an external resource vs. referencing something local
36
+ if !reference['Ref'].nil?
37
+ reference['Ref']
38
+ elsif !reference['Fn::GetAtt'].nil?
39
+ logical_resource_id_from_get_att reference['Fn::GetAtt'], attr
40
+ else
41
+ # anything else will be string manipulation functions
42
+ # which again leads us back to a string which must be an external resource known out of band
43
+ # so don't/can't link it up
44
+ return nil
45
+ end
46
+ end
47
+
32
48
  def self.is_security_group_id_external(group_id)
33
49
  resolve_security_group_id(group_id).nil?
34
50
  end
35
51
 
36
- ##
37
- # Return nil if
38
52
  def self.resolve_security_group_id(group_id)
39
- return nil if group_id.is_a? String
40
-
41
- # an imported value can only yield a literal to an external sg vs. referencing something local
42
- if !group_id['Ref'].nil?
43
- group_id['Ref']
44
- elsif !group_id['Fn::GetAtt'].nil?
45
- logical_resource_id_from_get_att group_id['Fn::GetAtt']
46
- else # !group_id['Fn::ImportValue'].nil?
47
- # anything else will be string manipulation functions
48
- # which again leads us back to a string which must be an external security group known out of band
49
- # so don't/can't link it up to a security group
50
- return nil
51
- end
53
+ resolve_resource_id group_id, 'GroupId'
52
54
  end
53
55
 
54
56
  private
55
57
 
56
- def self.logical_resource_id_from_get_att(attribute_spec)
58
+ def self.logical_resource_id_from_get_att(attribute_spec, attr_to_retrieve=nil)
57
59
  if attribute_spec.is_a? Array
58
- if attribute_spec[1] == 'GroupId'
60
+ if !attr_to_retrieve || attribute_spec[1] == attr_to_retrieve
59
61
  return attribute_spec.first
60
62
  else
61
63
  # this could be a reference to a nested stack output so treat it as external
@@ -63,7 +65,7 @@ module References
63
65
  return nil
64
66
  end
65
67
  elsif attribute_spec.is_a? String
66
- if attribute_spec.split('.')[1] == 'GroupId'
68
+ if !attr_to_retrieve || attribute_spec.split('.')[1] == attr_to_retrieve
67
69
  return attribute_spec.split('.').first
68
70
  else
69
71
  # this could be a reference to a nested stack output so treat it as external
@@ -72,4 +74,4 @@ module References
72
74
  end
73
75
  end
74
76
  end
75
- end
77
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'cfn-model/util/wildcard_patterns'
3
4
  require_relative 'principal'
4
5
 
5
6
  class Statement
@@ -27,6 +28,25 @@ class Statement
27
28
  @resources.select { |resource| resource.to_s == '*' }
28
29
  end
29
30
 
31
+ # allows_action?
32
+ # Checks if policy document allows the given action
33
+ #
34
+ # arg action (str): Action string to check
35
+ # arg wildcard (bool): Whether to apply 'wildcard_patterns' to action
36
+ #
37
+ # return: boolean
38
+ def allows_action?(action, wildcard=true)
39
+ if wildcard
40
+ patterns = wildcard_patterns(action.split(':')[1]).map! { |x| action.split(':')[0] + ':' + x } + ['*']
41
+ else
42
+ patterns = [action]
43
+ end
44
+
45
+ matching_actions = @actions.select { |statement_action| patterns.include? statement_action }
46
+
47
+ !matching_actions.empty? && @effect == 'Allow'
48
+ end
49
+
30
50
  def ==(another_statement)
31
51
  @effect == another_statement.effect &&
32
52
  @actions == another_statement.actions &&
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Compute the role_id for parsed Lambda function
4
+ class LambdaFunctionParser
5
+ def parse(cfn_model:, resource:)
6
+ lambda_function = resource
7
+
8
+ lambda_function.role_object = cfn_model.resource_by_ref(lambda_function.role, 'Arn')
9
+
10
+ lambda_function
11
+ end
12
+ end
@@ -18,6 +18,7 @@ class ParserRegistry
18
18
  'AWS::IAM::Policy' => WithPolicyDocumentParser,
19
19
  'AWS::IAM::ManagedPolicy' => WithPolicyDocumentParser,
20
20
  'AWS::KMS::Key' => KmsKeyParser,
21
+ 'AWS::Lambda::Function' => LambdaFunctionParser,
21
22
  'AWS::S3::BucketPolicy' => WithPolicyDocumentParser,
22
23
  'AWS::SNS::TopicPolicy' => WithPolicyDocumentParser,
23
24
  'AWS::SQS::QueuePolicy' => WithPolicyDocumentParser
@@ -0,0 +1,27 @@
1
+ ---
2
+ type: map
3
+ mapping:
4
+ Type:
5
+ type: str
6
+ required: yes
7
+ pattern: /AWS::Lambda::Function/
8
+ Properties:
9
+ type: map
10
+ required: yes
11
+ mapping:
12
+ Code:
13
+ type: any
14
+ required: yes
15
+ Handler:
16
+ type: any
17
+ required: yes
18
+ Role:
19
+ type: any
20
+ required: yes
21
+ Runtime:
22
+ type: any
23
+ required: yes
24
+ =:
25
+ type: any
26
+ =:
27
+ type: any
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create array of wildcard patterns for a given input string
4
+
5
+ def wildcard_patterns(input, pattern_types: %w[front back both])
6
+ input_string = input.to_s
7
+ results = [input_string]
8
+ pattern_types.each do |pattern_type|
9
+ case pattern_type
10
+ when 'front'
11
+ results += wildcard_front(input_string)
12
+ when 'back'
13
+ results += wildcard_back(input_string)
14
+ when 'both'
15
+ results += wildcard_front_back(input_string)
16
+ else
17
+ raise "no pattern of type: #{pattern_type}. Use one or more of: front, back, both"
18
+ end
19
+ end
20
+ results + ['*']
21
+ end
22
+
23
+ private
24
+
25
+ def wildcard_back(input_string, results = [], prepend = '')
26
+ return results if input_string.empty?
27
+
28
+ results << "#{prepend}#{input_string}*"
29
+ wildcard_back(input_string.chop, results, prepend)
30
+ end
31
+
32
+ def wildcard_front(input_string, results = [])
33
+ return results if input_string.empty?
34
+
35
+ results << "*#{input_string}"
36
+ wildcard_front(input_string[1..-1], results)
37
+ end
38
+
39
+ def wildcard_front_back(input_string, results = [])
40
+ return results if input_string.empty?
41
+
42
+ results += wildcard_back(input_string, [], '*')
43
+ wildcard_front_back(input_string[1..-1], results)
44
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfn-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.14
4
+ version: 0.4.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Kascic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-14 00:00:00.000000000 Z
11
+ date: 2020-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -71,6 +71,7 @@ files:
71
71
  - lib/cfn-model/model/iam_role.rb
72
72
  - lib/cfn-model/model/iam_user.rb
73
73
  - lib/cfn-model/model/kms_key.rb
74
+ - lib/cfn-model/model/lambda_function.rb
74
75
  - lib/cfn-model/model/lambda_principal.rb
75
76
  - lib/cfn-model/model/load_balancer.rb
76
77
  - lib/cfn-model/model/model_element.rb
@@ -94,6 +95,7 @@ files:
94
95
  - lib/cfn-model/parser/iam_role_parser.rb
95
96
  - lib/cfn-model/parser/iam_user_parser.rb
96
97
  - lib/cfn-model/parser/kms_key_parser.rb
98
+ - lib/cfn-model/parser/lambda_function_parser.rb
97
99
  - lib/cfn-model/parser/load_balancer_parser.rb
98
100
  - lib/cfn-model/parser/load_balancer_v2_parser.rb
99
101
  - lib/cfn-model/parser/parameter_substitution.rb
@@ -121,12 +123,14 @@ files:
121
123
  - lib/cfn-model/schema/AWS_IAM_User.yml
122
124
  - lib/cfn-model/schema/AWS_IAM_UserToGroupAddition.yml
123
125
  - lib/cfn-model/schema/AWS_KMS_Key.yml
126
+ - lib/cfn-model/schema/AWS_Lambda_Function.yml
124
127
  - lib/cfn-model/schema/AWS_Lambda_Permission.yml
125
128
  - lib/cfn-model/schema/AWS_S3_BucketPolicy.yml
126
129
  - lib/cfn-model/schema/AWS_SNS_TopicPolicy.yml
127
130
  - lib/cfn-model/schema/AWS_SQS_QueuePolicy.yml
128
131
  - lib/cfn-model/schema/schema.yml.erb
129
132
  - lib/cfn-model/transforms/serverless.rb
133
+ - lib/cfn-model/util/wildcard_patterns.rb
130
134
  - lib/cfn-model/validator/cloudformation_validator.rb
131
135
  - lib/cfn-model/validator/reference_validator.rb
132
136
  - lib/cfn-model/validator/resource_type_validator.rb