terrafying 1.7.4 → 1.7.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'base64'
3
5
  require 'erb'
@@ -6,40 +8,36 @@ require 'deep_merge'
6
8
  require 'terrafying/aws'
7
9
 
8
10
  module Terrafying
9
-
10
- ARG_PLACEHOLDER = "ARG_PLACEHOLDER123"
11
+ ARG_PLACEHOLDER = 'ARG_PLACEHOLDER123'
11
12
 
12
13
  class Ref
13
-
14
14
  def fn_call(fn, *args)
15
- if args.length == 0
16
- args = [ARG_PLACEHOLDER]
17
- end
15
+ args = [ARG_PLACEHOLDER] if args.empty?
18
16
  FnRef.new(fn: fn, args: args, ref: self)
19
17
  end
20
18
 
21
19
  def downcase
22
- fn_call("lower")
20
+ fn_call('lower')
23
21
  end
24
22
 
25
23
  def strip
26
- fn_call("trimspace")
24
+ fn_call('trimspace')
27
25
  end
28
26
 
29
27
  def split(separator)
30
- fn_call("split", separator, ARG_PLACEHOLDER)
28
+ fn_call('split', separator, ARG_PLACEHOLDER)
31
29
  end
32
30
 
33
- def slice(idx, length=0)
31
+ def slice(idx, length = 0)
34
32
  if length != 0
35
- fn_call("slice", ARG_PLACEHOLDER, idx, idx+length)
33
+ fn_call('slice', ARG_PLACEHOLDER, idx, idx + length)
36
34
  else
37
- fn_call("element", ARG_PLACEHOLDER, idx)
35
+ fn_call('element', ARG_PLACEHOLDER, idx)
38
36
  end
39
37
  end
40
38
 
41
39
  def realise
42
- ""
40
+ ''
43
41
  end
44
42
 
45
43
  def to_s
@@ -47,15 +45,15 @@ module Terrafying
47
45
  end
48
46
 
49
47
  def to_str
50
- self.to_s
48
+ to_s
51
49
  end
52
50
 
53
51
  def <=>(other)
54
- self.to_s <=> other.to_s
52
+ to_s <=> other.to_s
55
53
  end
56
54
 
57
55
  def ==(other)
58
- self.to_s == other.to_s
56
+ to_s == other.to_s
59
57
  end
60
58
 
61
59
  def [](key)
@@ -66,18 +64,17 @@ module Terrafying
66
64
  end
67
65
  end
68
66
 
69
- def []=(k, v)
67
+ def []=(_k, _v)
70
68
  raise "You can't set a value this way"
71
69
  end
72
-
73
70
  end
74
71
 
75
72
  class RootRef < Ref
76
73
  def initialize(
77
- kind: :resource,
78
- type: "",
79
- name:
80
- )
74
+ kind: :resource,
75
+ type: '',
76
+ name:
77
+ )
81
78
  @kind = kind
82
79
  @type = type
83
80
  @name = name
@@ -85,16 +82,14 @@ module Terrafying
85
82
 
86
83
  def realise
87
84
  type = [@type]
88
- if @kind != :resource
89
- type = [@kind, @type]
90
- end
85
+ type = [@kind, @type] if @kind != :resource
91
86
 
92
- (type + [@name]).reject(&:empty?).join(".")
87
+ (type + [@name]).reject(&:empty?).join('.')
93
88
  end
94
89
 
95
90
  def fn_call(fn, *args)
96
91
  if @kind == :resource
97
- self["id"].fn_call(fn, *args)
92
+ self['id'].fn_call(fn, *args)
98
93
  else
99
94
  super
100
95
  end
@@ -111,9 +106,9 @@ module Terrafying
111
106
 
112
107
  class AttributeRef < Ref
113
108
  def initialize(
114
- ref:,
115
- key:
116
- )
109
+ ref:,
110
+ key:
111
+ )
117
112
  @ref = ref
118
113
  @key = key
119
114
  end
@@ -125,9 +120,9 @@ module Terrafying
125
120
 
126
121
  class IndexRef < Ref
127
122
  def initialize(
128
- ref:,
129
- idx:
130
- )
123
+ ref:,
124
+ idx:
125
+ )
131
126
  @ref = ref
132
127
  @idx = idx
133
128
  end
@@ -139,10 +134,10 @@ module Terrafying
139
134
 
