Class: Terradactyl::CLI

Inherits:
Thor
  • Object
show all
Includes:
Common
Defined in:
lib/terradactyl/cli.rb

Overview

rubocop:disable Metrics/ClassLength

Constant Summary

Constants included from Common

Terradactyl::Common::BORDER_CHAR, Terradactyl::Common::COLUMN_WIDTH

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Common

border, centre, config, cputs, dot_icon, print_content, print_crit, print_dot, print_header, print_line, print_message, print_ok, print_warning, required_versions_re, stack_icon, supported_revisions, tag, terraform_binary

Constructor Details

#initialize(*args) ⇒ CLI

Returns a new instance of CLI.



30
31
32
33
34
# File 'lib/terradactyl/cli.rb', line 30

def initialize(*args)
  # Hook ensures abort on stack errors
  at_exit { abort if Stacks.error? }
  super
end

Class Method Details

.exit_on_failure?Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/terradactyl/cli.rb', line 26

def self.exit_on_failure?
  true
end

Instance Method Details

#apply(name, base_override = nil) ⇒ Object



368
369
370
371
372
373
374
375
376
377
# File 'lib/terradactyl/cli.rb', line 368

def apply(name, base_override = nil)
  @stack ||= Stack.new(name, base_override)
  print_warning "Applying in #{base_folder_name(base_override)}: #{@stack.name}"
  if @stack.apply.zero?
    print_ok "Applied: #{@stack.name}"
  else
    Stacks.error!(@stack)
    print_crit "Failed to apply changes: #{@stack.name}"
  end
end

#audit(name, base_override = nil) ⇒ Object



335
336
337
338
339
340
341
# File 'lib/terradactyl/cli.rb', line 335

def audit(name, base_override = nil)
  plan(name, base_override)
  if (@stack = Stacks.dirty?(name))
    Stacks.error!(@stack)
    print_crit "Dirty stack: #{@stack.name}"
  end
end

#audit_all(base_override = nil) ⇒ Object



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/terradactyl/cli.rb', line 230

def audit_all(base_override = nil)
  report = { start: Time.now.to_json }
  print_header "Auditing ALL Stacks in #{base_folder_name(base_override)} ..."
  Stacks.load(base_override: base_override).each do |name|
    catch(:error) do
      clean(name, base_override)
      init(name, base_override)
      audit(name, base_override)
    end
    @stack = nil
  end
  report[:finish] = Time.now.to_json
  if options[:report]
    print_header 'Audit Report ...'
    generate_report(report)
  end
end

#clean(name, base_override = nil) ⇒ Object



359
360
361
362
363
364
# File 'lib/terradactyl/cli.rb', line 359

def clean(name, base_override = nil)
  @stack ||= Stack.new(name, base_override)
  print_warning "Cleaning in #{config.base_folder}: #{@stack.name}"
  @stack.clean
  print_ok "Cleaned: #{@stack.name}"
end

#clean_all(base_override = nil) ⇒ Object



206
207
208
209
210
211
212
# File 'lib/terradactyl/cli.rb', line 206

def clean_all(base_override = nil)
  print_header "Cleaning ALL Stacks in #{base_folder_name(base_override)} ..."
  Stacks.load(base_override: base_override).each do |name|
    clean(name, base_override)
    @stack = nil
  end
end

#defaultsObject



100
101
102
# File 'lib/terradactyl/cli.rb', line 100

def defaults
  puts config.to_h.to_yaml
end

#destroy(name, base_override = nil) ⇒ Object



394
395
396
397
398
399
400
401
402
403
# File 'lib/terradactyl/cli.rb', line 394

def destroy(name, base_override = nil)
  @stack ||= Stack.new(name, base_override)
  print_crit "Destroying in #{base_folder_name(base_override)}: #{@stack.name}"
  if @stack.destroy.zero?
    print_warning "Destroyed: #{@stack.name}"
  else
    Stacks.error!(@stack)
    print_crit "Failed to apply changes: #{@stack.name}"
  end
end

#fmt(name, base_override = nil) ⇒ Object



282
283
284
285
286
287
288
289
290
291
# File 'lib/terradactyl/cli.rb', line 282

