cfndsl 0.4.4 → 0.5.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +5 -13
  2. data/.rubocop.yml +23 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +19 -17
  5. data/bin/cfndsl +20 -20
  6. data/cfndsl.gemspec +16 -15
  7. data/lib/cfndsl.rb +62 -68
  8. data/lib/cfndsl/aws/cloud_formation_template.rb +16 -0
  9. data/lib/cfndsl/aws/types.rb +12 -0
  10. data/lib/cfndsl/{aws_types.yaml → aws/types.yaml} +0 -0
  11. data/lib/cfndsl/{Conditions.rb → conditions.rb} +5 -7
  12. data/lib/cfndsl/creation_policy.rb +21 -0
  13. data/lib/cfndsl/errors.rb +29 -0
  14. data/lib/cfndsl/generate_types.rb +154 -0
  15. data/lib/cfndsl/jsonable.rb +214 -0
  16. data/lib/cfndsl/mappings.rb +23 -0
  17. data/lib/cfndsl/metadata.rb +16 -0
  18. data/lib/cfndsl/module.rb +52 -51
  19. data/lib/cfndsl/names.rb +5 -5
  20. data/lib/cfndsl/orchestration_template.rb +173 -0
  21. data/lib/cfndsl/os/heat_template.rb +16 -0
  22. data/lib/cfndsl/os/types.rb +12 -0
  23. data/lib/cfndsl/{os_types.yaml → os/types.yaml} +11 -11
  24. data/lib/cfndsl/{Outputs.rb → outputs.rb} +3 -4
  25. data/lib/cfndsl/{Parameters.rb → parameters.rb} +12 -13
  26. data/lib/cfndsl/plurals.rb +34 -0
  27. data/lib/cfndsl/properties.rb +21 -0
  28. data/lib/cfndsl/rake_task.rb +9 -7
  29. data/lib/cfndsl/ref_check.rb +44 -0
  30. data/lib/cfndsl/{Resources.rb → resources.rb} +13 -15
  31. data/lib/cfndsl/types.rb +151 -0
  32. data/lib/cfndsl/update_policy.rb +25 -0
  33. data/lib/cfndsl/version.rb +1 -1
  34. data/sample/autoscale.rb +152 -158
  35. data/sample/autoscale2.rb +151 -155
  36. data/sample/circular.rb +30 -33
  37. data/sample/codedeploy.rb +35 -36
  38. data/sample/config_service.rb +120 -0
  39. data/sample/ecs.rb +39 -39
  40. data/sample/iam_policies.rb +82 -0
  41. data/sample/lambda.rb +20 -24
  42. data/sample/s3.rb +11 -11
  43. data/sample/t1.rb +7 -9
  44. data/sample/vpc_example.rb +50 -0
  45. data/sample/vpc_with_vpn_example.rb +97 -0
  46. data/spec/cfndsl_spec.rb +22 -11
  47. data/spec/fixtures/heattest.rb +13 -14
  48. data/spec/fixtures/test.rb +56 -53
  49. metadata +36 -30
  50. data/lib/cfndsl/CloudFormationTemplate.rb +0 -267
  51. data/lib/cfndsl/CreationPolicy.rb +0 -25
  52. data/lib/cfndsl/Errors.rb +0 -31
  53. data/lib/cfndsl/JSONable.rb +0 -235
  54. data/lib/cfndsl/Mappings.rb +0 -25
  55. data/lib/cfndsl/Metadata.rb +0 -22
  56. data/lib/cfndsl/Plurals.rb +0 -35
  57. data/lib/cfndsl/Properties.rb +0 -25
  58. data/lib/cfndsl/RefCheck.rb +0 -48
  59. data/lib/cfndsl/Types.rb +0 -309
  60. data/lib/cfndsl/UpdatePolicy.rb +0 -29
  61. data/sample/config-service.rb +0 -119
  62. data/sample/iam-policies.rb +0 -82
  63. data/sample/vpc-example.rb +0 -51
  64. data/sample/vpc-with-vpn-example.rb +0 -97