140
135
  class FnRef < Ref
141
136
  def initialize(
142
- ref:,
143
- fn:,
144
- args: []
145
- )
137
+ ref:,
138
+ fn:,
139
+ args: []
140
+ )
146
141
  @ref = ref
147
142
  @fn = fn
148
143
  @args = args
@@ -150,7 +145,7 @@ module Terrafying
150
145
 
151
146
  def realise
152
147
  ref = @ref.realise
153
- args = @args.map { |arg|
148
+ args = @args.map do |arg|
154
149
  if arg == ARG_PLACEHOLDER
155
150
  ref
156
151
  elsif arg.is_a? String
@@ -158,19 +153,18 @@ module Terrafying
158
153
  else
159
154
  arg
160
155
  end
161
- }.join(", ")
156
+ end.join(', ')
162
157
 
163
158
  "#{@fn}(#{args})"
164
159
  end
165
160
  end
166
161
 
167
162
  class Context
168
-
169
- REGION = ENV.fetch("AWS_REGION", "eu-west-1")
163
+ REGION = ENV.fetch('AWS_REGION', 'eu-west-1')
170
164
 
171
165
  PROVIDER_DEFAULTS = {
172
166
  aws: { region: REGION }
173
- }
167
+ }.freeze
174
168
 
175
169
  def self.bundle(&block)
176
170
  ctx = Context.new
@@ -182,7 +176,7 @@ module Terrafying
182
176
 
183
177
  def initialize
184
178
  @output = {
185
- "resource" => {}
179
+ 'resource' => {}
186
180
  }
187
181
  @children = []
188
182
  end
@@ -195,6 +189,7 @@ module Terrafying
195
189
  key = provider_key(name, spec)
196
190
  @providers ||= {}
197
191
  raise "Duplicate provider configuration detected for #{key}" if key_exists_spec_differs(key, name, spec)
192
+
198
193
  @providers[key] = { name.to_s => spec }
199
194
  @output['provider'] = @providers.values
200
195
  key
@@ -209,37 +204,39 @@ module Terrafying
209
204
  end
210
205
 
211
206
  def local(name, value)
212
- @output["locals"] ||= {}
207
+ @output['locals'] ||= {}
213
208
 
214
- raise "Local already exists #{name.to_s}" if @output["locals"].has_key? name.to_s
209
+ raise "Local already exists #{name}" if @output['locals'].key? name.to_s
215
210
 
216
- @output["locals"][name.to_s] = value
211
+ @output['locals'][name.to_s] = value
217
212
  RootRef.new(kind: :local, name: name)
218
213
  end
219
214
 
220
215
  def var(name, spec)
221
- @output["variable"] ||= {}
216
+ @output['variable'] ||= {}
222
217
 
223
- raise "Var already exists #{name.to_s}" if @output["variable"].has_key? name.to_s
218
+ raise "Var already exists #{name}" if @output['variable'].key? name.to_s
224
219
 
225
- @output["variable"][name.to_s] = spec
220
+ @output['variable'][name.to_s] = spec
226
221
  RootRef.new(kind: :var, name: name)
227
222
  end
228
223
 
229
224
  def data(type, name, spec)
230
- @output["data"] ||= {}
231
- @output["data"][type.to_s] ||= {}
225
+ @output['data'] ||= {}
226
+ @output['data'][type.to_s] ||= {}
227
+
228
+ raise "Data already exists #{type}.#{name}" if @output['data'][type.to_s].key? name.to_s
232
229
 
233
- raise "Data already exists #{type.to_s}.#{name.to_s}" if @output["data"][type.to_s].has_key? name.to_s
234
- @output["data"][type.to_s][name.to_s] = spec
230
+ @output['data'][type.to_s][name.to_s] = spec
235
231
  RootRef.new(kind: :data, type: type, name: name)
236
232
  end
237
233
 
238
234
  def resource(type, name, attributes)
239
- @output["resource"][type.to_s] ||= {}
235
+ @output['resource'][type.to_s] ||= {}
240
236
 
241
- raise "Resource already exists #{type.to_s}.#{name.to_s}" if @output["resource"][type.to_s].has_key? name.to_s
242
- @output["resource"][type.to_s][name.to_s] = attributes
237
+ raise "Resource already exists #{type}.#{name}" if @output['resource'][type.to_s].key? name.to_s
238
+
239
+ @output['resource'][type.to_s][name.to_s] = attributes
243
240
  RootRef.new(kind: :resource, type: type, name: name)
