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 indicate when the brackets start and close.
100
- # Handles nested brackets.
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
- if char == '{'
105
- count += 1
106
- pair << i if count == 1
107
- next
108
- end
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
- if char == '}'
111
- count -= 1
112
- if count == 0
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
- # add 1 to the element in the position pair to make parsing easier in decompose
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
- last_index = line.size - 1
147
- parse_position = positions.shift
148
-
149
- line.split('').each_with_index do |char,current_i|
150
- # the current item's creation will end when
151
- # the next item's index is reached
152
- # or the end of the line is reached
153
- str << char
154
- next_i = current_i + 1
155
- end_of_item = next_i == parse_position
156
- end_of_line = current_i == last_index
157
- if end_of_item or end_of_line
158
- parse_position = positions.shift
159
- result << str
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 =~ /^{/ && s =~ /=>/) ? eval(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
@@ -1,3 +1,3 @@
1
1
  module Lono
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
3
3
  end
@@ -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"
@@ -233,7 +233,8 @@
233
233
  "Fn::Base64": {
234
234
  "Fn::Join": [
235
235
  "",
236
- <%= user_data('app.sh.erb') %>
236
+ <% script = @user_data_script || 'app.sh.erb' %>
237
+ <%= user_data(script) %>
237
238
  ]
238
239
  }
239
240
  }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ec2.tags.create(ec2.instances[my_instance_id], "Name", {:value => Facter.hostname})
4
+
5
+ find_all{ |record_set| record_set[:name] == record_name }
@@ -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
- line = 'a{"foo"=>"bar"}h'
45
- template.decompose(line).should == ['a','{"foo"=>"bar"}','h']
46
- line = 'a{"foo"=>"bar"}c{"dog"=>{"cat"=>"mouse"}}e' # nested brackets
47
- template.decompose(line).should == ['a','{"foo"=>"bar"}','c','{"dog"=>{"cat"=>"mouse"}}','e']
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
- line = 'test{"hello"=>"world"}me' # nested brackets
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", {"hello" => "world"}, "me"]
66
+ result.should == ["test", {"Ref" => "world"}, "me"]
53
67
 
54
- line = 'test{"hello"=>"world"}me'
55
- template.transform(line).should == ["test", {"hello" => "world"}, "me\n"]
56
- line = '{"hello"=>"world"}'
57
- template.transform(line).should == [{"hello" => "world"}, "\n"]
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.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-18 00:00:00.000000000 Z
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