@@ -0,0 +1,16 @@
1
+ require 'cfndsl/jsonable'
2
+
3
+ module CfnDsl
4
+ # Handles Metadata objects
5
+ class MetadataDefinition < JSONable
6
+ attr_reader :value
7
+
8
+ def initialize(value)
9
+ @value = value
10
+ end
11
+
12
+ def to_json(*a)
13
+ @value.to_json(*a)
14
+ end
15
+ end
16
+ end
data/lib/cfndsl/module.rb CHANGED
@@ -1,73 +1,74 @@
1
- require 'cfndsl/Plurals'
1
+ require 'cfndsl/plurals'
2
2
  require 'cfndsl/names'
3
+
4
+ # Adds some dsl module helpers
3
5
  class Module
4
6
  private
7
+
8
+ # Create setter methods
9
+ #
10
+ # Usage:
11
+ # class Something
12
+ # dsl_attr_setter :Thing
13
+ # end
14
+ #
15
+ # Generates a setter method like this one for each symbol in *symbols:
16
+ #
17
+ # def Thing(value)
18
+ # @Thing = value
19
+ # end
20
+ #
5
21
  def dsl_attr_setter(*symbols)
6
- ##
7
- # Create setter methods
8
- #
9
- # Usage:
10
- # class Something
11
- # dsl_attr_setter :Thing
12
- # end
13
- #
14
- # Generates a setter method like this one for each symbol in *symbols:
15
- #
16
- # def Thing(value)
17
- # @Thing = value
18
- # end
19
- #
20
22
  symbols.each do |symbol|
21
- class_eval do
22
- CfnDsl::methodNames(symbol) do |method|
23
+ class_eval do
24
+ CfnDsl.method_names(symbol) do |method|
23
25
  define_method(method) do |value|
24
- instance_variable_set( "@#{symbol}", value)
26
+ instance_variable_set("@#{symbol}", value)
25
27
  end
26
28
  end
27
- end
29
+ end
28
30
  end
29
31
  end
30
-
32
+
33
+ # Create object declaration methods.
34
+ #
35
+ # Usage:
36
+ # Class Something
37
+ # dsl_content_object :Stuff
38
+ # end
39
+ #
40
+ # Generates methods like this:
41
+ #
42
+ # def Stuff(name, *values, &block)
43
+ # @Stuffs ||= {}
44
+ # @Stuffs[name] ||= CfnDsl::#{symbol}Definition.new(*values)
45
+ # @Stuffs[name].instance_eval &block if block_given?
46
+ # return @Stuffs[name]
47
+ # end
48
+ #
49
+ # The effect of this is that you can then create named sub-objects
50
+ # from the main object. The sub objects get stuffed into a container
51
+ # on the main object, and the block is then evaluated in the context
52
+ # of the new object.
53
+ #
31
54
  def dsl_content_object(*symbols)
32
- ##
33
- # Create object declaration methods.
34
- #
35
- # Usage:
36
- # Class Something
37
- # dsl_content_object :Stuff
38
- # end
39
- #
40
- # Generates methods like this:
41
- #
42
- # def Stuff(name, *values, &block)
43
- # @Stuffs ||= {}
44
- # @Stuffs[name] ||= CfnDsl::#{symbol}Definition.new(*values)
45
- # @Stuffs[name].instance_eval &block if block_given?
46
- # return @Stuffs[name]
47
- # end
48
- #
49
- # The effect of this is that you can then create named sub-objects
50
- # from the main object. The sub objects get stuffed into a container
51
- # on the main object, and the block is then evaluated in the context
52
- # of the new object.
53
- #
54
55
  symbols.each do |symbol|
55
- plural = CfnDsl::Plurals::pluralize(symbol) # @@plurals[symbol] || "#{symbol}s"
56
+ plural = CfnDsl::Plurals.pluralize(symbol) # @@plurals[symbol] || "#{symbol}s"
56
57
  pluralvar = "@#{plural}".to_sym
57
- definition_class = CfnDsl.const_get( "#{symbol}Definition" )
58
+ definition_class = CfnDsl.const_get("#{symbol}Definition")
58
59
  class_eval do
59
- CfnDsl::methodNames(symbol) do |method|
60
- define_method(method) do |name,*values,&block|
60
+ CfnDsl.method_names(symbol) do |method|
61
+ define_method(method) do |name, *values, &block|
61
62
  name = name.to_s
