cfn-model 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/bin/cfn_parse +8 -0
  3. data/lib/cfn-model/model/bucket_policy.rb +13 -0
  4. data/lib/cfn-model/model/cfn_model.rb +64 -0
  5. data/lib/cfn-model/model/ec2_instance.rb +15 -0
  6. data/lib/cfn-model/model/ec2_network_interface.rb +18 -0
  7. data/lib/cfn-model/model/iam_group.rb +15 -0
  8. data/lib/cfn-model/model/iam_managed_policy.rb +14 -0
  9. data/lib/cfn-model/model/iam_policy.rb +14 -0
  10. data/lib/cfn-model/model/iam_role.rb +14 -0
  11. data/lib/cfn-model/model/iam_user.rb +16 -0
  12. data/lib/cfn-model/model/iam_user_to_group_addition.rb +10 -0
  13. data/lib/cfn-model/model/load_balancer.rb +37 -0
  14. data/lib/cfn-model/model/model_element.rb +101 -0
  15. data/lib/cfn-model/model/policy.rb +10 -0
  16. data/lib/cfn-model/model/policy_document.rb +52 -0
  17. data/lib/cfn-model/model/principal.rb +34 -0
  18. data/lib/cfn-model/model/queue_policy.rb +13 -0
  19. data/lib/cfn-model/model/references.rb +52 -0
  20. data/lib/cfn-model/model/security_group.rb +18 -0
  21. data/lib/cfn-model/model/security_group_egress.rb +29 -0
  22. data/lib/cfn-model/model/security_group_ingress.rb +38 -0
  23. data/lib/cfn-model/model/statement.rb +38 -0
  24. data/lib/cfn-model/model/topic_policy.rb +13 -0
  25. data/lib/cfn-model/parser/cfn_parser.rb +126 -0
  26. data/lib/cfn-model/parser/ec2_instance_parser.rb +10 -0
  27. data/lib/cfn-model/parser/ec2_network_interface_parser.rb +10 -0
  28. data/lib/cfn-model/parser/iam_group_parser.rb +17 -0
  29. data/lib/cfn-model/parser/iam_role_parser.rb +20 -0
  30. data/lib/cfn-model/parser/iam_user_parser.rb +58 -0
  31. data/lib/cfn-model/parser/load_balancer_parser.rb +10 -0
  32. data/lib/cfn-model/parser/load_balancer_v2_parser.rb +15 -0
  33. data/lib/cfn-model/parser/parser_error.rb +13 -0
  34. data/lib/cfn-model/parser/parser_registry.rb +34 -0
  35. data/lib/cfn-model/parser/policy_document_parser.rb +44 -0
  36. data/lib/cfn-model/parser/security_group_parser.rb +83 -0
  37. data/lib/cfn-model/parser/with_policy_document_parser.rb +10 -0
  38. data/lib/cfn-model/schema/AWS_CloudFront_Distribution.yml +42 -0
  39. data/lib/cfn-model/schema/AWS_EC2_Instance.yml +146 -0
  40. data/lib/cfn-model/schema/AWS_EC2_NetworkInterface.yml +62 -0
  41. data/lib/cfn-model/schema/AWS_EC2_NetworkInterfaceAttachment.yml +24 -0
  42. data/lib/cfn-model/schema/AWS_EC2_SecurityGroup.yml +71 -0
  43. data/lib/cfn-model/schema/AWS_EC2_SecurityGroupEgress.yml +27 -0
  44. data/lib/cfn-model/schema/AWS_EC2_SecurityGroupIngress.yml +27 -0
  45. data/lib/cfn-model/schema/AWS_ElasticLoadBalancingV2_LoadBalancer.yml +56 -0
  46. data/lib/cfn-model/schema/AWS_ElasticLoadBalancing_LoadBalancer.yml +188 -0
  47. data/lib/cfn-model/schema/AWS_IAM_Group.yml +23 -0
  48. data/lib/cfn-model/schema/AWS_IAM_ManagedPolicy.yml +34 -0
  49. data/lib/cfn-model/schema/AWS_IAM_Policy.yml +36 -0
  50. data/lib/cfn-model/schema/AWS_IAM_Role.yml +28 -0
  51. data/lib/cfn-model/schema/AWS_IAM_User.yml +38 -0
  52. data/lib/cfn-model/schema/AWS_IAM_UserToGroupAddition.yml +23 -0
  53. data/lib/cfn-model/schema/AWS_Lambda_Permission.yml +24 -0
  54. data/lib/cfn-model/schema/AWS_S3_BucketPolicy.yml +21 -0
  55. data/lib/cfn-model/schema/AWS_SNS_TopicPolicy.yml +23 -0
  56. data/lib/cfn-model/schema/AWS_SQS_QueuePolicy.yml +23 -0
  57. data/lib/cfn-model/schema/schema.yml.erb +17 -0
  58. data/lib/cfn-model/validator/cloudformation_validator.rb +12 -0
  59. data/lib/cfn-model/validator/reference_validator.rb +83 -0
  60. data/lib/cfn-model/validator/resource_type_validator.rb +34 -0
  61. data/lib/cfn-model/validator/schema_generator.rb +86 -0
  62. data/lib/cfn-model.rb +2 -0
  63. metadata +120 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: df7b00fc32259e430e24108cd53e3f9d6a314415
