cfn-model 0.0.0
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 +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: []
|