244
241
  end
245
242
 
@@ -255,8 +252,8 @@ module Terrafying
255
252
  @children.inject(@output) { |out, c| out.deep_merge(c.output_with_children) }
256
253
  end
257
254
 
258
- def id_of(type,name)
259
- output_of(type, name, "id")
255
+ def id_of(type, name)
256
+ output_of(type, name, 'id')
260
257
  end
261
258
 
262
259
  def output_of(type, name, key)
@@ -270,8 +267,8 @@ module Terrafying
270
267
  def resource_names
271
268
  out = output_with_children
272
269
  ret = []
273
- for type in out["resource"].keys
274
- for id in out["resource"][type].keys
270
+ out['resource'].keys.each do |type|
271
+ out['resource'][type].keys.each do |id|
275
272
  ret << "#{type}.#{id}"
276
273
  end
277
274
  end
@@ -281,8 +278,8 @@ module Terrafying
281
278
  def resources
282
279
  out = output_with_children
283
280
  ret = []
284
- for type in out["resource"].keys
285
- for id in out["resource"][type].keys
281
+ out['resource'].keys.each do |type|
282
+ out['resource'][type].keys.each do |id|
286
283
  ret << "${#{type}.#{id}.id}"
287
284
  end
288
285
  end
@@ -295,23 +292,21 @@ module Terrafying
295
292
  end
296
293
 
297
294
  def tf_safe(str)
298
- str.gsub(/[\.\s\/\?]/, "-")
295
+ str.gsub(%r{[\.\s/\?]}, '-')
299
296
  end
300
-
301
297
  end
302
298
 
303
299
  class RootContext < Context
304
-
305
300
  def initialize
306
301
  super
307
302
  @providers = {}
308
303
  end
309
304
 
310
305
  def backend(name, spec)
311
- @output["terraform"] = {
306
+ @output['terraform'] = {
312
307
  backend: {
313
- name => spec,
314
- },
308
+ name => spec
309
+ }
315
310
  }
316
311
  end
317
312
 
@@ -324,22 +319,19 @@ module Terrafying
324
319
  end
325
320
 
326
321
  def output_with_children
327
-
328
- PROVIDER_DEFAULTS.each { |name, spec|
329
- if not key_exists_spec_differs(provider_key(name, spec), name, spec)
322
+ PROVIDER_DEFAULTS.each do |name, spec|
323
+ unless key_exists_spec_differs(provider_key(name, spec), name, spec)
330
324
  provider(name, spec)
331
325
  end
332
- }
326
+ end
333
327
 
334
328
  super
335
329
  end
336
-
337
330
  end
338
331
 
339
332
  Generator = RootContext.new
340
333
 
341
334
  module DSL
342
-
343
335
  %w[
344
336
  add!
345
337
  aws
@@ -353,12 +345,10 @@ module Terrafying
353
345
  tf_safe
354
346
  id_of
355
347
  output_of
356
- ].each { |name|
357
- define_method(name) { |*args|
348
+ ].each do |name|
349
+ define_method(name) do |*args|
358
350
  Generator.send(name, *args)
359
- }
360
- }
361
-
351
+ end
352
+ end
362
353
  end
363
-
364
354
  end
@@ -1,16 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'terrafying/dynamodb/named_lock'
2
4
 
3
5
  module Terrafying
4
6
  module Locks
5
7
  class NoOpLock
6
8
  def acquire
7
- ""
9
+ ''
8
10
  end
11
+
9
12
  def steal
10
- ""
11
- end
12
- def release(lock_id)
13
+ ''
13
14
  end
15
+
16
+ def release(lock_id); end
14
17
  end
15
18
 
16
19
  def self.noop
@@ -20,6 +23,5 @@ module Terrafying
20
23
  def self.dynamodb(scope)
21
24
  Terrafying::DynamoDb::NamedLock.new(Terrafying::DynamoDb.config.lock_table, scope)
22
25
  end
23
-
24
26
  end
25
27
  end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'terrafying/dynamodb/state'
2
4
 
3
5
  module Terrafying
4
6
  module State
5
-
6
- STATE_FILENAME = "terraform.tfstate"
7
+ STATE_FILENAME = 'terraform.tfstate'
7
8
 
