Class: Terraspace::Terraform::RemoteState::Fetcher
Constant Summary
collapse
- @@pull_successes =
{}
- @@download_shown =
false
Class Method Summary
collapse
Instance Method Summary
collapse
#logger
#cache_dirs, #dirs, #extract_stack_name, #local_paths, #mod_names, #select_stack?, #stack_names, #with_each_mod
#command_is?
Constructor Details
#initialize(parent, identifier, options = {}) ⇒ Fetcher
Returns a new instance of Fetcher.
8
9
10
11
12
13
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 8
def initialize(parent, identifier, options={})
@parent, @identifier, @options = parent, identifier, options
child_name, @output_key = identifier.split('.')
@child = Terraspace::Mod.new(child_name)
@child.resolved = @parent.resolved
end
|
Class Method Details
.flush! ⇒ Object
153
154
155
156
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 153
def flush!
@@pull_successes = {}
@@cache = {}
end
|
Instance Method Details
#bucket_not_found_error ⇒ Object
96
97
98
99
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 96
def bucket_not_found_error
@@pull_successes[cache_key] = false
@error_type = :bucket_not_found
end
|
#cache_key ⇒ Object
115
116
117
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 115
def cache_key
@child.name
end
|
#load ⇒ Object
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 101
def load
return self unless pull_success?
if @@cache[cache_key]
@outputs = @@cache[cache_key]
else
@outputs = @@cache[cache_key] = read_statefile_outputs
end
self
end
|
#log_message(msg) ⇒ Object
Using debug level because all the tfvar files always get evaluated. So dont want these messages to show up and be noisy unless debugging.
147
148
149
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 147
def log_message(msg)
logger.debug "DEBUG: #{msg}".color(:yellow)
end
|
#output ⇒ Object
22
23
24
25
26
27
28
29
30
31
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 22
def output
run
if pull_success?
pull_success_output
else
@error_type ||= :state_not_found error = output_error(@error_type)
OutputProxy.new(@child, nil, @options.merge(error: error))
end
end
|
#output_error(type) ⇒ Object
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 48
def output_error(type)
msg = case type
when :key_not_found
"Output #{@output_key} was not found for the #{@parent.name} tfvars file. Either #{@child.name} stack has not been deployed yet or it does not have this output: #{@output_key}. Also, if local backend is being used and has been removed/cleaned, then it will also result zero-byte state.json with the 'terraform state pull' used to download the terraform state and output will not be found."
when :state_not_found
"Output #{@output_key} could not be looked up for the #{@parent.name} tfvars file. #{@child.name} stack needs to be deployed"
when :bucket_not_found
"The bucket for the backend could not be found"
end
msg = "(#{msg})"
log_message(msg)
msg
end
|
#output_value ⇒ Object
42
43
44
45
46
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 42
def output_value
return unless @outputs.key?(@output_key)
result = @outputs.dig(@output_key)
result.dig("value") if result
end
|
#pull ⇒ Object
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 64
def pull
return if @@pull_successes[cache_key]
logger.debug "Downloading tfstate files for dependencies defined in tfvars..." unless @@download_shown || @options[:quiet]
@@download_shown = true
logger.debug "Downloading tfstate for stack: #{@child.name}"
success = init return unless success
FileUtils.mkdir_p(File.dirname(state_path))
command = "cd #{@child.cache_dir} && #{Terraspace.terraform_bin} state pull > #{state_path}"
logger.debug "=> #{command}"
success = system(command)
unless success
logger.info "Error running: #{command}".color(:red)
logger.info "Please fix the error before continuing"
end
@@pull_successes[cache_key] = success
end
|
#pull_success? ⇒ Boolean
124
125
126
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 124
def pull_success?
@@pull_successes[cache_key]
end
|
#pull_success_output ⇒ Object
33
34
35
36
37
38
39
40
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 33
def pull_success_output
if @outputs.key?(@output_key)
OutputProxy.new(@child, output_value, @options)
else
error = output_error(:key_not_found)
OutputProxy.new(@child, nil, @options.merge(error: error))
end
end
|
#read_statefile_outputs ⇒ Object
119
120
121
122
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 119
def read_statefile_outputs
data = JSON.load(IO.read(state_path))
data ? data['outputs'] : {}
end
|
#run ⇒ Object
15
16
17
18
19
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 15
def run
validate! pull
load
end
|
#state_path ⇒ Object
128
129
130
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 128
def state_path
"#{Terraspace.tmp_root}/remote_state/#{@child.build_dir}/state.json"
end
|
#validate! ⇒ Object
Note we already validate mod exist at the terraform_output helper. This is just in case that logic changes.
133
134
135
136
137
138
139
140
141
142
143
|
# File 'lib/terraspace/terraform/remote_state/fetcher.rb', line 133
def validate!
unless @child.exist?
logger.error "ERROR: stack #{@child.name} not found".color(:red)
exit 1
end
select = Terraspace::Compiler::Select.new(@child.name)
unless select.selected?
logger.error "ERROR: stack #{@child.name} is configured to not be included. IE: config.all.include_stacks or config.all.exclude_stacks".color(:red)
exit 1
end
end
|