cfn-model 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/cfn_parse +8 -0
- data/lib/cfn-model/model/bucket_policy.rb +13 -0
- data/lib/cfn-model/model/cfn_model.rb +64 -0
- data/lib/cfn-model/model/ec2_instance.rb +15 -0
- data/lib/cfn-model/model/ec2_network_interface.rb +18 -0
- data/lib/cfn-model/model/iam_group.rb +15 -0
- data/lib/cfn-model/model/iam_managed_policy.rb +14 -0
- data/lib/cfn-model/model/iam_policy.rb +14 -0
- data/lib/cfn-model/model/iam_role.rb +14 -0
- data/lib/cfn-model/model/iam_user.rb +16 -0
- data/lib/cfn-model/model/iam_user_to_group_addition.rb +10 -0
- data/lib/cfn-model/model/load_balancer.rb +37 -0
- data/lib/cfn-model/model/model_element.rb +101 -0
- data/lib/cfn-model/model/policy.rb +10 -0
- data/lib/cfn-model/model/policy_document.rb +52 -0
- data/lib/cfn-model/model/principal.rb +34 -0
- data/lib/cfn-model/model/queue_policy.rb +13 -0
- data/lib/cfn-model/model/references.rb +52 -0
- data/lib/cfn-model/model/security_group.rb +18 -0
- data/lib/cfn-model/model/security_group_egress.rb +29 -0
- data/lib/cfn-model/model/security_group_ingress.rb +38 -0
- data/lib/cfn-model/model/statement.rb +38 -0
- data/lib/cfn-model/model/topic_policy.rb +13 -0
- data/lib/cfn-model/parser/cfn_parser.rb +126 -0
- data/lib/cfn-model/parser/ec2_instance_parser.rb +10 -0
- data/lib/cfn-model/parser/ec2_network_interface_parser.rb +10 -0
- data/lib/cfn-model/parser/iam_group_parser.rb +17 -0
- data/lib/cfn-model/parser/iam_role_parser.rb +20 -0
- data/lib/cfn-model/parser/iam_user_parser.rb +58 -0
- data/lib/cfn-model/parser/load_balancer_parser.rb +10 -0
- data/lib/cfn-model/parser/load_balancer_v2_parser.rb +15 -0
- data/lib/cfn-model/parser/parser_error.rb +13 -0
- data/lib/cfn-model/parser/parser_registry.rb +34 -0
- data/lib/cfn-model/parser/policy_document_parser.rb +44 -0
- data/lib/cfn-model/parser/security_group_parser.rb +83 -0
- data/lib/cfn-model/parser/with_policy_document_parser.rb +10 -0
- data/lib/cfn-model/schema/AWS_CloudFront_Distribution.yml +42 -0
- data/lib/cfn-model/schema/AWS_EC2_Instance.yml +146 -0
- data/lib/cfn-model/schema/AWS_EC2_NetworkInterface.yml +62 -0
- data/lib/cfn-model/schema/AWS_EC2_NetworkInterfaceAttachment.yml +24 -0
- data/lib/cfn-model/schema/AWS_EC2_SecurityGroup.yml +71 -0
- data/lib/cfn-model/schema/AWS_EC2_SecurityGroupEgress.yml +27 -0
- data/lib/cfn-model/schema/AWS_EC2_SecurityGroupIngress.yml +27 -0
- data/lib/cfn-model/schema/AWS_ElasticLoadBalancingV2_LoadBalancer.yml +56 -0
- data/lib/cfn-model/schema/AWS_ElasticLoadBalancing_LoadBalancer.yml +188 -0
- data/lib/cfn-model/schema/AWS_IAM_Group.yml +23 -0
- data/lib/cfn-model/schema/AWS_IAM_ManagedPolicy.yml +34 -0
- data/lib/cfn-model/schema/AWS_IAM_Policy.yml +36 -0
- data/lib/cfn-model/schema/AWS_IAM_Role.yml +28 -0
- data/lib/cfn-model/schema/AWS_IAM_User.yml +38 -0
- data/lib/cfn-model/schema/AWS_IAM_UserToGroupAddition.yml +23 -0
- data/lib/cfn-model/schema/AWS_Lambda_Permission.yml +24 -0
- data/lib/cfn-model/schema/AWS_S3_BucketPolicy.yml +21 -0
- data/lib/cfn-model/schema/AWS_SNS_TopicPolicy.yml +23 -0
- data/lib/cfn-model/schema/AWS_SQS_QueuePolicy.yml +23 -0
- data/lib/cfn-model/schema/schema.yml.erb +17 -0
- data/lib/cfn-model/validator/cloudformation_validator.rb +12 -0
- data/lib/cfn-model/validator/reference_validator.rb +83 -0
- data/lib/cfn-model/validator/resource_type_validator.rb +34 -0
- data/lib/cfn-model/validator/schema_generator.rb +86 -0
- data/lib/cfn-model.rb +2 -0
- metadata +120 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
type: map
|
3
|
+
mapping:
|
4
|
+
Type:
|
5
|
+
type: str
|
6
|
+
required: yes
|
7
|
+
pattern: /AWS::SNS::TopicPolicy/
|
8
|
+
Properties:
|
9
|
+
type: map
|
10
|
+
required: yes
|
11
|
+
mapping:
|
12
|
+
PolicyDocument:
|
13
|
+
type: any
|
14
|
+
required: yes
|
15
|
+
Topics:
|
16
|
+
type: seq
|
17
|
+
required: yes
|
18
|
+
sequence:
|
19
|
+
- type: any
|
20
|
+
=:
|
21
|
+
type: any
|
22
|
+
=:
|
23
|
+
type: any
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
type: map
|
3
|
+
mapping:
|
4
|
+
Type:
|
5
|
+
type: str
|
6
|
+
required: yes
|
7
|
+
pattern: /AWS::SQS::QueuePolicy/
|
8
|
+
Properties:
|
9
|
+
type: map
|
10
|
+
required: yes
|
11
|
+
mapping:
|
12
|
+
PolicyDocument:
|
13
|
+
type: any
|
14
|
+
required: yes
|
15
|
+
Queues:
|
16
|
+
type: seq
|
17
|
+
required: yes
|
18
|
+
sequence:
|
19
|
+
- type: any
|
20
|
+
=:
|
21
|
+
type: any
|
22
|
+
=:
|
23
|
+
type: any
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative 'schema_generator'
|
2
|
+
require 'kwalify'
|
3
|
+
|
4
|
+
class CloudFormationValidator
|
5
|
+
def validate(cloudformation_string)
|
6
|
+
schema = SchemaGenerator.new.generate cloudformation_string
|
7
|
+
|
8
|
+
validator = Kwalify::Validator.new(schema)
|
9
|
+
|
10
|
+
validator.validate(YAML.load(cloudformation_string))
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
class ReferenceValidator
|
4
|
+
def unresolved_references(cloudformation_hash)
|
5
|
+
if cloudformation_hash['Parameters'].nil?
|
6
|
+
parameter_keys = []
|
7
|
+
else
|
8
|
+
parameter_keys = cloudformation_hash['Parameters'].keys
|
9
|
+
end
|
10
|
+
|
11
|
+
resource_keys = cloudformation_hash['Resources'].keys
|
12
|
+
missing_refs = all_references(cloudformation_hash) - Set.new(parameter_keys + resource_keys)
|
13
|
+
missing_refs
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def all_references(cloudformation_hash)
|
19
|
+
result = Set.new
|
20
|
+
cloudformation_hash['Resources'].values.each do |resource_hash|
|
21
|
+
result |= all_ref(resource_hash['Properties'])
|
22
|
+
result |= all_get_att(resource_hash['Properties'])
|
23
|
+
end
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
def all_ref(properties_hash)
|
28
|
+
refs = Set.new
|
29
|
+
|
30
|
+
unless properties_hash.nil?
|
31
|
+
properties_hash.values.each do |value|
|
32
|
+
if value.is_a? Hash
|
33
|
+
sub_hash = value
|
34
|
+
|
35
|
+
if sub_hash.size == 1 && !sub_hash['Ref'].nil?
|
36
|
+
unless sub_hash['Ref'].is_a? String
|
37
|
+
raise ParserError.new("Ref target must be string literal: #{sub_hash}")
|
38
|
+
end
|
39
|
+
|
40
|
+
unless pseudo_reference?(sub_hash['Ref'])
|
41
|
+
refs << sub_hash['Ref']
|
42
|
+
end
|
43
|
+
else
|
44
|
+
refs |= all_ref(sub_hash)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
refs
|
50
|
+
end
|
51
|
+
|
52
|
+
def all_get_att(properties_hash)
|
53
|
+
refs = Set.new
|
54
|
+
|
55
|
+
unless properties_hash.nil?
|
56
|
+
properties_hash.values.each do |value|
|
57
|
+
if value.is_a? Hash
|
58
|
+
sub_hash = value
|
59
|
+
|
60
|
+
# ! GetAtt too
|
61
|
+
if sub_hash.size == 1 && !sub_hash['Fn::GetAtt'].nil?
|
62
|
+
if sub_hash['Fn::GetAtt'].is_a? Array
|
63
|
+
refs << sub_hash['Fn::GetAtt'][0]
|
64
|
+
elsif sub_hash['Fn::GetAtt'].is_a? String
|
65
|
+
if sub_hash['Fn::GetAtt'] =~ /([^.]*)\.(.*)/
|
66
|
+
refs << $1
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
else
|
71
|
+
refs |= all_get_att(sub_hash)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
refs
|
78
|
+
end
|
79
|
+
|
80
|
+
def pseudo_reference?(ref)
|
81
|
+
ref =~ /AWS::.*/
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'cfn-model/parser/parser_error'
|
2
|
+
|
3
|
+
class ResourceTypeValidator
|
4
|
+
|
5
|
+
def self.validate(cloudformation_yml)
|
6
|
+
hash = YAML.load cloudformation_yml
|
7
|
+
if hash == false || hash.nil?
|
8
|
+
raise ParserError.new 'yml empty'
|
9
|
+
end
|
10
|
+
|
11
|
+
if hash['Resources'].nil? or hash['Resources'].empty?
|
12
|
+
raise ParserError.new 'Illegal cfn - no Resources'
|
13
|
+
end
|
14
|
+
|
15
|
+
resources = hash['Resources']
|
16
|
+
|
17
|
+
resources.each do |resource_id, resource|
|
18
|
+
if resource['Type'].nil?
|
19
|
+
raise ParserError.new "Illegal cfn - missing Type: id: #{resource_id}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
parameters = hash['Parameters']
|
24
|
+
unless parameters.nil?
|
25
|
+
parameters.each do |parameter_id, parameter|
|
26
|
+
if parameter['Type'].nil?
|
27
|
+
raise ParserError.new "Illegal cfn - missing Parameter Type: id: #{parameter_id}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
hash
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require_relative 'resource_type_validator'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
##
|
5
|
+
# This generator is a bit of hacking to trick kwalify into validating yaml for a cfn template.
|
6
|
+
#
|
7
|
+
# because cfn uses open-ended key names for the resources.... a static schema can't be used
|
8
|
+
# with kwalify. so first we make sure there is a basic structure of resources with Type values
|
9
|
+
# then we generate the schema from the document for the keys and cross-reference with schema
|
10
|
+
# files per resource type
|
11
|
+
class SchemaGenerator
|
12
|
+
def generate(cloudformation_yml)
|
13
|
+
|
14
|
+
# make sure structure of Resources is decent and that every record has a Type at least
|
15
|
+
cloudformation_hash = ResourceTypeValidator.validate cloudformation_yml
|
16
|
+
|
17
|
+
parameters_schema = generate_schema_for_parameter_keys cloudformation_hash
|
18
|
+
resources_schema = generate_schema_for_resource_keys cloudformation_hash
|
19
|
+
|
20
|
+
main_schema = YAML.load IO.read(schema_file('schema.yml.erb'))
|
21
|
+
if parameters_schema.empty?
|
22
|
+
main_schema['mapping'].delete 'Parameters'
|
23
|
+
else
|
24
|
+
main_schema['mapping']['Parameters']['mapping'] = parameters_schema
|
25
|
+
end
|
26
|
+
main_schema['mapping']['Resources']['mapping'] = resources_schema
|
27
|
+
main_schema
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
##
|
33
|
+
# this is fairly superfluous. there's not much structure here
|
34
|
+
# except that Types are Strings.... anything else is up to a rule
|
35
|
+
# to wade through all the optional crap (like looking for NoEcho)
|
36
|
+
def generate_schema_for_parameter_keys(cloudformation_hash)
|
37
|
+
return {} if cloudformation_hash['Parameters'].nil?
|
38
|
+
|
39
|
+
parameters_schema = {
|
40
|
+
'=' => { 'type' => 'any'}
|
41
|
+
}
|
42
|
+
|
43
|
+
cloudformation_hash['Parameters'].each do |parameter_key, parameter|
|
44
|
+
parameters_schema[parameter_key] = {
|
45
|
+
'type' => 'map',
|
46
|
+
'mapping' => {
|
47
|
+
'Type' => {
|
48
|
+
'type' => 'str'
|
49
|
+
},
|
50
|
+
'=' => {
|
51
|
+
'type' => 'any'
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
parameters_schema
|
57
|
+
end
|
58
|
+
|
59
|
+
def generate_schema_for_resource_keys(cloudformation_hash)
|
60
|
+
resources_schema = {
|
61
|
+
'=' => { 'type' => 'any'}
|
62
|
+
}
|
63
|
+
|
64
|
+
cloudformation_hash['Resources'].each do |resource_id, resource|
|
65
|
+
schema_hash = schema_for_type(resource['Type'])
|
66
|
+
unless schema_hash.nil?
|
67
|
+
resources_schema[resource_id] = schema_hash
|
68
|
+
end
|
69
|
+
end
|
70
|
+
resources_schema
|
71
|
+
end
|
72
|
+
|
73
|
+
def schema_file(file)
|
74
|
+
"#{__dir__}/../schema/#{file.gsub(/::/, '_')}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def schema_for_type(type)
|
78
|
+
schema_file_path = schema_file("#{type}.yml")
|
79
|
+
|
80
|
+
if !File.exist? schema_file_path
|
81
|
+
nil
|
82
|
+
else
|
83
|
+
YAML.load IO.read(schema_file_path)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/cfn-model.rb
ADDED
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cfn-model
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Kascic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-07-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kwalify
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.7.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.7.2
|
27
|
+
description: An object model for CloudFormation templates
|
28
|
+
email:
|
29
|
+
executables:
|
30
|
+
- cfn_parse
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- bin/cfn_parse
|
35
|
+
- lib/cfn-model.rb
|
36
|
+
- lib/cfn-model/model/bucket_policy.rb
|
37
|
+
- lib/cfn-model/model/cfn_model.rb
|
38
|
+
- lib/cfn-model/model/ec2_instance.rb
|
39
|
+
- lib/cfn-model/model/ec2_network_interface.rb
|
40
|
+
- lib/cfn-model/model/iam_group.rb
|
41
|
+
- lib/cfn-model/model/iam_managed_policy.rb
|
42
|
+
- lib/cfn-model/model/iam_policy.rb
|
43
|
+
- lib/cfn-model/model/iam_role.rb
|
44
|
+
- lib/cfn-model/model/iam_user.rb
|
45
|
+
- lib/cfn-model/model/iam_user_to_group_addition.rb
|
46
|
+
- lib/cfn-model/model/load_balancer.rb
|
47
|
+
- lib/cfn-model/model/model_element.rb
|
48
|
+
- lib/cfn-model/model/policy.rb
|
49
|
+
- lib/cfn-model/model/policy_document.rb
|
50
|
+
- lib/cfn-model/model/principal.rb
|
51
|
+
- lib/cfn-model/model/queue_policy.rb
|
52
|
+
- lib/cfn-model/model/references.rb
|
53
|
+
- lib/cfn-model/model/security_group.rb
|
54
|
+
- lib/cfn-model/model/security_group_egress.rb
|
55
|
+
- lib/cfn-model/model/security_group_ingress.rb
|
56
|
+
- lib/cfn-model/model/statement.rb
|
57
|
+
- lib/cfn-model/model/topic_policy.rb
|
58
|
+
- lib/cfn-model/parser/cfn_parser.rb
|
59
|
+
- lib/cfn-model/parser/ec2_instance_parser.rb
|
60
|
+
- lib/cfn-model/parser/ec2_network_interface_parser.rb
|
61
|
+
- lib/cfn-model/parser/iam_group_parser.rb
|
62
|
+
- lib/cfn-model/parser/iam_role_parser.rb
|
63
|
+
- lib/cfn-model/parser/iam_user_parser.rb
|
64
|
+
- lib/cfn-model/parser/load_balancer_parser.rb
|
65
|
+
- lib/cfn-model/parser/load_balancer_v2_parser.rb
|
66
|
+
- lib/cfn-model/parser/parser_error.rb
|
67
|
+
- lib/cfn-model/parser/parser_registry.rb
|
68
|
+
- lib/cfn-model/parser/policy_document_parser.rb
|
69
|
+
- lib/cfn-model/parser/security_group_parser.rb
|
70
|
+
- lib/cfn-model/parser/with_policy_document_parser.rb
|
71
|
+
- lib/cfn-model/schema/AWS_CloudFront_Distribution.yml
|
72
|
+
- lib/cfn-model/schema/AWS_EC2_Instance.yml
|
73
|
+
- lib/cfn-model/schema/AWS_EC2_NetworkInterface.yml
|
74
|
+
- lib/cfn-model/schema/AWS_EC2_NetworkInterfaceAttachment.yml
|
75
|
+
- lib/cfn-model/schema/AWS_EC2_SecurityGroup.yml
|
76
|
+
- lib/cfn-model/schema/AWS_EC2_SecurityGroupEgress.yml
|
77
|
+
- lib/cfn-model/schema/AWS_EC2_SecurityGroupIngress.yml
|
78
|
+
- lib/cfn-model/schema/AWS_ElasticLoadBalancingV2_LoadBalancer.yml
|
79
|
+
- lib/cfn-model/schema/AWS_ElasticLoadBalancing_LoadBalancer.yml
|
80
|
+
- lib/cfn-model/schema/AWS_IAM_Group.yml
|
81
|
+
- lib/cfn-model/schema/AWS_IAM_ManagedPolicy.yml
|
82
|
+
- lib/cfn-model/schema/AWS_IAM_Policy.yml
|
83
|
+
- lib/cfn-model/schema/AWS_IAM_Role.yml
|
84
|
+
- lib/cfn-model/schema/AWS_IAM_User.yml
|
85
|
+
- lib/cfn-model/schema/AWS_IAM_UserToGroupAddition.yml
|
86
|
+
- lib/cfn-model/schema/AWS_Lambda_Permission.yml
|
87
|
+
- lib/cfn-model/schema/AWS_S3_BucketPolicy.yml
|
88
|
+
- lib/cfn-model/schema/AWS_SNS_TopicPolicy.yml
|
89
|
+
- lib/cfn-model/schema/AWS_SQS_QueuePolicy.yml
|
90
|
+
- lib/cfn-model/schema/schema.yml.erb
|
91
|
+
- lib/cfn-model/validator/cloudformation_validator.rb
|
92
|
+
- lib/cfn-model/validator/reference_validator.rb
|
93
|
+
- lib/cfn-model/validator/resource_type_validator.rb
|
94
|
+
- lib/cfn-model/validator/schema_generator.rb
|
95
|
+
homepage: https://github.com/stelligent/cfn-model
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '2.2'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 2.4.6
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: cfn-model
|
120
|
+
test_files: []
|