8
9
  def self.store(config)
9
10
  if LocalStateStore.has_local_state?(config)
@@ -20,7 +21,7 @@ module Terrafying
20
21
  def self.remote(config)
21
22
  Terrafying::DynamoDb::StateStore.new(config.scope)
22
23
  end
23
-
24
+
24
25
  class LocalStateStore
25
26
  def initialize(path)
26
27
  @path = LocalStateStore.state_path(path)
@@ -39,10 +40,11 @@ module Terrafying
39
40
  end
40
41
 
41
42
  def self.has_local_state?(config)
42
- File.exists?(state_path(config.path))
43
+ File.exist?(state_path(config.path))
43
44
  end
44
-
45
+
45
46
  private
47
+
46
48
  def self.state_path(path)
47
49
  File.join(File.dirname(path), STATE_FILENAME)
48
50
  end
@@ -1,32 +1,29 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  require 'yaml'
3
4
 
4
5
  def data_url_from_string(str)
5
6
  b64_contents = Base64.strict_encode64(str)
6
- return "data:;base64,#{b64_contents}"
7
+ "data:;base64,#{b64_contents}"
7
8
  end
8
9
 
9
10
  module Terrafying
10
-
11
11
  module Util
12
-
13
12
  def self.to_ignition(yaml)
14
- config = YAML.load(yaml)
13
+ config = YAML.safe_load(yaml)
14
+
15
+ if config.key?('storage') && config['storage'].key?('files')
16
+ files = config['storage']['files']
17
+ config['storage']['files'] = files.each do |file|
18
+ next unless file['contents'].is_a? String
15
19
 
16
- if config.has_key? "storage" and config["storage"].has_key? "files"
17
- files = config["storage"]["files"]
18
- config["storage"]["files"] = files.each { |file|
19
- if file["contents"].is_a? String
20
- file["contents"] = {
21
- source: data_url_from_string(file["contents"]),
22
- }
23
- end
24
- }
20
+ file['contents'] = {
21
+ source: data_url_from_string(file['contents'])
22
+ }
23
+ end
25
24
  end
26
25
 
27
26
  JSON.generate(config)
28
27
  end
29
-
30
28
  end
31
-
32
29
  end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Terrafying
2
- VERSION = "1.7.4" # will be inserted by Drone
3
- CLI_VERSION = "0.11.7"
4
+ VERSION = '1.7.5' # will be inserted by Drone
5
+ CLI_VERSION = '0.11.7'
4
6
  end
data/lib/terrafying.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fileutils'
2
4
  require 'logger'
3
5
  require 'pathname'
@@ -12,9 +14,7 @@ require 'terrafying/version'
12
14
  require 'terrafying/state'
13
15
 
14
16
  module Terrafying
15
-
16
17
  class Config
17
-
18
18
  attr_reader :path, :scope
19
19
 
20
20
  def initialize(path, options)
@@ -22,7 +22,7 @@ module Terrafying
22
22
  @options = options
23
23
  @scope = options[:scope] || scope_for_path(@path)
24
24
 
25
- $stderr.puts "Scope: #{@scope}"
25
+ warn "Scope: #{@scope}"
26
26
 
27
27
  load(path)
28
28
  end
@@ -97,9 +97,7 @@ module Terrafying
97
97
  with_lock do
98
98
  local = State.local(self)
99
99
  state = local.get
100
- if state
101
- State.remote(self).put(state)
102
- end
100
+ State.remote(self).put(state) if state
103
101
  local.delete
104
102
  end
105
103
  end
@@ -108,9 +106,7 @@ module Terrafying
108
106
  with_lock do
109
107
  remote = State.remote(self)
110
108
  state = remote.get
111
- if state
112
- State.local(self).put(state)
113
- end
109
+ State.local(self).put(state) if state
114
110
  end
115
111
  end
116
112
 
@@ -127,6 +123,7 @@ module Terrafying
127
123
  end
128
124
 
129
125
  private
126
+
130
127
  def lock_timeout
131
128
  "-lock-timeout=#{@options[:lock_timeout]}" if @options[:lock_timeout]
132
129
  end
@@ -144,24 +141,22 @@ module Terrafying
144
141
  end
145
142
 
146
143
  def with_config(&block)
