diff --git a/app/models/manageiq/providers/embedded_terraform/automation_manager/stack.rb b/app/models/manageiq/providers/embedded_terraform/automation_manager/stack.rb index c608285..d953615 100644 --- a/app/models/manageiq/providers/embedded_terraform/automation_manager/stack.rb +++ b/app/models/manageiq/providers/embedded_terraform/automation_manager/stack.rb @@ -54,4 +54,61 @@ def refresh def raw_status Status.new(miq_task) end + + # Intend to be called by UI to display stdout. The stdout is stored in TerraformRunner(api/stack#message) + def raw_stdout_via_worker(userid, format = 'txt') + unless MiqRegion.my_region.role_active?("embedded_terraform") + msg = "Cannot get standard output of this terraform-template because the embedded terraform role is not enabled" + return MiqTask.create( + :name => 'terraform_stdout', + :userid => userid || 'system', + :state => MiqTask::STATE_FINISHED, + :status => MiqTask::STATUS_ERROR, + :message => msg + ).id + end + + options = {:userid => userid || 'system', :action => 'terraform_stdout'} + queue_options = { + :class_name => self.class, + :method_name => 'raw_stdout', + :instance_id => id, + :args => [format], + :priority => MiqQueue::HIGH_PRIORITY, + :role => nil + } + + MiqTask.generic_action_with_callback(options, queue_options) + end + + def raw_stdout(format = 'txt') + case format + when "html" then raw_stdout_html + else raw_stdout_txt + end + end + + def raw_stdout_txt + data = terraform_runner_stack_data + data&.message + end + + def raw_stdout_html + text = raw_stdout_txt + text = _("No output available") if text.blank? + TerminalToHtml.render(text) + end + + private + + def terraform_runner_stack_data + return if miq_task.nil? || miq_task.job.nil? + + job = miq_task.job + terraform_stack_id = job.options[:terraform_stack_id] + + return if terraform_stack_id.blank? + + Terraform::Runner.fetch_result_by_stack_id(terraform_stack_id) + end end diff --git a/spec/models/manageiq/providers/embedded_terraform/automation_manager/stack_spec.rb b/spec/models/manageiq/providers/embedded_terraform/automation_manager/stack_spec.rb index 3014951..6c8447c 100644 --- a/spec/models/manageiq/providers/embedded_terraform/automation_manager/stack_spec.rb +++ b/spec/models/manageiq/providers/embedded_terraform/automation_manager/stack_spec.rb @@ -30,4 +30,161 @@ end end end + + describe "#raw_stdout" do + let(:stack) { FactoryBot.create(:terraform_stack, :miq_task => miq_task) } + let(:template) { FactoryBot.create(:terraform_template) } + + context "when miq_task.job present" do + let(:terraform_runner_url) { "https://1.2.3.4:7000" } + let(:hello_world_retrieve_response) do + require 'json' + JSON.parse(File.read(File.join(__dir__, "../../../../../lib/terraform/runner/data/responses/hello-world-retrieve-success.json"))) + end + let(:miq_task) { FactoryBot.create(:miq_task, :job => job) } + + let(:job) do + ManageIQ::Providers::EmbeddedTerraform::AutomationManager::Job.create_job(template, {}, {}, []).tap do |job| + job.state = "finished" + job.options = { + :terraform_stack_id => hello_world_retrieve_response['stack_id'] + } + end + end + + let(:terraform_runner_stdout) { hello_world_retrieve_response['message'] } + let(:terraform_runner_stdout_html) { TerminalToHtml.render(terraform_runner_stdout) } + + before do + stub_const("ENV", ENV.to_h.merge("TERRAFORM_RUNNER_URL" => terraform_runner_url)) + + stub_request(:post, "#{terraform_runner_url}/api/stack/retrieve") + .with(:body => hash_including({:stack_id => hello_world_retrieve_response['stack_id']})) + .to_return( + :status => 200, + :body => hello_world_retrieve_response.to_json + ) + end + + it "json" do + expect(stack.raw_stdout("json")).to eq terraform_runner_stdout + end + + it "txt" do + expect(stack.raw_stdout("txt")).to eq terraform_runner_stdout + end + + it "html" do + expect(stack.raw_stdout("html")).to eq terraform_runner_stdout_html + end + + it "nil" do + expect(stack.raw_stdout).to eq terraform_runner_stdout + end + end + + shared_examples_for "terraform runner stdout not available from miq_task" do + it "json" do + expect(stack.raw_stdout("json")).to be_nil + end + + it "txt" do + expect(stack.raw_stdout("txt")).to be_nil + end + + it "html" do + expect(stack.raw_stdout("html")).to include <<~EOHTML +