def fmt(name, base_override = nil)
  @stack ||= Stack.new(name, base_override)
  print_warning "Formatting: #{@stack.name}"
  if @stack.fmt.zero?
    print_ok "Formatted: #{@stack.name}"
  else
    Stacks.error!(@stack)
    print_crit "Formatting failed: #{@stack.name}"
  end
end

#init(name, base_override = nil, backend: true) ⇒ Object

rubocop:disable Metrics/AbcSize



296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/terradactyl/cli.rb', line 296

def init(name, base_override = nil, backend: true)
  @stack ||= Stack.new(name, base_override)
  @stack.config.terraform.init.backend = backend

  print_ok "Initializing in #{base_folder_name(base_override)}: #{@stack.name}"
  if @stack.init.zero?
    print_ok "Initialized: #{@stack.name}"
  else
    Stacks.error!(@stack)
    print_crit "Initialization failed: #{@stack.name}"
    throw :error
  end
end

#install(component) ⇒ Object

rubocop:disable Metrics/AbcSize



433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/terradactyl/cli.rb', line 433

def install(component)
  case component.to_sym
  when :terraform
    print_warning "Installing: #{component}, version: #{options[:version]}"
    version = options[:version] == 'latest' ? terraform_latest : options[:version]
    Terradactyl::Terraform::VersionManager.reset!
    Terradactyl::Terraform::VersionManager.version = version
    Terradactyl::Terraform::VersionManager.install
    if Terradactyl::Terraform::VersionManager.binary
      print_ok "Installed: #{Terradactyl::Terraform::VersionManager.binary}"
    end
  else
    msg = %(Operation not supported -- I don't know how to install: #{component})
    print_crit msg
    exit 1
  end
end

#lint(name, base_override = nil) ⇒ Object



269
270
271
272
273
274
275
276
277
278
# File 'lib/terradactyl/cli.rb', line 269

def lint(name, base_override = nil)
  @stack ||= Stack.new(name, base_override)
  print_ok "Linting: #{@stack.name}"
  if @stack.lint.zero?
    print_ok "Formatting OK: #{@stack.name}"
  else
    Stacks.error!(@stack)
    print_warning "Bad Formatting: #{@stack.name}"
  end
end

#plan(name, base_override = nil) ⇒ Object



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/terradactyl/cli.rb', line 312

def plan(name, base_override = nil)
  @stack ||= Stack.new(name, base_override)
  print_ok "Planning in #{base_folder_name(base_override)}: #{@stack.name}"
  case @stack.plan
  when 0
    print_ok "No changes: #{@stack.name}"
  when 1
    Stacks.error!(@stack)
    print_crit "Plan failed: #{@stack.name}"
    @stack.print_error
    throw :error
  when 2
    Stacks.dirty!(@stack)
    print_warning "Changes detected: #{@stack.name}"
    @stack.print_plan
  else
    raise
  end
end

#plan_all(base_override = nil) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
# File 'lib/terradactyl/cli.rb', line 215

def plan_all(base_override = nil)
  print_header "Planning ALL Stacks in #{base_folder_name(base_override)} ..."
  Stacks.load(base_override: base_override).each do |name|
    catch(:error) do
      clean(name, base_override)
      init(name, base_override)
      plan(name, base_override)
    end
    @stack = nil
  end
end

#planpr(base_override = nil) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/terradactyl/cli.rb', line 126

def planpr(base_override = nil)
  print_header "SmartPlanning PR in #{base_folder_name(base_override)} ..."
  stacks = Stacks.load(
    filter: StacksPlanFilterGitDiffOriginBranch.new,
    base_override: base_override
  )
  validate_planpr(stacks).each do |name|
    clean(name, base_override)
    init(name, base_override)
    plan(name, base_override)
    @stack = nil
  end
end

#quickplan(name, base_override = nil) ⇒ Object



198
199
200
201
202
203
# File 'lib/terradactyl/cli.rb', line 198

def quickplan(name, base_override = nil)
  print_header "Quick planning #{name} ..."
  clean(name, base_override)
  init(name, base_override)
  plan(name, base_override)
end

#refresh(name, base_override = nil) ⇒ Object



381
382
383
384
385
386
387
388
389
390
# File 'lib/terradactyl/cli.rb', line 381

def refresh(name, base_override = nil)
  @stack ||= Stack.new(name, base_override)
  print_crit "Refreshing in #{base_folder_name(base_override)}: #{@stack.name}"
  if @stack.refresh.zero?
    print_warning "Refreshed: #{@stack.name}"
  else
    Stacks.error!(@stack)
    print_crit "Failed to refresh stack: #{@stack.name}"
  end
end

#smartapply(base_override = nil) ⇒ Object



156
157
158
159
160
161
162
163
164
165
# File 'lib/terradactyl/cli.rb', line 156

def smartapply(base_override = nil)
  print_header "SmartApplying Stacks in #{base_folder_name(base_override)} ..."
  stacks = Stacks.load(filter: StacksApplyFilterPrePlanned.new, base_override: base_override)
  print_warning 'No stacks contain plan files ...' unless stacks.any?
  stacks.each do |name|
    apply(name, base_override)
    @stack = nil
  end
  print_message "Total Stacks Modified: #{stacks.size}"
end

#smartplan(base_override = nil) ⇒ Object



142
143
144
145
146
147
148
149
150
151
# File 'lib/terradactyl/cli.rb', line 142

def smartplan(base_override = nil)
  print_header "SmartPlanning Stacks in #{base_folder_name(base_override)} ..."
  stacks = Stacks.load(filter: StacksPlanFilterGitDiffHead.new, base_override: base_override)
  validate_smartplan(stacks).each do |name|
    clean(name, base_override)
    init(name, base_override)
    plan(name, base_override)
    @stack = nil
  end
end

#smartrefresh(base_override = nil) ⇒ Object



170
171
172
173
174
175
176
177
178
179
# File 'lib/terradactyl/cli.rb', line 170

def smartrefresh(base_override = nil)
  print_header "SmartRefreshing Stacks in #{base_folder_name(base_override)} ..."
  stacks = Stacks.load(filter: StacksApplyFilterPrePlanned.new, base_override: base_override)
  print_warning 'No stacks contain plan files ...' unless stacks.any?
  stacks.each do |name|
    refresh(name, base_override)
    @stack = nil
  end
  print_message "Total Stacks Refreshed: #{stacks.size}"
end

#stacks(base_override = nil) ⇒ Object



105
106
107
108
109
110
# File 'lib/terradactyl/cli.rb', line 105

def stacks(base_override = nil)
  print_ok 'Stacks:'
  Stacks.load(base_override: base_override).each do |name|
    print_dot name.to_s
  end
end

#upgrade(name, base_override = nil) ⇒ Object



189
190
191
192
193
194
# File 'lib/terradactyl/cli.rb', line 189

def upgrade(name, base_override = nil)
  clean(name, base_override)
  init(name, base_override, backend: false)
  upgrade_stack(name, base_override)
  fmt(name, base_override)
end

#validate(name, base_override = nil) ⇒ Object



345
346
347
348
349
350
351
352
353
354
355
# File 'lib/terradactyl/cli.rb', line 345

def validate(name, base_override = nil)
  @stack ||= Stack.new(name, base_override)
  print_ok "Validating in #{base_folder_name(base_override)}: #{@stack.name}"
  if @stack.validate.zero?
    print_ok "Validated: #{@stack.name}"
  else
    Stacks.error!(@stack)
    print_crit "Validation failed: #{@stack.name}"
    throw :error
  end
end

#validate_all(base_override = nil) ⇒ Object



250
251
252
253
254
255
256
257
258
259
260
# File 'lib/terradactyl/cli.rb', line 250

def validate_all(base_override = nil)
  print_header "Validating ALL Stacks in #{base_folder_name(base_override)} ..."
  Stacks.load(base_override: base_override).each do |name|
    catch(:error) do
      clean(name, base_override)
      init(name, base_override)
      validate(name, base_override)
    end
    @stack = nil
  end
end

#versionObject



113
114
115
# File 'lib/terradactyl/cli.rb', line 113

def version
  print_message format('version: %<semver>s', semver: Terradactyl::VERSION)
end