147
- abort("***** ERROR: You must have terraform installed to run this gem *****") unless terraform_installed?
144
+ abort('***** ERROR: You must have terraform installed to run this gem *****') unless terraform_installed?
148
145
  check_version
149
- name = File.basename(@path, ".*")
146
+ name = File.basename(@path, '.*')
150
147
  dir = File.join(git_toplevel, 'tmp', SecureRandom.uuid)
151
- terraform_files = File.join(git_toplevel, ".terraform/")
152
- unless Dir.exists?(terraform_files)
148
+ terraform_files = File.join(git_toplevel, '.terraform/')
149
+ unless Dir.exist?(terraform_files)
153
150
  abort("***** ERROR: No .terraform directory found. Please run 'terraform init' to install plugins *****")
154
151
  end
155
152
  FileUtils.mkdir_p(dir)
156
- output_path = File.join(dir, name + ".tf.json")
153
+ output_path = File.join(dir, name + '.tf.json')
157
154
  FileUtils.cp_r(terraform_files, dir)
158
155
  Dir.chdir(dir) do
159
- begin
160
- File.write(output_path, Terrafying::Generator.pretty_generate)
161
- yield block
162
- ensure
163
- FileUtils.rm_rf(dir) unless @options[:keep]
164
- end
156
+ File.write(output_path, Terrafying::Generator.pretty_generate)
157
+ yield block
158
+ ensure
159
+ FileUtils.rm_rf(dir) unless @options[:keep]
165
160
  end
166
161
  end
167
162
 
@@ -191,31 +186,27 @@ module Terrafying
191
186
  end
192
187
 
193
188
  def with_state(opts, &block)
194
- if !@options[:dynamodb]
195
- return yield(block)
196
- end
189
+ return yield(block) unless @options[:dynamodb]
197
190
 
198
191
  store = State.store(self)
199
192
 
200
193
  begin
201
194
  state = store.get
202
195
  File.write(State::STATE_FILENAME, state) if state
203
- rescue => e
196
+ rescue StandardError => e
204
197
  raise "Error retrieving state for config #{self}: #{e}"
205
198
  end
206
199
 
207
200
  yield block
208
201
 
209
202
  begin
210
- if opts[:mode] == :update
211
- store.put(IO.read(State::STATE_FILENAME))
212
- end
213
- rescue => e
203
+ store.put(IO.read(State::STATE_FILENAME)) if opts[:mode] == :update
204
+ rescue StandardError => e
214
205
  raise "Error updating state for config #{self}: #{e}"
215
206
  end
216
207
  end
217
208
 
218
- def scope_for_path(path)
209
+ def scope_for_path(_path)
219
210
  top_level_path = Pathname.new(git_toplevel)
220
211
  Pathname.new(@path).relative_path_from(top_level_path).to_s
221
212
  end
@@ -224,6 +215,7 @@ module Terrafying
224
215
  @top_level ||= begin
225
216
  top_level = `git rev-parse --show-toplevel`
226
217
  raise "Unable to find .git directory top level for '#{@path}'" if top_level.empty?
218
+
227
219
  File.expand_path(top_level.chomp)
228
220
  end
229
221
  end
@@ -239,16 +231,16 @@ module Terrafying
239
231
  end
240
232
 
241
233
  def terraform_version
242
- `terraform -v`.split("\n").first.split("v").last
234
+ `terraform -v`.split("\n").first.split('v').last
243
235
  end
244
236
 
245
237
  def stream_command(cmd)
246
238
  IO.popen(cmd) do |io|
247
- while (line = io.gets) do
248
- puts line.gsub('\n', "\n").gsub('\\"', "\"")
239
+ while (line = io.gets)
240
+ puts line.gsub('\n', "\n").gsub('\\"', '"')
249
241
  end
250
242
  end
251
- return $?.exitstatus
243
+ $CHILD_STATUS.exitstatus
252
244
  end
253
245
 
254
246
  # Cross-platform way of finding an executable in the $PATH.
@@ -257,12 +249,12 @@ module Terrafying
257
249
  def which(cmd)
258
250
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
259
251
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
260
- exts.each { |ext|
252
+ exts.each do |ext|
261
253
  exe = File.join(path, "#{cmd}#{ext}")
262
254
  return exe if File.executable?(exe) && !File.directory?(exe)
263
- }
255
+ end
264
256
  end
265
- return nil
257
+ nil
266
258
  end
267
259
  end
268
260
  end