62
- hash = instance_variable_get( pluralvar )
63
- if( ! hash ) then
63
+ hash = instance_variable_get(pluralvar)
64
+ unless hash
64
65
  hash = {}
65
- instance_variable_set( pluralvar, hash )
66
+ instance_variable_set(pluralvar, hash)
66
67
  end
67
68
  hash[name] ||= definition_class.new(*values)
68
- hash[name].instance_eval &block if block
69
+ hash[name].instance_eval(&block) if block
69
70
  return hash[name]
70
- end
71
+ end
71
72
  end
72
73
  end
73
74
  end
data/lib/cfndsl/names.rb CHANGED
@@ -1,16 +1,16 @@
1
+ # Method name helper
1
2
  module CfnDsl
2
- ##
3
3
  # iterates through the the valid case-insensitive names
4
- # for "name".
5
- def self.methodNames(name, &block)
6
- if block then
4
+ # for "name"
5
+ def self.method_names(name, &block)
6
+ if block
7
7
  name_str = name.to_s
8
8
  yield name_str.to_sym
9
9
  n = name_str.dup
10
10
  n[0] = n[0].swapcase
11
11
  yield n.to_sym
12
12
  else
13
- result = [name.dup,name.dup]
13
+ result = [name.dup, name.dup]
14
14
  result[1][0] = result[1][0].swapcase
15
15
  return result
16
16
  end
