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