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 +4 -4
- data/lib/cfn-model/model/cfn_model.rb +17 -0
- data/lib/cfn-model/model/lambda_function.rb +15 -0
- data/lib/cfn-model/model/model_element.rb +8 -8
- data/lib/cfn-model/model/references.rb +21 -19
- data/lib/cfn-model/model/statement.rb +20 -0
- data/lib/cfn-model/parser/lambda_function_parser.rb +12 -0
- data/lib/cfn-model/parser/parser_registry.rb +1 -0
- data/lib/cfn-model/schema/AWS_Lambda_Function.yml +27 -0
- data/lib/cfn-model/util/wildcard_patterns.rb +44 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ea0ce4fe023541429f2281bf73a25427e4f7f8e38699d813538c94fd9eb7f99
|
4
|
+
data.tar.gz: ccc58faba8de9f7a2888aa77193416866cfd0cecd1e1e9facb4a84aa221ae42a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
module SNS
|
34
|
+
module Lambda
|
35
35
|
|
36
36
|
end
|
37
37
|
|
38
|
-
module
|
38
|
+
module S3
|
39
39
|
|
40
40
|
end
|
41
41
|
|
42
|
-
module
|
42
|
+
module SNS
|
43
43
|
|
44
44
|
end
|
45
45
|
|
46
|
-
module
|
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
|
-
|
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] ==
|
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] ==
|
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.
|
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-
|
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
|