cfndsl 0.4.4 → 0.5.0.pre

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.
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