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.
- checksums.yaml +5 -13
- data/.rubocop.yml +23 -0
- data/Gemfile +4 -0
- data/Rakefile +19 -17
- data/bin/cfndsl +20 -20
- data/cfndsl.gemspec +16 -15
- data/lib/cfndsl.rb +62 -68
- data/lib/cfndsl/aws/cloud_formation_template.rb +16 -0
- data/lib/cfndsl/aws/types.rb +12 -0
- data/lib/cfndsl/{aws_types.yaml → aws/types.yaml} +0 -0
- data/lib/cfndsl/{Conditions.rb → conditions.rb} +5 -7
- data/lib/cfndsl/creation_policy.rb +21 -0
- data/lib/cfndsl/errors.rb +29 -0
- data/lib/cfndsl/generate_types.rb +154 -0
- data/lib/cfndsl/jsonable.rb +214 -0
- data/lib/cfndsl/mappings.rb +23 -0
- data/lib/cfndsl/metadata.rb +16 -0
- data/lib/cfndsl/module.rb +52 -51
- data/lib/cfndsl/names.rb +5 -5
- data/lib/cfndsl/orchestration_template.rb +173 -0
- data/lib/cfndsl/os/heat_template.rb +16 -0
- data/lib/cfndsl/os/types.rb +12 -0
- data/lib/cfndsl/{os_types.yaml → os/types.yaml} +11 -11
- data/lib/cfndsl/{Outputs.rb → outputs.rb} +3 -4
- data/lib/cfndsl/{Parameters.rb → parameters.rb} +12 -13
- data/lib/cfndsl/plurals.rb +34 -0
- data/lib/cfndsl/properties.rb +21 -0
- data/lib/cfndsl/rake_task.rb +9 -7
- data/lib/cfndsl/ref_check.rb +44 -0
- data/lib/cfndsl/{Resources.rb → resources.rb} +13 -15
- data/lib/cfndsl/types.rb +151 -0
- data/lib/cfndsl/update_policy.rb +25 -0
- data/lib/cfndsl/version.rb +1 -1
- data/sample/autoscale.rb +152 -158
- data/sample/autoscale2.rb +151 -155
- data/sample/circular.rb +30 -33
- data/sample/codedeploy.rb +35 -36
- data/sample/config_service.rb +120 -0
- data/sample/ecs.rb +39 -39
- data/sample/iam_policies.rb +82 -0
- data/sample/lambda.rb +20 -24
- data/sample/s3.rb +11 -11
- data/sample/t1.rb +7 -9
- data/sample/vpc_example.rb +50 -0
- data/sample/vpc_with_vpn_example.rb +97 -0
- data/spec/cfndsl_spec.rb +22 -11
- data/spec/fixtures/heattest.rb +13 -14
- data/spec/fixtures/test.rb +56 -53
- metadata +36 -30
- data/lib/cfndsl/CloudFormationTemplate.rb +0 -267
- data/lib/cfndsl/CreationPolicy.rb +0 -25
- data/lib/cfndsl/Errors.rb +0 -31
- data/lib/cfndsl/JSONable.rb +0 -235
- data/lib/cfndsl/Mappings.rb +0 -25
- data/lib/cfndsl/Metadata.rb +0 -22
- data/lib/cfndsl/Plurals.rb +0 -35
- data/lib/cfndsl/Properties.rb +0 -25
- data/lib/cfndsl/RefCheck.rb +0 -48
- data/lib/cfndsl/Types.rb +0 -309
- data/lib/cfndsl/UpdatePolicy.rb +0 -29
- data/sample/config-service.rb +0 -119
- data/sample/iam-policies.rb +0 -82
- data/sample/vpc-example.rb +0 -51
- data/sample/vpc-with-vpn-example.rb +0 -97
data/lib/cfndsl/JSONable.rb
DELETED
@@ -1,235 +0,0 @@
|
|
1
|
-
require 'cfndsl/Errors'
|
2
|
-
require 'cfndsl/RefCheck'
|
3
|
-
|
4
|
-
module CfnDsl
|
5
|
-
module Functions
|
6
|
-
##
|
7
|
-
# These functions are available anywhere inside
|
8
|
-
# a block for a JSONable object.
|
9
|
-
def Ref(value)
|
10
|
-
##
|
11
|
-
# Equivalent to the CloudFormation template built in function Ref
|
12
|
-
RefDefinition.new(value)
|
13
|
-
end
|
14
|
-
|
15
|
-
def FnBase64( value )
|
16
|
-
##
|
17
|
-
# Equivalent to the CloudFormation template built in function Fn::Base64
|
18
|
-
Fn.new("Base64", value);
|
19
|
-
end
|
20
|
-
|
21
|
-
def FnFindInMap( map, key, value)
|
22
|
-
##
|
23
|
-
# Equivalent to the CloudFormation template built in function Fn::FindInMap
|
24
|
-
Fn.new("FindInMap", [map,key,value] )
|
25
|
-
end
|
26
|
-
|
27
|
-
def FnGetAtt(logicalResource, attribute)
|
28
|
-
##
|
29
|
-
# Equivalent to the CloudFormation template built in function Fn::GetAtt
|
30
|
-
Fn.new( "GetAtt", [logicalResource, attribute] )
|
31
|
-
end
|
32
|
-
|
33
|
-
def FnGetAZs(region)
|
34
|
-
##
|
35
|
-
# Equivalent to the CloudFormation template built in function Fn::GetAZs
|
36
|
-
Fn.new("GetAZs", region)
|
37
|
-
end
|
38
|
-
|
39
|
-
def FnJoin(string, array)
|
40
|
-
##
|
41
|
-
# Equivalent to the CloudFormation template built in function Fn::Join
|
42
|
-
Fn.new("Join", [ string, array] )
|
43
|
-
end
|
44
|
-
|
45
|
-
def FnAnd(array)
|
46
|
-
##
|
47
|
-
# Equivalent to the CloudFormation template built in function Fn::And
|
48
|
-
if !array || array.count < 2 || array.count > 10
|
49
|
-
raise 'The array passed to Fn::And must have at least 2 elements and no more than 10'
|
50
|
-
end
|
51
|
-
Fn.new("And", array)
|
52
|
-
end
|
53
|
-
|
54
|
-
def FnEquals(value1, value2)
|
55
|
-
##
|
56
|
-
# Equivalent to the Cloudformation template built in function Fn::Equals
|
57
|
-
Fn.new("Equals", [value1, value2])
|
58
|
-
end
|
59
|
-
|
60
|
-
def FnIf(conditionName, trueValue, falseValue)
|
61
|
-
##
|
62
|
-
# Equivalent to the Cloudformation template built in function Fn::If
|
63
|
-
Fn.new("If", [conditionName, trueValue, falseValue])
|
64
|
-
end
|
65
|
-
|
66
|
-
def FnNot(value)
|
67
|
-
##
|
68
|
-
# Equivalent to the Cloudformation template built in function Fn::Not
|
69
|
-
Fn.new("Not", value)
|
70
|
-
end
|
71
|
-
|
72
|
-
def FnOr(array)
|
73
|
-
##
|
74
|
-
# Equivalent to the CloudFormation template built in function Fn::Or
|
75
|
-
if !array || array.count < 2 || array.count > 10
|
76
|
-
raise 'The array passed to Fn::Or must have at least 2 elements and no more than 10'
|
77
|
-
end
|
78
|
-
Fn.new("Or", array)
|
79
|
-
end
|
80
|
-
|
81
|
-
def FnSelect(index, array)
|
82
|
-
##
|
83
|
-
# Equivalent to the CloudFormation template built in function Fn::Select
|
84
|
-
Fn.new("Select", [ index, array] )
|
85
|
-
end
|
86
|
-
|
87
|
-
def FnFormat(string, *arguments)
|
88
|
-
##
|
89
|
-
# Usage
|
90
|
-
# FnFormat( "This is a %0. It is 100%% %1","test", "effective")
|
91
|
-
# or
|
92
|
-
# FnFormat( "This is a %{test}. It is 100%% %{effective},
|
93
|
-
# :test=>"test",
|
94
|
-
# :effective=>"effective")
|
95
|
-
#
|
96
|
-
# These will each generate a call to Fn::Join that when
|
97
|
-
# evaluated will produce the string "This is a test. It is 100%
|
98
|
-
# effective."
|
99
|
-
#
|
100
|
-
# Think of this as %0,%1, etc in the format string being replaced by the
|
101
|
-
# corresponding arguments given after the format string. '%%' is replaced
|
102
|
-
# by the '%' character.
|
103
|
-
#
|
104
|
-
# The actual Fn::Join call corresponding to the above FnFormat call would be
|
105
|
-
# {"Fn::Join": ["",["This is a ","test",". It is 100","%"," ","effective"]]}
|
106
|
-
#
|
107
|
-
# If no arguments are given, or if a hash is given and the format
|
108
|
-
# variable name does not exist in the hash, it is used as a Ref
|
109
|
-
# to an existing resource or parameter.
|
110
|
-
#
|
111
|
-
array = [];
|
112
|
-
if(arguments.length == 0 ||
|
113
|
-
(arguments.length == 1 && arguments[0].instance_of?(Hash)) ) then
|
114
|
-
hash = arguments[0] || {}
|
115
|
-
string.scan( /(.*?)(%(%|\{([\w:]+)\})|\z)/m ) do |x,y|
|
116
|
-
array.push $1 if $1 && $1 != ""
|
117
|
-
if( $3 == '%' ) then
|
118
|
-
array.push '%'
|
119
|
-
elsif( $3 ) then
|
120
|
-
array.push hash[ $4 ] || hash[ $4.to_sym ] || Ref( $4 )
|
121
|
-
end
|
122
|
-
end
|
123
|
-
else
|
124
|
-
string.scan( /(.*?)(%(%|\d+)|\z)/m ) do |x,y|
|
125
|
-
array.push $1 if $1 && $1 != ""
|
126
|
-
if( $3 == '%' ) then
|
127
|
-
array.push '%'
|
128
|
-
elsif( $3 ) then
|
129
|
-
array.push arguments[ $3.to_i ]
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
Fn.new("Join", ["", array])
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
class JSONable
|
138
|
-
##
|
139
|
-
# This is the base class for just about everything useful in the
|
140
|
-
# DSL. It knows how to turn DSL Objects into the corresponding
|
141
|
-
# json, and it lets you create new built in function objects
|
142
|
-
# from inside the context of a dsl object.
|
143
|
-
|
144
|
-
include Functions
|
145
|
-
extend Functions
|
146
|
-
include RefCheck
|
147
|
-
|
148
|
-
def to_json(*a)
|
149
|
-
##
|
150
|
-
# Use instance variables to build a json object. Instance
|
151
|
-
# variables that begin with a single underscore are elided.
|
152
|
-
# Instance variables that begin with two underscores have one of
|
153
|
-
# them removed.
|
154
|
-
hash = {}
|
155
|
-
self.instance_variables.each do |var|
|
156
|
-
name = var[1..-1]
|
157
|
-
|
158
|
-
if( name =~ /^__/ ) then
|
159
|
-
# if a variable starts with double underscore, strip one off
|
160
|
-
name = name[1..-1]
|
161
|
-
elsif( name =~ /^_/ ) then
|
162
|
-
# Hide variables that start with single underscore
|
163
|
-
name = nil
|
164
|
-
end
|
165
|
-
|
166
|
-
hash[name] = self.instance_variable_get var if name
|
167
|
-
end
|
168
|
-
hash.to_json(*a)
|
169
|
-
end
|
170
|
-
|
171
|
-
def ref_children
|
172
|
-
return self.instance_variables.map { |var| self.instance_variable_get var }
|
173
|
-
end
|
174
|
-
|
175
|
-
def declare(&block)
|
176
|
-
self.instance_eval &block if block_given?
|
177
|
-
end
|
178
|
-
|
179
|
-
def method_missing(meth, *args, &block)
|
180
|
-
error = "Undefined symbol: #{meth}"
|
181
|
-
error = "#{error}(" + args.inspect[1..-2] + ")" unless args.empty?
|
182
|
-
error = "#{error}\n\nTry '#{titleize(meth)}' instead" if incorrect_capitalization?(meth)
|
183
|
-
CfnDsl::Errors.error(error, 1)
|
184
|
-
end
|
185
|
-
|
186
|
-
def incorrect_capitalization?(method)
|
187
|
-
method != titleize(method) && respond_to?(titleize(method))
|
188
|
-
end
|
189
|
-
|
190
|
-
def titleize(method)
|
191
|
-
method.to_s.clone.tap do |m|
|
192
|
-
m[0] = m[0,1].upcase
|
193
|
-
end.to_sym
|
194
|
-
end
|
195
|
-
|
196
|
-
end
|
197
|
-
|
198
|
-
|
199
|
-
class Fn < JSONable
|
200
|
-
##
|
201
|
-
# Handles all of the Fn:: objects
|
202
|
-
def initialize( function, argument, refs=[] )
|
203
|
-
@function = function
|
204
|
-
@argument = argument
|
205
|
-
@_refs = refs
|
206
|
-
end
|
207
|
-
|
208
|
-
def to_json(*a)
|
209
|
-
hash = {}
|
210
|
-
hash["Fn::#{@function}"] = @argument
|
211
|
-
hash.to_json(*a)
|
212
|
-
end
|
213
|
-
|
214
|
-
def get_references()
|
215
|
-
return @_refs
|
216
|
-
end
|
217
|
-
|
218
|
-
def ref_children
|
219
|
-
return [@argument]
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
class RefDefinition < JSONable
|
224
|
-
##
|
225
|
-
# Handles the Ref objects
|
226
|
-
def initialize( value )
|
227
|
-
@Ref = value
|
228
|
-
end
|
229
|
-
|
230
|
-
def get_references()
|
231
|
-
[@Ref]
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
end
|
data/lib/cfndsl/Mappings.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'cfndsl/JSONable'
|
2
|
-
|
3
|
-
module CfnDsl
|
4
|
-
class MappingDefinition < JSONable
|
5
|
-
##
|
6
|
-
# Handles mapping objects
|
7
|
-
#
|
8
|
-
# Usage:
|
9
|
-
# Mapping("AWSRegionArch2AMI", {
|
10
|
-
# "us-east-1" => { "32" => "ami-6411e20d", "64" => "ami-7a11e213" },
|
11
|
-
# "us-west-1" => { "32" => "ami-c9c7978c", "64" => "ami-cfc7978a" },
|
12
|
-
# "eu-west-1" => { "32" => "ami-37c2f643", "64" => "ami-31c2f645" },
|
13
|
-
# "ap-southeast-1" => { "32" => "ami-66f28c34", "64" => "ami-60f28c32" },
|
14
|
-
# "ap-northeast-1" => { "32" => "ami-9c03a89d", "64" => "ami-a003a8a1" }
|
15
|
-
# })
|
16
|
-
|
17
|
-
def initialize(value)
|
18
|
-
@value = value
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_json(*a)
|
22
|
-
@value.to_json(*a)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/cfndsl/Metadata.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'cfndsl/JSONable'
|
2
|
-
|
3
|
-
module CfnDsl
|
4
|
-
|
5
|
-
class MetadataDefinition < JSONable
|
6
|
-
##
|
7
|
-
# Handles Metadata objects
|
8
|
-
def initialize(value)
|
9
|
-
@value = value;
|
10
|
-
end
|
11
|
-
|
12
|
-
def value
|
13
|
-
return @value
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_json(*a)
|
17
|
-
@value.to_json(*a)
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
data/lib/cfndsl/Plurals.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
module CfnDsl
|
2
|
-
module Plurals
|
3
|
-
##
|
4
|
-
# Plural names for lists of content objects
|
5
|
-
#
|
6
|
-
|
7
|
-
@@plurals = {
|
8
|
-
"Metadata" => "Metadata",
|
9
|
-
"Property" => "Properties",
|
10
|
-
"Policy" => "Policies",
|
11
|
-
"PolicyDocument" => "PolicyDocument",
|
12
|
-
"AssumeRolePolicyDocument" => "AssumeRolePolicyDocument",
|
13
|
-
"SecurityGroupIngress" => "SecurityGroupIngress",
|
14
|
-
"SecurityGroupEgress" => "SecurityGroupEgress",
|
15
|
-
"DBSecurityGroupIngress" => "DBSecurityGroupIngress",
|
16
|
-
"UpdatePolicy" => "UpdatePolicy",
|
17
|
-
"CreationPolicy" => "CreationPolicy"
|
18
|
-
}
|
19
|
-
|
20
|
-
@@singles = {}
|
21
|
-
@@plurals.each_pair { |key,val| @@singles[val] = key }
|
22
|
-
|
23
|
-
def self.pluralize(name)
|
24
|
-
name = name.to_s
|
25
|
-
return @@plurals[name] if( @@plurals.has_key? name )
|
26
|
-
return "#{name}s"
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.singularize(name)
|
30
|
-
name = name.to_s
|
31
|
-
return @@singles[name] if( @@singles.has_key? name )
|
32
|
-
return name[0..-2]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/cfndsl/Properties.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'cfndsl/JSONable'
|
2
|
-
|
3
|
-
module CfnDsl
|
4
|
-
class PropertyDefinition < JSONable
|
5
|
-
##
|
6
|
-
# Handles property objects for Resources
|
7
|
-
#
|
8
|
-
# Usage
|
9
|
-
# Resource("aaa") {
|
10
|
-
# Property("propName", "propValue" )
|
11
|
-
# }
|
12
|
-
#
|
13
|
-
def initialize(value)
|
14
|
-
@value = value;
|
15
|
-
end
|
16
|
-
|
17
|
-
def value
|
18
|
-
return @value
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_json(*a)
|
22
|
-
@value.to_json(*a)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/cfndsl/RefCheck.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
|
2
|
-
module RefCheck
|
3
|
-
##
|
4
|
-
# This module defines some methods for walking the reference tree
|
5
|
-
# of various objects.
|
6
|
-
#
|
7
|
-
def references(refs)
|
8
|
-
##
|
9
|
-
# Build up a set of references.
|
10
|
-
#
|
11
|
-
raise "Circular reference" if @_visited
|
12
|
-
|
13
|
-
@_visited = true
|
14
|
-
|
15
|
-
if( self.respond_to?(:get_references ) ) then
|
16
|
-
self.get_references.each do |ref|
|
17
|
-
refs[ref.to_s] = 1
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
self.ref_children.each do |elem|
|
22
|
-
elem.references(refs) if elem.respond_to?(:references)
|
23
|
-
end
|
24
|
-
|
25
|
-
@_visited = nil
|
26
|
-
|
27
|
-
return refs
|
28
|
-
end
|
29
|
-
|
30
|
-
def ref_children
|
31
|
-
return []
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
class Array
|
37
|
-
include RefCheck
|
38
|
-
def ref_children
|
39
|
-
return self
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
class Hash
|
44
|
-
include RefCheck
|
45
|
-
def ref_children
|
46
|
-
return self.values
|
47
|
-
end
|
48
|
-
end
|
data/lib/cfndsl/Types.rb
DELETED
@@ -1,309 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'cfndsl/JSONable'
|
3
|
-
require 'cfndsl/Plurals'
|
4
|
-
require 'cfndsl/names'
|
5
|
-
|
6
|
-
module CfnDsl
|
7
|
-
module AWSTypes
|
8
|
-
aws_types = YAML::load( File.open( "#{File.dirname(__FILE__)}/aws_types.yaml") );
|
9
|
-
AWSTypes.const_set( "AWS_Types", aws_types);
|
10
|
-
|
11
|
-
# Do a little sanity checking - all of the types referenced in Resources
|
12
|
-
# should be represented in Types
|
13
|
-
aws_types["Resources"].keys.each do |resource_name|
|
14
|
-
#puts resource_name
|
15
|
-
|
16
|
-
resource = aws_types["Resources"][resource_name]
|
17
|
-
resource.values.each do |thing|
|
18
|
-
thing.values.each do |type|
|
19
|
-
if( type.kind_of? Array ) then
|
20
|
-
type.each do | type |
|
21
|
-
puts "unknown type #{type}" unless aws_types["Types"].has_key? type
|
22
|
-
end
|
23
|
-
else
|
24
|
-
puts "unknown type #{type}" unless aws_types["Types"].has_key? type
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# All of the type values should also be references
|
31
|
-
|
32
|
-
aws_types["Types"].values do |type|
|
33
|
-
if( type.respond_to? :values) then
|
34
|
-
type.values.each do |tv|
|
35
|
-
puts "unknown type #{tv}" unless aws_types["Types"].has_key? tv
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# declare classes for all of the types with named methods for setting the values
|
41
|
-
class AWSType < JSONable
|
42
|
-
end
|
43
|
-
|
44
|
-
classes = {}
|
45
|
-
|
46
|
-
# Go through and declare all of the types first
|
47
|
-
aws_types["Types"].each_key do |typename|
|
48
|
-
if( ! AWSTypes.const_defined? typename ) then
|
49
|
-
klass = AWSTypes.const_set( typename, Class.new(AWSType ) )
|
50
|
-
classes[typename] = klass
|
51
|
-
else
|
52
|
-
classes[typename] = AWSTypes.const_get(typename)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Now go through them again and define attribute setter methods
|
57
|
-
classes.each_pair do |typename,type|
|
58
|
-
#puts typename
|
59
|
-
typeval = aws_types["Types"][typename]
|
60
|
-
if( typeval.respond_to? :each_pair ) then
|
61
|
-
typeval.each_pair do |attr_name, attr_type|
|
62
|
-
if( attr_type.kind_of? Array ) then
|
63
|
-
klass = CfnDsl::AWSTypes.const_get( attr_type[0] )
|
64
|
-
variable = "@#{attr_name}".to_sym
|
65
|
-
|
66
|
-
method = CfnDsl::Plurals::singularize(attr_name)
|
67
|
-
methods = attr_name
|
68
|
-
all_methods = CfnDsl::methodNames(method) +
|
69
|
-
CfnDsl::methodNames(methods)
|
70
|
-
type.class_eval do
|
71
|
-
all_methods.each do |method_name|
|
72
|
-
define_method(method_name) do | value=nil, *rest, &block|
|
73
|
-
existing = instance_variable_get( variable )
|
74
|
-
# For no-op invocations, get out now
|
75
|
-
return existing if value.nil? and rest.length == 0 and ! block
|
76
|
-
|
77
|
-
# We are going to modify the value in some
|
78
|
-
# way, make sure that we have an array to mess
|
79
|
-
# with if we start with nothing
|
80
|
-
if( !existing ) then
|
81
|
-
existing = instance_variable_set( variable, [] )
|
82
|
-
end
|
83
|
-
|
84
|
-
# special case for just a block, no args
|
85
|
-
if( value.nil? and rest.length == 0 and block ) then
|
86
|
-
val = klass.new
|
87
|
-
existing.push val
|
88
|
-
value.instance_eval &block(val)
|
89
|
-
return existing
|
90
|
-
end
|
91
|
-
|
92
|
-
# Glue all of our parameters together into
|
93
|
-
# a giant array - flattening one level deep, if needed
|
94
|
-
array_params = []
|
95
|
-
if( value.kind_of? Array) then
|
96
|
-
value.each {|x| array_params.push x}
|
97
|
-
else
|
98
|
-
array_params.push value
|
99
|
-
end
|
100
|
-
if( rest.length > 0) then
|
101
|
-
rest.each do |v|
|
102
|
-
if( v.kind_of? Array ) then
|
103
|
-
array_params += rest
|
104
|
-
else
|
105
|
-
array_params.push v
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# Here, if we were given multiple arguments either
|
111
|
-
# as method [a,b,c], method(a,b,c), or even
|
112
|
-
# method( a, [b], c) we end up with
|
113
|
-
# array_params = [a,b,c]
|
114
|
-
#
|
115
|
-
# array_params will have at least one item
|
116
|
-
# unless the user did something like pass in
|
117
|
-
# a bunch of empty arrays.
|
118
|
-
if block then
|
119
|
-
array_params.each do |val|
|
120
|
-
value = klass.new
|
121
|
-
existing.push value
|
122
|
-
value.instance_eval &block(val) if block
|
123
|
-
end
|
124
|
-
else
|
125
|
-
# List of parameters with no block -
|
126
|
-
# hope that the user knows what he is
|
127
|
-
# doing and stuff them into our existing
|
128
|
-
# array
|
129
|
-
array_params.each do |val|
|
130
|
-
existing.push value
|
131
|
-
end
|
132
|
-
end
|
133
|
-
return existing
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
else
|
138
|
-
klass = CfnDsl::AWSTypes.const_get( attr_type );
|
139
|
-
variable = "@#{attr_name}".to_sym
|
140
|
-
|
141
|
-
type.class_eval do
|
142
|
-
CfnDsl::methodNames(attr_name) do |method|
|
143
|
-
define_method(method) do | value=nil, *rest, &block |
|
144
|
-
value ||= klass.new
|
145
|
-
instance_variable_set( variable, value )
|
146
|
-
value.instance_eval &block if block
|
147
|
-
value
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
module OSTypes
|
158
|
-
os_types = YAML::load( File.open( "#{File.dirname(__FILE__)}/os_types.yaml") );
|
159
|
-
OSTypes.const_set( "OS_Types", os_types);
|
160
|
-
|
161
|
-
# Do a little sanity checking - all of the types referenced in Resources
|
162
|
-
# should be represented in Types
|
163
|
-
os_types["Resources"].keys.each do |resource_name|
|
164
|
-
#puts resource_name
|
165
|
-
|
166
|
-
resource = os_types["Resources"][resource_name]
|
167
|
-
resource.values.each do |thing|
|
168
|
-
thing.values.each do |type|
|
169
|
-
if( type.kind_of? Array ) then
|
170
|
-
type.each do | type |
|
171
|
-
puts "unknown type #{type}" unless os_types["Types"].has_key? type
|
172
|
-
end
|
173
|
-
else
|
174
|
-
puts "unknown type #{type}" unless os_types["Types"].has_key? type
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
# All of the type values should also be references
|
181
|
-
|
182
|
-
os_types["Types"].values do |type|
|
183
|
-
if( type.respond_to? :values) then
|
184
|
-
type.values.each do |tv|
|
185
|
-
puts "unknown type #{tv}" unless os_types["Types"].has_key? tv
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
# declare classes for all of the types with named methods for setting the values
|
191
|
-
class OSType < JSONable
|
192
|
-
end
|
193
|
-
|
194
|
-
classes = {}
|
195
|
-
|
196
|
-
# Go through and declare all of the types first
|
197
|
-
os_types["Types"].each_key do |typename|
|
198
|
-
if( ! OSTypes.const_defined? typename ) then
|
199
|
-
klass = OSTypes.const_set( typename, Class.new(OSType ) )
|
200
|
-
classes[typename] = klass
|
201
|
-
else
|
202
|
-
classes[typename] = OSTypes.const_get(typename)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
# Now go through them again and define attribute setter methods
|
207
|
-
classes.each_pair do |typename,type|
|
208
|
-
#puts typename
|
209
|
-
typeval = os_types["Types"][typename]
|
210
|
-
if( typeval.respond_to? :each_pair ) then
|
211
|
-
typeval.each_pair do |attr_name, attr_type|
|
212
|
-
if( attr_type.kind_of? Array ) then
|
213
|
-
klass = CfnDsl::OSTypes.const_get( attr_type[0] )
|
214
|
-
variable = "@#{attr_name}".to_sym
|
215
|
-
|
216
|
-
method = CfnDsl::Plurals::singularize(attr_name)
|
217
|
-
methods = attr_name
|
218
|
-
all_methods = CfnDsl::methodNames(method) +
|
219
|
-
CfnDsl::methodNames(methods)
|
220
|
-
type.class_eval do
|
221
|
-
all_methods.each do |method_name|
|
222
|
-
define_method(method_name) do | value=nil, *rest, &block|
|
223
|
-
existing = instance_variable_get( variable )
|
224
|
-
# For no-op invocations, get out now
|
225
|
-
return existing if value.nil? and rest.length == 0 and ! block
|
226
|
-
|
227
|
-
# We are going to modify the value in some
|
228
|
-
# way, make sure that we have an array to mess
|
229
|
-
# with if we start with nothing
|
230
|
-
if( !existing ) then
|
231
|
-
existing = instance_variable_set( variable, [] )
|
232
|
-
end
|
233
|
-
|
234
|
-
# special case for just a block, no args
|
235
|
-
if( value.nil? and rest.length == 0 and block ) then
|
236
|
-
val = klass.new
|
237
|
-
existing.push val
|
238
|
-
value.instance_eval &block(val)
|
239
|
-
return existin
|
240
|
-
end
|
241
|
-
|
242
|
-
# Glue all of our parameters together into
|
243
|
-
# a giant array - flattening one level deep, if needed
|
244
|
-
array_params = []
|
245
|
-
if( value.kind_of? Array) then
|
246
|
-
value.each {|x| array_params.push x}
|
247
|
-
else
|
248
|
-
array_params.push value
|
249
|
-
end
|
250
|
-
if( rest.length > 0) then
|
251
|
-
rest.each do |v|
|
252
|
-
if( v.kind_of? Array ) then
|
253
|
-
array_params += rest
|
254
|
-
else
|
255
|
-
array_params.push v
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
# Here, if we were given multiple arguments either
|
261
|
-
# as method [a,b,c], method(a,b,c), or even
|
262
|
-
# method( a, [b], c) we end up with
|
263
|
-
# array_params = [a,b,c]
|
264
|
-
#
|
265
|
-
# array_params will have at least one item
|
266
|
-
# unless the user did something like pass in
|
267
|
-
# a bunch of empty arrays.
|
268
|
-
if block then
|
269
|
-
array_params.each do |val|
|
270
|
-
value = klass.new
|
271
|
-
existing.push value
|
272
|
-
value.instance_eval &block(val) if block
|
273
|
-
end
|
274
|
-
else
|
275
|
-
# List of parameters with no block -
|
276
|
-
# hope that the user knows what he is
|
277
|
-
# doing and stuff them into our existing
|
278
|
-
# array
|
279
|
-
array_params.each do |val|
|
280
|
-
existing.push value
|
281
|
-
end
|
282
|
-
end
|
283
|
-
return existing
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
|
-
else
|
288
|
-
klass = CfnDsl::OSTypes.const_get( attr_type );
|
289
|
-
variable = "@#{attr_name}".to_sym
|
290
|
-
|
291
|
-
type.class_eval do
|
292
|
-
CfnDsl::methodNames(attr_name) do |method|
|
293
|
-
define_method(method) do | value=nil, *rest, &block |
|
294
|
-
value ||= klass.new
|
295
|
-
instance_variable_set( variable, value )
|
296
|
-
value.instance_eval &block if block
|
297
|
-
value
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|
302
|
-
end
|
303
|
-
end
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
|
308
|
-
end
|
309
|
-
|