cfn-model 0.4.14 → 0.4.15

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.
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