From b9ccc094d5aebc559cc9530552020c25897082e6 Mon Sep 17 00:00:00 2001 From: Lucy Fu Date: Thu, 4 Oct 2018 10:54:27 -0400 Subject: [PATCH 1/2] Add ApiAnsibleMixin for extra_vars support of Ansible Tower. Refactor extra_vars support for ServiceAnsiblePlaybook. https://github.com/ManageIQ/manageiq/issues/18005 --- app/models/mixins/ansible_extra_vars_mixin.rb | 35 +++++++++++++++++ app/models/service_ansible_playbook.rb | 39 +++++++------------ spec/models/service_ansible_playbook_spec.rb | 4 +- 3 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 app/models/mixins/ansible_extra_vars_mixin.rb diff --git a/app/models/mixins/ansible_extra_vars_mixin.rb b/app/models/mixins/ansible_extra_vars_mixin.rb new file mode 100644 index 00000000000..a5763f1cffd --- /dev/null +++ b/app/models/mixins/ansible_extra_vars_mixin.rb @@ -0,0 +1,35 @@ +module AnsibleExtraVarsMixin + extend ActiveSupport::Concern + + def manageiq_env(user, miq_group, request_task = nil) + { + 'api_url' => api_url, + 'api_token' => api_token(user), + 'user' => user.href_slug, + 'group' => miq_group.href_slug, + 'X_MIQ_Group' => user.current_group.description, + }.merge(task_url(request_task)) + end + + def manageiq_connection_env(user) + { + 'url' => api_url, + 'token' => api_token(user), + 'X_MIQ_Group' => user.current_group.description + } + end + + private + + def api_token(user) + @api_token ||= Api::UserTokenService.new.generate_token(user.userid, 'api') + end + + def api_url + @api_url ||= MiqRegion.my_region.remote_ws_url + end + + def task_url(request_task) + request_task ? {'request_task' => "#{request_task.miq_request.href_slug}/#{request_task.href_slug}", 'request' => request_task.miq_request.href_slug} : {} + end +end diff --git a/app/models/service_ansible_playbook.rb b/app/models/service_ansible_playbook.rb index 6e4c8c3979f..4bd25b310f8 100644 --- a/app/models/service_ansible_playbook.rb +++ b/app/models/service_ansible_playbook.rb @@ -1,4 +1,6 @@ class ServiceAnsiblePlaybook < ServiceGeneric + include AnsibleExtraVarsMixin + delegate :job_template, :to => :service_template, :allow_nil => true # A chance for taking options from automate script to override options from a service dialog @@ -13,7 +15,12 @@ def preprocess(action, add_options = {}) def execute(action) jt = job_template(action) - opts = get_job_options(action).deep_merge(:extra_vars => {'manageiq' => manageiq_extra_vars(action), 'manageiq_connection' => manageiq_connection_env}) + opts = get_job_options(action).deep_merge( + :extra_vars => { + 'manageiq' => service_manageiq_env(action), + 'manageiq_connection' => manageiq_connection_env(evm_owner) + } + ) hosts = opts.delete(:hosts) _log.info("Launching Ansible Tower job with options:") @@ -61,32 +68,12 @@ def on_error(action) private - def manageiq_extra_vars(action) - { - 'api_url' => api_url, - 'api_token' => api_token, - 'service' => href_slug, - 'user' => evm_owner.href_slug, - 'group' => miq_group.href_slug, - 'action' => action, - 'X_MIQ_Group' => evm_owner.current_group.description - }.merge(request_options_extra_vars) - end - - def manageiq_connection_env + def service_manageiq_env(action) { - 'url' => api_url, - 'token' => api_token, - 'X_MIQ_Group' => evm_owner.current_group.description - } - end - - def api_token - @api_token ||= Api::UserTokenService.new.generate_token(evm_owner.userid, 'api') - end - - def api_url - @api_url ||= MiqRegion.my_region.remote_ws_url + 'service' => href_slug, + 'action' => action + }.merge(manageiq_env(evm_owner, miq_group, miq_request_task)) + .merge(request_options_extra_vars) end def request_options_extra_vars diff --git a/spec/models/service_ansible_playbook_spec.rb b/spec/models/service_ansible_playbook_spec.rb index 190bf5e1110..eecae314577 100644 --- a/spec/models/service_ansible_playbook_spec.rb +++ b/spec/models/service_ansible_playbook_spec.rb @@ -144,7 +144,7 @@ let(:control_extras) { {'a' => 'A', 'b' => 'B', 'c' => 'C'} } before do FactoryGirl.create(:miq_region, :region => ApplicationRecord.my_region_number) - miq_request_task = FactoryGirl.create(:miq_request_task) + miq_request_task = FactoryGirl.create(:miq_request_task, :miq_request => FactoryGirl.create(:service_template_provision_request)) miq_request_task.update_attributes(:options => {:request_options => {:manageiq_extra_vars => control_extras}}) loaded_service.update_attributes(:evm_owner => FactoryGirl.create(:user_with_group), :miq_group => FactoryGirl.create(:miq_group), @@ -154,7 +154,7 @@ it 'creates an Ansible Tower job' do expect(ManageIQ::Providers::EmbeddedAnsible::AutomationManager::Job).to receive(:create_job) do |jobtemp, opts| expect(jobtemp).to eq(tower_job_temp) - exposed_miq = %w(api_url api_token service user group X_MIQ_Group) + control_extras.keys + exposed_miq = %w(api_url api_token service user group X_MIQ_Group request_task request) + control_extras.keys exposed_connection = %w(url token X_MIQ_Group) expect(opts[:extra_vars].delete('manageiq').keys).to include(*exposed_miq) expect(opts[:extra_vars].delete('manageiq_connection').keys).to include(*exposed_connection) From 3b6fa05d325bf2804f880c4839207d4c066cd1d7 Mon Sep 17 00:00:00 2001 From: Lucy Fu Date: Thu, 4 Oct 2018 10:55:09 -0400 Subject: [PATCH 2/2] Add extra_vars for ServiceAnsibleTower. https://github.com/ManageIQ/manageiq/issues/18005 --- app/models/service_ansible_tower.rb | 22 +++++++++++++++++++++- spec/models/service_ansible_tower_spec.rb | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/models/service_ansible_tower.rb b/app/models/service_ansible_tower.rb index 6a0ea1b1f4d..56f503f2348 100644 --- a/app/models/service_ansible_tower.rb +++ b/app/models/service_ansible_tower.rb @@ -1,4 +1,5 @@ class ServiceAnsibleTower < Service + include AnsibleExtraVarsMixin include ServiceConfigurationMixin include ServiceOrchestrationOptionsMixin @@ -9,6 +10,14 @@ class ServiceAnsibleTower < Service def launch_job job_class = "#{job_template.class.parent.name}::#{job_template.class.stack_type}".constantize + job_options.deep_merge!( + :extra_vars => { + 'manageiq' => service_manageiq_env, + 'manageiq_connection' => manageiq_connection_env(evm_owner) + } + ) + _log.info("Launching Ansible Tower job with options:") + $log.log_hashes(job_options) @job = job_class.create_job(job_template, job_options) add_resource(@job) @job @@ -40,7 +49,7 @@ def build_stack_create_options raise _("job template was not set") if job_template.nil? - build_stack_options_from_dialog(dialog_options) + build_stack_options_from_dialog(dialog_options).with_indifferent_access end def save_launch_options @@ -62,4 +71,15 @@ def extra_vars_from_dialog(dialog_options) end end end + + def service_manageiq_env + { + 'service' => href_slug + }.merge(manageiq_env(evm_owner, miq_group, miq_request_task)) + .merge(request_options_extra_vars) + end + + def request_options_extra_vars + miq_request_task.options.fetch_path(:request_options, :manageiq_extra_vars) || {} + end end diff --git a/spec/models/service_ansible_tower_spec.rb b/spec/models/service_ansible_tower_spec.rb index 13187557d6a..af9a010848e 100644 --- a/spec/models/service_ansible_tower_spec.rb +++ b/spec/models/service_ansible_tower_spec.rb @@ -61,11 +61,26 @@ end describe '#launch_job' do + let(:control_extras) { {'a' => 'A', 'b' => 'B', 'c' => 'C'} } + before do + FactoryGirl.create(:miq_region, :region => ApplicationRecord.my_region_number) + miq_request_task = FactoryGirl.create(:miq_request_task, :miq_request => FactoryGirl.create(:service_template_provision_request)) + miq_request_task.update_attributes(:options => {:request_options => {:manageiq_extra_vars => control_extras}}) + service.update_attributes(:evm_owner => FactoryGirl.create(:user_with_group), + :miq_group => FactoryGirl.create(:miq_group), + :miq_request_task => miq_request_task) + end + it 'launches a job through ansible tower provider' do allow(ManageIQ::Providers::AnsibleTower::AutomationManager::Job).to receive(:raw_create_stack) do |template, opts| expect(template).to be_kind_of ConfigurationScript expect(opts).to have_key(:limit) expect(opts).to have_key(:extra_vars) + + exposed_miq = %w(api_url api_token service user group X_MIQ_Group request_task request) + control_extras.keys + exposed_connection = %w(url token X_MIQ_Group) + expect(opts[:extra_vars].delete('manageiq').keys).to include(*exposed_miq) + expect(opts[:extra_vars].delete('manageiq_connection').keys).to include(*exposed_connection) end.and_return(double(:raw_job, :id => 1, :status => "completed",