# frozen_string_literal: true module MuxTf module TerraformHelpers include PiotrbCliUtils::ShellHelpers def tf_force_unlock(id:) run_terraform(tf_prepare_command(['force-unlock', '-force', id], need_auth: true)) end def tf_apply(filename: nil, targets: []) args = [] args << filename if filename if targets && !targets.empty? targets.each do |target| args << "-target=#{target}" end end cmd = tf_prepare_command(['apply', *args], need_auth: true) run_terraform(cmd) end def tf_validate cmd = tf_prepare_command(['validate', '-json'], need_auth: true) capture_terraform(cmd, json: true) end def tf_init(input: nil, upgrade: nil, color: true, &block) args = [] args << "-input=#{input.inspect}" unless input.nil? args << '-upgrade' unless upgrade.nil? args << '-no-color' unless color cmd = tf_prepare_command(['init', *args], need_auth: true) stream_or_run_terraform(cmd, &block) end def tf_plan(out:, color: true, detailed_exitcode: nil, compact_warnings: false, input: nil, &block) args = [] args += ['-out', out] args << "-input=#{input.inspect}" unless input.nil? args << '-compact-warnings' if compact_warnings args << '-no-color' unless color args << '-detailed-exitcode' if detailed_exitcode cmd = tf_prepare_command(['plan', *args], need_auth: true) stream_or_run_terraform(cmd, &block) end def tf_show(file, json: false) if json args = ['show', '-json', file] cmd = tf_prepare_command(args, need_auth: true) capture_terraform(cmd, json: true) else args = ['show', file] cmd = tf_prepare_command(args, need_auth: true) run_terraform(cmd) end end private def tf_prepare_command(args, need_auth:) if ENV['MUX_TF_AUTH_WRAPPER'] && need_auth words = Shellwords.shellsplit(ENV['MUX_TF_AUTH_WRAPPER']) [*words, 'terraform', *args] else ['terraform', *args] end end def stream_or_run_terraform(args, &block) if block_given? stream_terraform(args, &block) else run_terraform(args) end end # return_status: false, echo_command: true, quiet: false, indent: 0 def run_terraform(args, **_options) status = run_shell(args, return_status: true, echo_command: true, quiet: false) OpenStruct.new({ status: status, success?: status == 0 }) end def stream_terraform(args, &block) status = run_with_each_line(args, &block) # status is a Process::Status OpenStruct.new({ status: status.exitstatus, success?: status.exitstatus == 0 }) end # error: true, echo_command: true, indent: 0, raise_on_error: false, detailed_result: false def capture_terraform(args, json: nil) result = capture_shell(args, error: true, echo_command: false, raise_on_error: false, detailed_result: true) parsed_output = JSON.parse(result.output) if json OpenStruct.new({ status: result.status, success?: result.status == 0, output: result.output, parsed_output: parsed_output }) rescue JSON::ParserError => e fail_with "Execution Failed! - #{result.inspect}" end end end