@@ -0,0 +1,173 @@
1
+ require 'cfndsl/jsonable'
2
+ require 'cfndsl/names'
3
+ require 'cfndsl/aws/types'
4
+ require 'cfndsl/os/types'
5
+
6
+ module CfnDsl
7
+ # Handles the overall template object
8
+ # rubocop:disable Metrics/ClassLength
9
+ class OrchestrationTemplate < JSONable
10
+ dsl_attr_setter :AWSTemplateFormatVersion, :Description
11
+ dsl_content_object :Condition, :Parameter, :Output, :Resource, :Mapping
12
+
13
+ def initialize
14
+ @AWSTemplateFormatVersion = '2010-09-09'
15
+ end
16
+
17
+ GlobalRefs = {
18
+ 'AWS::NotificationARNs' => 1,
19
+ 'AWS::Region' => 1,
20
+ 'AWS::StackId' => 1,
21
+ 'AWS::StackName' => 1,
22
+ 'AWS::AccountId' => 1,
23
+ 'AWS::NoValue' => 1
24
+ }.freeze
25
+
26
+ # rubocop:disable Metrics/PerceivedComplexity
27
+ def valid_ref?(ref, origin = nil)
28
+ ref = ref.to_s
29
+ origin = origin.to_s if origin
30
+
31
+ return true if GlobalRefs.key?(ref)
32
+
33
+ return true if @Parameters && @Parameters.key?(ref)
34
+
35
+ if @Resources.key?(ref)
36
+ return !origin || !@_resource_refs || !@_resource_refs[ref] || !@_resource_refs[ref].key?(origin)
37
+ end
38
+
39
+ false
40
+ end
41
+ # rubocop:enable Metrics/PerceivedComplexity
42
+
43
+ def check_refs
44
+ invalids = check_resource_refs + check_output_refs
45
+
46
+ invalids.empty? ? nil : invalids
47
+ end
48
+
49
+ def check_resource_refs
50
+ invalids = []
51
+
52
+ @_resource_refs = {}
53
+ if @Resources
54
+ @Resources.keys.each do |resource|
55
+ @_resource_refs[resource.to_s] = @Resources[resource].build_references({})
56
+ end
57
+ @_resource_refs.keys.each do |origin|
58
+ @_resource_refs[origin].keys.each do |ref|
59
+ invalids.push "Invalid Reference: Resource #{origin} refers to #{ref}" unless valid_ref?(ref, origin)
60
+ end
61
+ end
62
+ end
63
+
64
+ invalids
65
+ end
66
+
67
+ def check_output_refs
68
+ invalids = []
69
+
70
+ output_refs = {}
71
+ if @Outputs
72
+ @Outputs.keys.each do |resource|
73
+ output_refs[resource.to_s] = @Outputs[resource].build_references({})
74
+ end
75
+ output_refs.keys.each do |origin|
76
+ output_refs[origin].keys.each do |ref|
77
+ invalids.push "Invalid Reference: Output #{origin} refers to #{ref}" unless valid_ref?(ref)
78
+ end
79
+ end
80
+ end
81
+
82
+ invalids
83
+ end
84
+
85
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
86
+ def self.create_types
87
+ names = {}
88
+ nametypes = {}
89
+ template_types['Resources'].each_pair do |name, type|
90
+ # Subclass ResourceDefintion and generate property methods
91
+ klass = Class.new(CfnDsl::ResourceDefinition)
92
+ klassname = name.split('::').join('_')
93
+ type_module.const_set(klassname, klass)
94
+ type['Properties'].each_pair do |pname, ptype|
95
+ if ptype.instance_of?(String)
96
+ create_klass = type_module.const_get(ptype)
97
+
98
+ klass.class_eval do
99
+ CfnDsl.method_names(pname) do |method|
100
+ define_method(method) do |*values, &block|
101
+ values.push create_klass.new if values.empty?
102
+
103
+ @Properties ||= {}
104
+ @Properties[pname] = CfnDsl::PropertyDefinition.new(*values)
105
+ @Properties[pname].value.instance_eval(&block) if block
106
+ @Properties[pname].value
107
+ end
108
+ end
109
+ end
110
+ else
111
+ # Array version
112
+ sing_name = CfnDsl::Plurals.singularize(pname)
113
+ create_klass = type_module.const_get(ptype[0])
114
+ klass.class_eval do
115
+ CfnDsl.method_names(pname) do |method|
116
+ define_method(method) do |*values, &block|
117
+ values.push [] if values.empty?
118
+ @Properties ||= {}
119
+ @Properties[pname] ||= PropertyDefinition.new(*values)
120
+ @Properties[pname].value.instance_eval(&block) if block
121
+ @Properties[pname].value
122
+ end
123
+ end
124
+
125
+ CfnDsl.method_names(sing_name) do |method|
126
+ define_method(method) do |value = nil, &block|
127
+ @Properties ||= {}
128
+ @Properties[pname] ||= PropertyDefinition.new([])
129
+ value = create_klass.new unless value
130
+ @Properties[pname].value.push value
131
+ value.instance_eval(&block) if block
132
+ value
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ parts = name.split('::')
139
+ until parts.empty?
140
+ abreve_name = parts.join('_')
141
+ if names.key?(abreve_name)
142
+ # this only happens if there is an ambiguity
143
+ names[abreve_name] = nil
144
+ else
145
+ names[abreve_name] = type_module.const_get(klassname)
146
+ nametypes[abreve_name] = name
147
+ end
148
+ parts.shift
149
+ end
150
+ end
151
+
152
+ # Define property setter methods for each of the unambiguous type names
153
+ names.each_pair do |typename, type|
154
+ next unless type
155
+
156
+ class_eval do
157
+ CfnDsl.method_names(typename) do |method|
158
+ define_method(method) do |name, *values, &block|
159
+ name = name.to_s
160
+ @Resources ||= {}
161
+ resource = @Resources[name] ||= type.new(*values)
162
+ resource.instance_eval(&block) if block
163
+ resource.instance_variable_set('@Type', nametypes[typename])
164
+ resource
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
171
+ end
172
+ # rubocop:enable Metrics/ClassLength
173
+ end
@@ -0,0 +1,16 @@
1
+ require 'cfndsl/orchestration_template'
2
+
3
+ module CfnDsl
4
+ # Heat Templates
5
+ class HeatTemplate < OrchestrationTemplate
6
+ def self.template_types
7
+ CfnDsl::OS::Types::Types_Internal
8
+ end
9
+
10
+ def self.type_module
11
+ CfnDsl::OS::Types
12
+ end
13
+
14
+ create_types
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ require 'cfndsl/types'
2
+
3
+ module CfnDsl
4
+ module OS
5
+ # Open Stack Types
6
+ module Types
7
+ TYPE_PREFIX = 'os'.freeze
8
+ class Type < JSONable; end
9
+ include CfnDsl::Types
10
+ end
11
+ end
12
+ end
@@ -211,7 +211,7 @@ Resources:
211
211
  #property.
