lono 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
data/lib/lono/template.rb
CHANGED
@@ -96,26 +96,45 @@ module Lono
|
|
96
96
|
# Output:
|
97
97
|
# Array of parse positions
|
98
98
|
#
|
99
|
-
# The positions
|
100
|
-
#
|
99
|
+
# The positions of tokens taking into account when brackets start and close,
|
100
|
+
# handles nested brackets.
|
101
101
|
def bracket_positions(line)
|
102
102
|
positions,pair,count = [],[],0
|
103
|
+
|
103
104
|
line.split('').each_with_index do |char,i|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
pair << i if pair.empty?
|
106
|
+
|
107
|
+
first_pair_char = line[pair[0]]
|
108
|
+
if first_pair_char == '{' # object logic
|
109
|
+
if char == '{'
|
110
|
+
count += 1
|
111
|
+
end
|
109
112
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
+
if char == '}'
|
114
|
+
count -= 1
|
115
|
+
if count == 0
|
116
|
+
pair << i
|
117
|
+
positions << pair
|
118
|
+
pair = []
|
119
|
+
end
|
120
|
+
end
|
121
|
+
else # string logic
|
122
|
+
lookahead = line[i+1]
|
123
|
+
if lookahead == '{'
|
113
124
|
pair << i
|
114
125
|
positions << pair
|
115
126
|
pair = []
|
116
127
|
end
|
117
128
|
end
|
129
|
+
end # end of loop
|
130
|
+
|
131
|
+
# for string logic when lookahead does not contain a object token
|
132
|
+
# need to clear out what's left to match the final pair
|
133
|
+
if !pair.empty?
|
134
|
+
pair << line.size - 1
|
135
|
+
positions << pair
|
118
136
|
end
|
137
|
+
|
119
138
|
positions
|
120
139
|
end
|
121
140
|
|
@@ -125,8 +144,7 @@ module Lono
|
|
125
144
|
# Array - positions that can be use to determine what to parse
|
126
145
|
def parse_positions(line)
|
127
146
|
positions = bracket_positions(line)
|
128
|
-
|
129
|
-
positions.map {|pair| [pair[0],pair[1]+1]}.flatten
|
147
|
+
positions.flatten
|
130
148
|
end
|
131
149
|
|
132
150
|
# Input
|
@@ -143,29 +161,46 @@ module Lono
|
|
143
161
|
|
144
162
|
result = []
|
145
163
|
str = ''
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
# the
|
151
|
-
#
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
str = ''
|
164
|
+
until positions.empty?
|
165
|
+
left = positions.shift
|
166
|
+
right = positions.shift
|
167
|
+
token = line[left..right]
|
168
|
+
# if cfn object, add to the result set but after clearing out
|
169
|
+
# the temp str that is being built up when the token is just a string
|
170
|
+
if cfn_object?(token)
|
171
|
+
unless str.empty? # first token might be a object
|
172
|
+
result << str
|
173
|
+
str = ''
|
174
|
+
end
|
175
|
+
result << token
|
176
|
+
else
|
177
|
+
str << token # keeps building up the string
|
161
178
|
end
|
162
179
|
end
|
163
180
|
|
181
|
+
# at the of the loop there's a leftover string, unless the last token
|
182
|
+
# is an object
|
183
|
+
result << str unless str.empty?
|
184
|
+
|
164
185
|
result
|
165
186
|
end
|
166
187
|
|
188
|
+
def cfn_object?(s)
|
189
|
+
whitelist = %w[
|
190
|
+
Ref
|
191
|
+
Fn::FindInMap
|
192
|
+
Fn::Base64
|
193
|
+
Fn::GetAtt
|
194
|
+
Fn::GetAZs
|
195
|
+
Fn::Join
|
196
|
+
Fn::Select
|
197
|
+
]
|
198
|
+
whitelisted = !!whitelist.detect {|word| s.include?(word)}
|
199
|
+
whitelisted && s =~ /^{/ && s =~ /=>/
|
200
|
+
end
|
201
|
+
|
167
202
|
def recompose(decomposition)
|
168
|
-
decomposition.map { |s| (s
|
203
|
+
decomposition.map { |s| cfn_object?(s) ? eval(s) : s }
|
169
204
|
end
|
170
205
|
|
171
206
|
def evaluate(line)
|
data/lib/lono/version.rb
CHANGED
@@ -20,6 +20,29 @@ template "prod-api-app.json" do
|
|
20
20
|
)
|
21
21
|
end
|
22
22
|
|
23
|
+
template "prod-api-worker.json" do
|
24
|
+
env,app,role = name.sub('.json','').split('-')
|
25
|
+
source "app.json.erb"
|
26
|
+
variables(
|
27
|
+
:env => env,
|
28
|
+
:app => app,
|
29
|
+
:role => role,
|
30
|
+
:ami => "ami-123",
|
31
|
+
:instance_type => "m1.small",
|
32
|
+
:port => "80",
|
33
|
+
:high_threshold => "15",
|
34
|
+
:high_periods => "4",
|
35
|
+
:low_threshold => "5",
|
36
|
+
:low_periods => "10",
|
37
|
+
:max_size => "24",
|
38
|
+
:min_size => "6",
|
39
|
+
:down_adjustment => "-3",
|
40
|
+
:up_adjustment => "3",
|
41
|
+
:user_data_script => "ruby_script.rb.erb",
|
42
|
+
:ssl_cert => "arn:aws:iam::12345:server-certificate/wildcard"
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
23
46
|
template "prod-api-redis.json" do
|
24
47
|
env,app,role = name.sub('.json','').split('-')
|
25
48
|
source "db.json.erb"
|
data/spec/lib/lono_spec.rb
CHANGED
@@ -25,38 +25,54 @@ describe Lono do
|
|
25
25
|
template = Lono::Template.new("foo", block)
|
26
26
|
|
27
27
|
line = '0{2345}7'
|
28
|
-
template.bracket_positions(line).should == [[1,6]]
|
28
|
+
template.bracket_positions(line).should == [[0,0],[1,6],[7,7]]
|
29
29
|
line = '0{2}4{6}' # more than one bracket
|
30
|
-
template.bracket_positions(line).should == [[1,3],[5,7]]
|
30
|
+
template.bracket_positions(line).should == [[0,0],[1,3],[4,4],[5,7]]
|
31
31
|
line = '0{2}4{6{8}0}2' # nested brackets
|
32
|
-
template.bracket_positions(line).should == [[1,3],[5,11]]
|
33
|
-
|
34
|
-
line = '0{2=>5}7'
|
35
|
-
template.parse_positions(line).should == [1,7]
|
36
|
-
line = '0{2=>5}4{6=>{8=>9}}2' # nested brackets
|
37
|
-
template.parse_positions(line).should == [1, 7, 8, 19]
|
38
|
-
line = '0{2=>5}4{' # nested brackets
|
39
|
-
template.parse_positions(line).should == [1, 7]
|
32
|
+
template.bracket_positions(line).should == [[0,0],[1,3],[4,4],[5,11],[12,12]]
|
40
33
|
|
41
34
|
line = '{'
|
42
35
|
template.decompose(line).should == ['{']
|
43
36
|
|
44
|
-
|
45
|
-
|
46
|
-
line
|
47
|
-
|
37
|
+
##########################
|
38
|
+
line = '1{"Ref"=>"A"}{"Ref"=>"B"}'
|
39
|
+
template.decompose(line).should == ['1','{"Ref"=>"A"}','{"Ref"=>"B"}']
|
40
|
+
|
41
|
+
line = '{"Ref"=>"A"}{"Ref"=>"B"}2'
|
42
|
+
template.decompose(line).should == ['{"Ref"=>"A"}','{"Ref"=>"B"}','2']
|
43
|
+
|
44
|
+
line = '1{"Ref"=>"A"}{"Ref"=>"B"}2'
|
45
|
+
template.decompose(line).should == ['1','{"Ref"=>"A"}','{"Ref"=>"B"}','2']
|
46
|
+
|
47
|
+
line = '{"Ref"=>"A"}{"Ref"=>"B"}'
|
48
|
+
template.decompose(line).should == ['{"Ref"=>"A"}','{"Ref"=>"B"}']
|
49
|
+
|
50
|
+
line = 'Ref{"Ref"=>"B"}'
|
51
|
+
template.decompose(line).should == ['Ref','{"Ref"=>"B"}']
|
52
|
+
##############################
|
48
53
|
|
49
|
-
|
54
|
+
# only allow whitelist
|
55
|
+
line = 'a{b}{"foo"=>"bar"}h'
|
56
|
+
template.decompose(line).should == ['a{b}{"foo"=>"bar"}h']
|
57
|
+
|
58
|
+
line = 'a{b}{"Ref"=>"bar"}h'
|
59
|
+
template.decompose(line).should == ['a{b}','{"Ref"=>"bar"}','h']
|
60
|
+
line = 'a{"Ref"=>"bar"}c{"Ref"=>{"cat"=>"mouse"}}e' # nested brackets
|
61
|
+
template.decompose(line).should == ['a','{"Ref"=>"bar"}','c','{"Ref"=>{"cat"=>"mouse"}}','e']
|
62
|
+
|
63
|
+
line = 'test{"Ref"=>"world"}me' # nested brackets
|
50
64
|
decomposition = template.decompose(line)
|
51
65
|
result = template.recompose(decomposition)
|
52
|
-
result.should == ["test", {"
|
66
|
+
result.should == ["test", {"Ref" => "world"}, "me"]
|
53
67
|
|
54
|
-
line = 'test{"
|
55
|
-
template.transform(line).should == ["test", {"
|
56
|
-
line = '{"
|
57
|
-
template.transform(line).should == [{"
|
68
|
+
line = 'test{"Ref"=>"world"}me'
|
69
|
+
template.transform(line).should == ["test", {"Ref" => "world"}, "me\n"]
|
70
|
+
line = '{"Ref"=>"world"}'
|
71
|
+
template.transform(line).should == [{"Ref" => "world"}, "\n"]
|
58
72
|
line = '{'
|
59
73
|
template.transform(line).should == ["{\n"]
|
74
|
+
line = 'Ref{"Ref"=>"B"}'
|
75
|
+
template.transform(line).should == ['Ref',{"Ref"=>"B"}, "\n"]
|
60
76
|
end
|
61
77
|
end
|
62
78
|
|
@@ -133,6 +149,14 @@ describe Lono do
|
|
133
149
|
data.should == ["echo ", {"Fn::FindInMap" => ["A", "B", {"Ref"=>"AWS::StackName"}]}, " > /tmp/stack_name ; ", {"Ref"=>"Ami"}, "\n"]
|
134
150
|
end
|
135
151
|
|
152
|
+
it "should not transform user_data ruby scripts" do
|
153
|
+
raw = IO.read("#{@project}/output/prod-api-worker.json")
|
154
|
+
json = JSON.load(raw)
|
155
|
+
user_data = json['Resources']['LaunchConfig']['Properties']['UserData']['Fn::Base64']['Fn::Join'][1]
|
156
|
+
user_data.should include(%Q|ec2.tags.create(ec2.instances[my_instance_id], "Name", {:value => Facter.hostname})\n|)
|
157
|
+
user_data.should include(%Q{find_all{ |record_set| record_set[:name] == record_name }\n})
|
158
|
+
end
|
159
|
+
|
136
160
|
it "task should generate cloud formation templates" do
|
137
161
|
Lono::Task.generate(
|
138
162
|
:project_root => @project,
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lono
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -223,6 +223,7 @@ files:
|
|
223
223
|
- lib/starter_project/templates/user_data/app.sh.erb
|
224
224
|
- lib/starter_project/templates/user_data/db.sh.erb
|
225
225
|
- lib/starter_project/templates/user_data/db2.sh.erb
|
226
|
+
- lib/starter_project/templates/user_data/ruby_script.rb.erb
|
226
227
|
- lono.gemspec
|
227
228
|
- spec/fixtures/cfn.json
|
228
229
|
- spec/lib/lono_spec.rb
|