lono 0.3.3 → 0.3.4

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