Class: Cfer::Auster::CferEvaluator

Inherits:
Object
  • Object
show all
Includes:
Logging::Mixin
Defined in:
lib/cfer/auster/cfer_evaluator.rb

Instance Method Summary collapse

Methods included from Logging::Mixin

#logger

Constructor Details

#initialize(path:, stack_name:, parameters:, metadata:, client_options: {}, stack_options: {}) ⇒ CferEvaluator

Returns a new instance of CferEvaluator.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/cfer/auster/cfer_evaluator.rb', line 22

def initialize(path:, stack_name:, parameters:, metadata:, client_options: {}, stack_options: {})
  raise "path must be a String" unless path.is_a?(String)
  raise "path must be a directory" unless File.directory?(path)

  raise "stack_name must be a String" unless stack_name.is_a?(String)

  raise "parameters must be a Hash" unless parameters.is_a?(Hash)

  parameters[:AusterOptions] ||= {}

  @stack_name = stack_name
  @stack_options = stack_options
  @cfer_client = Cfer::Cfn::Client.new(client_options.merge(stack_name: stack_name, region: parameters[:AWSRegion]))
  @cfer_stack = Cfer::Core::Stack.new(
    stack_options.merge(
      client: @cfer_client, include_base: path, parameters: parameters,
      force_s3: !!parameters[:AusterOptions][:S3Path],
      s3_path: parameters[:AusterOptions][:S3Path]
    )
  )

  require_rb = File.join(path, "require.rb")
  parameters_rb = File.join(path, "parameters.rb")
  outputs_rb = File.join(path, "outputs.rb")

  global_helpers_dir = File.join(path, "../../../cfer-helpers")
  global_helpers = Dir["#{global_helpers_dir}/**/*.rb"].reject { |f| File.basename(f).start_with?("_") }
  helpers_dir = File.join(path, "helpers")
  helpers = Dir["#{helpers_dir}/**/*.rb"].reject { |f| File.basename(f).start_with?("_") }
  defs_dir = File.join(path, "defs")

  @cfer_stack.extend Cfer::Auster::CferHelpers
  @cfer_stack.build_from_block do
    self[:Metadata][:Auster] = 

    global_helpers.each do |helper_file|
      eval_file helper_file
    end

    helpers.each do |helper_file|
      eval_file helper_file
    end

    [require_rb, parameters_rb, outputs_rb].each do |file|
      f = file.gsub(path, ".")
      include_template f if File.file?(file)
    end

    Dir["#{defs_dir}/**/*.rb"].each do |def_file|
      f = def_file.gsub(path, ".")
      include_template f
    end
  end
end

Instance Method Details

#converge!(block: true) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/cfer/auster/cfer_evaluator.rb', line 77

def converge!(block: true)
  # because it isn't actually redundant...
  # rubocop:disable Style/RedundantBegin
  begin
    @cfer_stack.converge!(@stack_options)
    tail! if block
  rescue Aws::CloudFormation::Errors::ValidationError => err
    if err.message == "No updates are to be performed."
      logger.info "CloudFormation has no updates to perform."
    else
      logger.error "Error (#{err.class.name}) in converge: #{err.message}"
      raise err
    end
  end
end

#destroy!(block: true) ⇒ Object



93
94
95
96
# File 'lib/cfer/auster/cfer_evaluator.rb', line 93

def destroy!(block: true)
  @cfer_client.delete_stack(stack_name: @stack_name)
  tail! if block
end

#generate_jsonObject



120
121
122
# File 'lib/cfer/auster/cfer_evaluator.rb', line 120

def generate_json
  JSON.pretty_generate(@cfer_stack)
end

#tail!(throw_if_failed: true) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/cfer/auster/cfer_evaluator.rb', line 98

def tail!(throw_if_failed: true)
  tail_start = DateTime.now
  has_shown_bar = false
  has_failed = false

  @cfer_client.tail(number: 0, follow: true) do |event|
    has_failed = true if event.timestamp >= tail_start && event.resource_status.include?("FAILED")
    if event.timestamp >= tail_start && !has_shown_bar
      logger.info "CFN >> ----- CURRENT RUN START -----"
      has_failed = false
      has_shown_bar = true
    end
    logger.info "CFN >> %-30s %-40s %-20s %s" % [
      event.resource_status, event.resource_type,
      event.logical_resource_id, event.resource_status_reason
    ]
  end

  raise "Operation failed. Please check the log." if has_failed && throw_if_failed
  nil
end