212
212
  rolling_updates : RollingUpdateMap
213
213
  # Policy for rolling updates for this scaling group.
214
- # Can be updated without replacement.
214
+ # Can be updated without replacement.
215
215
  # Optional property.
216
216
  "OS::Heat::CWLiteAlarm" :
217
217
  Properties:
@@ -246,8 +246,8 @@ Resources:
246
246
  LaunchConfigurationName: String
247
247
  LoadBalancerNames: [ String ]
248
248
  Size: Integer
249
- Tags: [ EC2Tag ]
250
- Attributes:
249
+ Tags: [ EC2Tag ]
250
+ Attributes:
251
251
  InstanceList: String
252
252
 
253
253
  "OS::Heat::MultipartMime" :
@@ -279,7 +279,7 @@ Resources:
279
279
  # Required property.
280
280
 
281
281
  #Attributes:
282
- # refs: String
282
+ # refs: String
283
283
  # # A list of resource IDs for the resources in the group
284
284
 
285
285
  "OS::Heat::ScalingPolicy" :
@@ -421,7 +421,7 @@ Resources:
421
421
  #ow the server should signal to heat with the deployment output values. CFN_SIGNAL will allow an HTTP POST to a CFN keypair signed URL. HEAT_SIGNAL will allow calls to the Heat API resource-signal using the provided keystone credentials. NO_SIGNAL will result in the resource going to the COMPLETE state without waiting for any signal.
422
422
  #pdates cause replacement.
423
423
  #ptional property, defaults to “CFN_SIGNAL”.
424
- #llowed values: CFN_SIGNAL, HEAT_SIGNAL, NO_SIGNAL
424
+ #llowed values: CFN_SIGNAL, HEAT_SIGNAL, NO_SIGNAL
425
425
  Attributes:
426
426
  deploy_status_code: String
427
427
  #eturned status code from the configuration execution
@@ -915,7 +915,7 @@ Resources:
915
915
  #The unique identifier of the tenant owning the ipsec site connection.
916
916
  vpnservice_id: String
917
917
  #The unique identifier of vpn service associated with the ipsec site connection.
918
-
918
+
919
919
  "OS::Neutron::LoadBalancer" :
920
920
  Properties:
921
921
  members : [ String ]
@@ -1642,7 +1642,7 @@ Resources:
1642
1642
  #The URL of the container.
1643
1643
 
1644
1644
  "OS::Trove::Instance" :
1645
- Properties:
1645
+ Properties:
1646
1646
  availability_zone : String
1647
1647
  #Name of the availability zone for DB instance.
1648
1648
  #Updates cause replacement.
@@ -1811,12 +1811,12 @@ Resources:
1811
1811
  VpcId: String
1812
1812
  Tags: [ EC2Tag ]
1813
1813
  "AWS::EC2::SecurityGroup" :
1814
- Properties:
1814
+ Properties:
1815
1815
  GroupDescription: String
1816
1816
  SecurityGroupIngress: [ EC2SecurityGroupRule ]
1817
1817
  SecurityGroupEgress: [ EC2SecurityGroupRule ]
1818
1818
  VpcId: String
1819
- "AWS::EC2::Subnet" :
1819
+ "AWS::EC2::Subnet" :
1820
1820
  Properties:
1821
1821
  AvailabilityZone: String
1822
1822
  VpcId: String
@@ -1909,7 +1909,7 @@ Types:
1909
1909
  Integer: Integer
1910
1910
  Number: Number
1911
1911
  List: [ String ]
1912
- RollingUpdateMap:
1912
+ RollingUpdateMap:
1913
1913
  max_batch_size : Number
1914
1914
  # The maximum number of resources to replace at once.
1915
1915
  # Updates cause replacement.
@@ -2314,7 +2314,7 @@ Types:
2314
2314
  #The name of the index document.
2315
2315
  #Updates cause replacement.
2316
2316
  #Optional property.
2317
- #BlockDeviceMapping:
2317
+ #BlockDeviceMapping:
2318
2318
  # DeviceName: String
2319
2319
  # VirtualName: String
2320
2320
  #Ebs: BlockDeviceTemplate