4
+ data.tar.gz: fdfe0f37dc53623ffda3fad4cd32b9aaa466b3fa
5
+ SHA512:
6
+ metadata.gz: 98060606e4d5a092a4b6619093f770b09b7bdf714a15dd93481f0c3df6b10ba6907afcfe26db0940cdb5a7cf9666b72acf828aa61a40f6e6c1cb6c68286d2f3f
7
+ data.tar.gz: 4e30e1684419ff1cab3d400dfcf5eb57591c9a6518ae7fea8fd6362788280c5d4bcbca9344eca566f8b4441bed5da4e8433c3ca910cbb652c3cf469eb992bff3
data/bin/cfn_parse ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'cfn-model'
3
+
4
+ puts '======'
5
+ puts ARGV[0]
6
+ puts '======'
7
+ cfn_model = CfnParser.new.parse IO.read(ARGV[0])
8
+ puts cfn_model
@@ -0,0 +1,13 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::S3::BucketPolicy < ModelElement
4
+ # mapped from document
5
+ attr_accessor :bucket, :policyDocument
6
+
7
+ # PolicyDocument - objectified policyDocument
8
+ attr_accessor :policy_document
9
+
10
+ def initialize
11
+ @resource_type = 'AWS::S3::BucketPolicy'
12
+ end
13
+ end
@@ -0,0 +1,64 @@
1
+ require_relative 'references'
2
+
3
+ class CfnModel
4
+ attr_reader :resources
5
+
6
+ ##
7
+ # if you really want it, here it is - the raw Hash from YAML.load. you'll have to mess with structural nits of
8
+ # CloudFormation and deal with variations between yaml/json refs and all that
9
+ #
10
+ attr_accessor :raw_model
11
+
12
+ def initialize
13
+ @resources = {}
14
+ @raw_model = nil
15
+ end
16
+
17
+ def security_groups
18
+ resources_by_type 'AWS::EC2::SecurityGroup'
19
+ end
20
+
21
+ def iam_users
22
+ resources_by_type 'AWS::IAM::User'
23
+ end
24
+
25
+ def standalone_ingress
26
+ security_group_ingresses = resources_by_type 'AWS::EC2::SecurityGroupIngress'
27
+ security_group_ingresses.select do |security_group_ingress|
28
+ References.is_security_group_id_external(security_group_ingress.groupId)
29
+ end
30
+ end
31
+
32
+ def standalone_egress
33
+ security_group_egresses = resources_by_type 'AWS::EC2::SecurityGroupEgress'
34
+ security_group_egresses.select do |security_group_egress|
35
+ References.is_security_group_id_external(security_group_egress.groupId)
36
+ end
37
+ end
38
+
39
+ def resources_by_type(resource_type)
40
+ @resources.values.select { |resource| resource.resource_type == resource_type }
41
+ end
42
+
43
+ def find_security_group_by_group_id(security_group_reference)
44
+ security_group_id = References.resolve_security_group_id(security_group_reference)
45
+ if security_group_id.nil?
46
+ # leave it alone since external ref or something we don't grok
47
+ security_group_reference
48
+ else
49
+ matched_security_group = security_groups.find do |security_group|
50
+ security_group.logical_resource_id == security_group_id
51
+ end
52
+ if matched_security_group.nil?
53
+ # leave it alone since external ref or something we don't grok
54
+ security_group_reference
55
+ else
56
+ matched_security_group
57
+ end
58
+ end
59
+ end
60
+
61
+ def to_s
62
+ @resources.to_s
63
+ end
64
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::EC2::Instance < ModelElement
4
+ attr_accessor :securityGroupIds, :networkInterfaces
5
+
6
+ # SecurityGroup objects based upon securityGroupIds
7
+ attr_accessor :security_groups
8
+
9
+ def initialize
10
+ @securityGroupIds = []
11
+ @networkInterfaces = []
12
+ @security_groups = []
13
+ @resource_type = 'AWS::EC2::Instance'
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::EC2::NetworkInterface < ModelElement
4
+ attr_accessor :groupSet, :ipv6Addresses, :privateIpAddresses, :tags
5
+ attr_accessor :description, :ipv6AddressCount, :privateIpAddress, :secondaryPrivateIpAddressCount, :sourceDestCheck, :subnetId
6
+
7
+ # SecurityGroup objects based upon groupSet
8
+ attr_accessor :security_groups
9
+
10
+ def initialize
11
+ @groupSet = []
12
+ @ipv6Addresses = []
13
+ @privateIpAddresses = []
14
+ @tags = []
15
+ @security_groups = []
16
+ @resource_type = 'AWS::EC2::NetworkInterface'
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::IAM::Group < ModelElement
4
+ attr_accessor :groupName, :managedPolicyArns, :path, :policies
5
+
6
+ # synthesized version of policies
7
+ attr_accessor :policy_objects
8
+
9
+ def initialize
10
+ @managedPolicyArns = []
11
+ @policies = []
12
+ @policy_objects = []
13
+ @resource_type = 'AWS::IAM::Group'
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::IAM::ManagedPolicy < ModelElement
4
+ attr_accessor :description, :managedPolicyName, :policyDocument, :groups, :roles, :users, :path
5
+
6
+ attr_accessor :policy_document
7
+
8
+ def initialize
9
+ @groups = []
10
+ @roles = []
11
+ @users = []
12
+ @resource_type = 'AWS::IAM::ManagedPolicy'
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::IAM::Policy < ModelElement
4
+ attr_accessor :policyName, :policyDocument, :groups, :roles, :users
5
+
6
+ attr_accessor :policy_document
7
+
8
+ def initialize
9
+ @groups = []
10
+ @roles = []
11
+ @users = []
12
+ @resource_type = 'AWS::IAM::Policy'
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::IAM::Role < ModelElement
4
+ attr_accessor :roleName, :assumeRolePolicyDocument, :policies, :path, :managedPolicyArns
5
+
6
+ attr_accessor :policy_objects, :assume_role_policy_document
7
+
8
+ def initialize
9
+ @policies = []
10
+ @managedPolicyArns = []
11
+ @policy_objects = []
12
+ @resource_type = 'AWS::IAM::Role'
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::IAM::User < ModelElement
4
+ attr_accessor :groups, :loginProfile, :path, :policies, :userName
5
+
6
+ # synthesized version of policies
7
+ attr_accessor :policy_objects, :group_names
8
+
9
+ def initialize
10
+ @groups = []
11
+ @policies = []
12
+ @policy_objects = []
13
+ @group_names = []
14
+ @resource_type = 'AWS::IAM::User'
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::IAM::UserToGroupAddition < ModelElement
4
+ attr_accessor :groupName, :users
5
+
6
+ def initialize
7
+ @users = []
8
+ @resource_type = 'AWS::IAM::UserToGroupAddition'
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::ElasticLoadBalancing::LoadBalancer < ModelElement
4
+ attr_accessor :securityGroups, :subnets, :tags, :scheme, :loadBalancerName, :crossZone, :availabilityZones, :connectionDrainingPolicy
5
+ attr_accessor :connectionSettings, :accessLoggingPolicy, :instances, :appCookieStickinessPolicy, :lBCookieStickinessPolicy, :healthCheck, :policies, :listeners
6
+
7
+ attr_accessor :security_groups
8
+
9
+ def initialize
10
+ @securityGroups = []
11
+ @security_groups = []
12
+ @subnets = []
13
+ @tags = []
14
+ @availabilityZones = []
15
+ @instances = []
16
+ @appCookieStickinessPolicy = []
17
+ @lBCookieStickinessPolicy = []
18
+ @policies = []
19
+ @listeners = []
20
+ @resource_type = 'AWS::ElasticLoadBalancing::LoadBalancer'
21
+ end
22
+ end
23
+
24
+ class AWS::ElasticLoadBalancingV2::LoadBalancer < ModelElement
25
+ attr_accessor :securityGroups, :loadBalancerAttributes, :subnets, :tags, :scheme, :name, :ipAddressType
26
+
27
+ attr_accessor :security_groups
28
+
29
+ def initialize
30
+ @securityGroups = []
31
+ @security_groups = []
32
+ @loadBalancerAttributes = []
33
+ @subnets = []
34
+ @tags = []
35
+ @resource_type = 'AWS::ElasticLoadBalancingV2::LoadBalancer'
36
+ end
37
+ end
@@ -0,0 +1,101 @@
1
+
2
+ module AWS
3
+ module CloudFormation
4
+
5
+ end
6
+
7
+ module EC2
8
+
9
+ end
10
+
11
+ module ElasticLoadBalancing
12
+
13
+ end
14
+
15
+ module ElasticLoadBalancingV2
16
+
17
+ end
18
+
19
+ module IAM
20
+
21
+ end
22
+
23
+ module S3
24
+
25
+ end
26
+
27
+ module SNS
28
+
29
+ end
30
+
31
+ module SQS
32
+
33
+ end
34
+
35
+ module Lambda
36
+
37
+ end
38
+
39
+ module CloudFront
40
+
41
+ end
42
+ end
43
+
44
+ module Custom
45
+
46
+ end
47
+
48
+ class ModelElement
49
+ attr_accessor :logical_resource_id, :resource_type
50
+
51
+ def to_s
52
+ <<END
53
+ {
54
+ #{emit_instance_vars}
55
+ }
56
+ END
57
+ end
58
+
59
+ def ==(another_model_element)
60
+ found_unequal_instance_var = false
61
+ instance_variables_without_at_sign.each do |instance_variable|
62
+ if instance_variable != :logical_resource_id
63
+ if self.send(instance_variable) != another_model_element.send(instance_variable)
64
+ found_unequal_instance_var = true
65
+ end
66
+ end
67
+ end
68
+ !found_unequal_instance_var
69
+ end
70
+
71
+ private
72
+
73
+ ##
74
+ # Treat any missing method as an instance variable get/set
75
+ #
76
+ # This will allow arbitrary elements in Resource/Properties definitions
77
+ # to map to instance variables without having to anticipate them in a schema
78
+ def method_missing(method_name, *args)
79
+ if method_name =~ /^(\w+)=$/
80
+ instance_variable_set "@#{$1}", args[0]
81
+ else
82
+ instance_variable_get "@#{method_name}"
83
+ end
84
+ end
85
+
86
+ def instance_variables_without_at_sign
87
+ self.instance_variables.map { |instance_variable| strip(instance_variable) }
88
+ end
89
+
90
+ def strip(sym)
91
+ sym.to_s.gsub(/@/, '').to_sym
92
+ end
93
+
94
+ def emit_instance_vars
95
+ instance_vars_str = ''
96
+ self.instance_variables.each do |instance_variable|
97
+ instance_vars_str += " #{instance_variable}=#{instance_variable_get(instance_variable)}\n"
98
+ end
99
+ instance_vars_str
100
+ end
101
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'model_element'
2
+
3
+ class Policy
4
+ attr_accessor :policy_name, :policy_document
5
+
6
+ def ==(another_policy)
7
+ policy_name == another_policy.policy_name &&
8
+ policy_document == another_policy.policy_document
9
+ end
10
+ end
@@ -0,0 +1,52 @@
1
+ require_relative 'statement'
2
+
3
+ class PolicyDocument
4
+ attr_accessor :version, :statements
5
+
6
+ def initialize
7
+ @statements = []
8
+ end
9
+
10
+ def wildcard_allowed_resources
11
+ @statements.select { |statement| !statement.wildcard_resources.empty? && statement.effect == 'Allow' }
12
+ end
13
+
14
+ def wildcard_allowed_actions
15
+ @statements.select { |statement| !statement.wildcard_actions.empty? && statement.effect == 'Allow' }
16
+ end
17
+
18
+ def wildcard_allowed_principals
19
+ @statements.select { |statement| statement.wildcard_principal? && statement.effect == 'Allow' }
20
+ end
21
+
22
+ ##
23
+ # Select any Statement objects that Allow in conjunction with a NotAction
24
+ #
25
+ def allows_not_action
26
+ @statements.select { |statement| !statement.not_actions.empty? && statement.effect == 'Allow' }
27
+ end
28
+
29
+ def allows_not_resource
30
+ @statements.select { |statement| !statement.not_resources.empty? && statement.effect == 'Allow' }
31
+ end
32
+
33
+ def allows_not_principal
34
+ @statements.select { |statement| !statement.not_principal.nil? && statement.effect == 'Allow' }
35
+ end
36
+
37
+ def ==(another_doc)
38
+ @version == another_doc.version && @statements == another_doc.statements
39
+ end
40
+
41
+ def to_s
42
+ <<END
43
+ {
44
+ version=#{@version}
45
+ statements=#{@statements}
46
+ }
47
+ END
48
+ end
49
+ end
50
+
51
+
52
+
@@ -0,0 +1,34 @@
1
+ class Principal
2
+ def self.wildcard?(principal)
3
+ if principal.is_a? String
4
+ return has_asterisk principal
5
+ elsif principal.is_a? Hash
6
+ # if new principal types arrive, let's not tie ourselves down - the * is still likely the thing to look for
7
+ # unless %w(AWS FederatedUser CanonicalUser Service).include?(principal.keys.first)
8
+ # raise "whacky principal key: #{principal}"
9
+ # end
10
+
11
+ has_wildcard = false
12
+ principal.values.each do |principal_value|
13
+ if principal_value.is_a? String
14
+ has_wildcard ||= has_asterisk principal_value
15
+ elsif principal_value.is_a? Array
16
+ wildcard_principal = principal_value.find { |principal_iter| principal_iter =~ /\*/ }
17
+ has_wildcard ||= !wildcard_principal.nil?
18
+ end
19
+ end
20
+ has_wildcard
21
+ elsif principal.nil?
22
+ false
23
+ else
24
+ # array? not legal?
25
+ raise "whacky principal not string or hash: #{principal}"
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def self.has_asterisk(string)
32
+ !(string =~ /\*/).nil?
33
+ end
34
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::SQS::QueuePolicy < ModelElement
4
+ attr_accessor :queues, :policyDocument
5
+
6
+ # PolicyDocument - objectified policyDocument
7
+ attr_accessor :policy_document
8
+
9
+ def initialize
10
+ @queues = []
11
+ @resource_type = 'AWS::SQS::QueuePolicy'
12
+ end
13
+ end
@@ -0,0 +1,52 @@
1
+
2
+ ##
3
+ # this is a placeholder for anything related to resolving references
4
+ #
5
+ # not sure if we are going to be able to have a useful generic set of code for
6
+ # references yet... in the meantime pile things up here and hope a pattern becomes
7
+ # clear
8
+ module References
9
+ def self.is_security_group_id_external(group_id)
10
+ resolve_security_group_id(group_id).nil?
11
+ end
12
+
13
+ ##
14
+ # Return nil if
15
+ def self.resolve_security_group_id(group_id)
16
+ return nil if group_id.is_a? String
17
+
18
+ # an imported value can only yield a literal to an external sg vs. referencing something local
19
+ if !group_id['Ref'].nil?
20
+ group_id['Ref']
21
+ elsif !group_id['Fn::GetAtt'].nil?
22
+ logical_resource_id_from_get_att group_id['Fn::GetAtt']
23
+ else # !group_id['Fn::ImportValue'].nil?
24
+ # anything else will be string manipulation functions
25
+ # which again leads us back to a string which must be an external security group known out of band
26
+ # so don't/can't link it up to a security group
27
+ return nil
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def self.logical_resource_id_from_get_att(attribute_spec)
34
+ if attribute_spec.is_a? Array
35
+ if attribute_spec[1] == 'GroupId'
36
+ return attribute_spec.first
37
+ else
38
+ # this could be a reference to a nested stack output so treat it as external
39
+ # and presume the ingress is freestanding.
40
+ return nil
41
+ end
42
+ elsif attribute_spec.is_a? String
43
+ if attribute_spec.split('.')[1] == 'GroupId'
44
+ return attribute_spec.split('.').first
45
+ else
46
+ # this could be a reference to a nested stack output so treat it as external
47
+ # and presume the ingress is freestanding.
48
+ return nil
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::EC2::SecurityGroup < ModelElement
4
+ attr_accessor :groupDescription, :vpcId
5
+ attr_accessor :tags
6
+ attr_accessor :securityGroupIngress, :securityGroupEgress
7
+
8
+ attr_accessor :ingresses, :egresses
9
+
10
+ def initialize
11
+ @securityGroupIngress = []
12
+ @securityGroupEgress = []
13
+ @ingresses = []
14
+ @egresses = []
15
+ @tags = []
16
+ @resource_type = 'AWS::EC2::SecurityGroup'
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'model_element'
2
+
3
+ # this could have been inline or freestanding
4
+ # in latter case there would be a logical resource id
5
+ # but i think we don't ever care?
6
+ class AWS::EC2::SecurityGroupEgress < ModelElement
7
+ # You must specify a destination security group (destinationPrefixListId or destinationSecurityGroupId) or a CIDR range (CidrIp or CidrIpv6).
8
+ attr_accessor :cidrIp,
9
+ :cidrIpv6,
10
+ :destinationPrefixListId,
11
+ :destinationSecurityGroupId
12
+
13
+ # required
14
+ attr_accessor :groupId,
15
+ :fromPort,
16
+ :toPort,
17
+ :ipProtocol
18
+
19
+ def initialize
20
+ @resource_type = 'AWS::EC2::SecurityGroupEgress'
21
+ end
22
+
23
+ # def valid?
24
+ # has_no_destination = @cidrIp.nil? && @cidrIpv6.nil? && @destinationPrefixListId.nil? && @destinationSecurityGroupId.nil?
25
+ # if has_no_destination
26
+ # raise "SG egress #{@logical_resource_id} has no destination specified"
27
+ # end
28
+ # end
29
+ end
@@ -0,0 +1,38 @@
1
+ require_relative 'model_element'
2
+
3
+ # this could have been inline or freestanding
4
+ # in latter case there would be a logical resource id
5
+ # but i think we don't ever care?
6
+ class AWS::EC2::SecurityGroupIngress < ModelElement
7
+ # You must specify a source security group (SourceSecurityGroupName or SourceSecurityGroupId) or a CIDR range (CidrIp or CidrIpv6).
8
+ attr_accessor :cidrIp,
9
+ :cidrIpv6,
10
+ :sourceSecurityGroupName,
11
+ :sourceSecurityGroupId
12
+
13
+ # Required: Conditional. You must specify the GroupName property or the GroupId property.
14
+ # For security groups that are in a VPC, you must use the GroupId property. For example, EC2-VPC accounts must use the GroupId property.
15
+ # this will be nil for inline ingress rules
16
+ attr_accessor :groupId,
17
+ :groupName
18
+
19
+ # required
20
+ attr_accessor :fromPort,
21
+ :toPort,
22
+ :ipProtocol
23
+
24
+ # Required: Conditional. If you specify SourceSecurityGroupName and that security group is owned by a different
25
+ # account than the account creating the stack, you must specify the SourceSecurityGroupOwnerId; otherwise, this property is optional.
26
+ attr_accessor :sourceSecurityGroupOwnerId
27
+
28
+ def initialize
29
+ @resource_type = 'AWS::EC2::SecurityGroupIngress'
30
+ end
31
+
32
+ # def valid?
33
+ # has_no_source = @cidrIp.nil? && @cidrIpv6.nil? && @sourceSecurityGroupName.nil? && @sourceSecurityGroupId.nil?
34
+ # if has_no_source
35
+ # raise "SG ingress #{@logical_resource_id} has no source specified"
36
+ # end
37
+ # end
38
+ end
@@ -0,0 +1,38 @@
1
+ require_relative 'principal'
2
+
3
+ class Statement
4
+ attr_accessor :sid, :effect, :condition
5
+ attr_accessor :actions, :not_actions
6
+ attr_accessor :resources, :not_resources
7
+ attr_accessor :principal, :not_principal
8
+
9
+ def initialize
10
+ @actions = []
11
+ @not_actions = []
12
+ @resources = []
13
+ @not_resources = []
14
+ end
15
+
16
+ def wildcard_actions
17
+ @actions.select { |action| action.to_s =~ /\*/ }
18
+ end
19
+
20
+ def wildcard_principal?
21
+ Principal.wildcard? @principal
22
+ end
23
+
24
+ def wildcard_resources
25
+ @resources.select { |action| action.to_s =~ /\*/ }
26
+ end
27
+
28
+ def ==(another_statement)
29
+ @effect == another_statement.effect &&
30
+ @actions == another_statement.actions &&
31
+ @not_actions == another_statement.not_actions &&
32
+ @resources == another_statement.resources &&
33
+ @not_resources == another_statement.not_resources &&
34
+ @principal == another_statement.principal &&
35
+ @not_principal == another_statement.not_principal &&
36
+ @condition == another_statement.condition
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'model_element'
2
+
3
+ class AWS::SNS::TopicPolicy < ModelElement
4
+ attr_accessor :topics, :policyDocument
5
+
6
+ # PolicyDocument - objectified policyDocument
7
+ attr_accessor :policy_document
8
+
9
+ def initialize
10
+ @topics = []
11
+ @resource_type = 'AWS::SNS::TopicPolicy'
12
+ end
13
+ end