Skip to content

Commit

Permalink
Merge pull request #13896 from syncrou/create_service_template_with_t…
Browse files Browse the repository at this point in the history
…ower_2

Create service template with Ansible Tower after first creating a new job template
  • Loading branch information
gmcculloug authored Feb 15, 2017
2 parents 55ab1e6 + c81dbcb commit fc185c2
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ def create_in_provider(manager_id, params)

# Get the record in our database
# TODO: This needs to be targeted refresh so it doesn't take too long
EmsRefresh.queue_refresh(manager, nil, true) if !manager.missing_credentials? && manager.authentication_status_ok?
EmsRefresh.queue_refresh(manager, nil, true) if manager.authentication_status_ok?

find_by(:manager_id => manager.id, :manager_ref => job_template.id)
end

def create_in_provider_queue(manager_id, params)
def create_in_provider_queue(manager_id, params, auth_user = nil)
task_opts = {
:action => "Creating Ansible Tower Job Template",
:userid => "system"
:userid => auth_user || "system"
}

manager = ExtManagementSystem.find(manager_id)
Expand All @@ -27,7 +27,7 @@ def create_in_provider_queue(manager_id, params)
:method_name => "create_in_provider",
:priority => MiqQueue::HIGH_PRIORITY,
:role => "ems_operations",
:zone => manager.zone_id
:zone => manager.my_zone
}

MiqTask.generic_action_with_callback(task_opts, queue_opts)
Expand Down
51 changes: 40 additions & 11 deletions app/models/service_template_ansible_playbook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,49 @@ def self.prepare_job_template_and_dialog(action, service_name, description, conf
end
private_class_method :prepare_job_template_and_dialog

def self.create_job_template(name, description, info)
playbook = ManageIQ::Providers::AnsibleTower::ConfigurationManager::Playbook.find(info[:playbook_id])
# tower = playbook.manager

# params = {
# :name => name,
# :description => description || '',
# :extra_vars => info[:variables] || {},
# :inventory_id => playbook.inventory_root_group,
# }
# tower.class.create_in_provider(tower, params)
def self.create_job_templates(service_name, description, config_info, auth_user)
[:provision, :retirement, :reconfigure].each_with_object({}) do |action, hash|
next unless config_info[action]
hash[action] = { :configuration_template => create_job_template("miq_#{service_name}_#{action}", description, config_info[action], auth_user) }
end
end
private_class_method :create_job_templates

def self.create_job_template(name, description, info, auth_user)
tower, params = build_parameter_list(name, description, info)

task_id = ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript.create_in_provider_queue(tower.id, params, auth_user)
task = MiqTask.wait_for_taskid(task_id)
raise task.message unless task.status == "Ok"
task.task_results
end
private_class_method :create_job_template

def self.build_parameter_list(name, description, info)
playbook = ManageIQ::Providers::AnsibleTower::AutomationManager::Playbook.find(info[:playbook_id])
tower = playbook.manager
params = {
:name => name,
:description => description || '',
:project => playbook.configuration_script_source.manager_ref,
:playbook => playbook.name,
:inventory => tower.inventory_root_groups.first.ems_ref,
:ask_variables_on_launch => true,
:ask_limit_on_launch => true,
:ask_inventory_on_launch => true,
:ask_credential_on_launch => true
}
params[:extra_vars] = info[:extra_vars].to_json if info[:extra_vars]

[:credential, :cloud_credential, :network_credential].each do |credential|
cred_sym = "#{credential}_id".to_sym
params[credential] = Authentication.find(info[cred_sym]).manager_ref if info[cred_sym]
end

[tower, params.compact]
end
private_class_method :build_parameter_list

def self.validate_config_info(options)
info = options[:config_info]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
:method_name => "create_in_provider",
:priority => MiqQueue::HIGH_PRIORITY,
:role => "ems_operations",
:zone => manager.zone_id
:zone => manager.my_zone
)
end

Expand Down
116 changes: 116 additions & 0 deletions spec/models/service_template_ansible_playbook_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
describe ServiceTemplateAnsiblePlaybook do
describe 'building_job_templates' do
let(:user) { FactoryGirl.create(:user_with_group) }
let(:job_template) do
FactoryGirl.create(:configuration_script,
:variables => catalog_item_options.fetch_path(:config_info, :provision, :extra_vars))
end
let(:auth_one) { FactoryGirl.create(:authentication, :manager_ref => 6) }
let(:auth_two) { FactoryGirl.create(:authentication, :manager_ref => 10) }
let(:user) { FactoryGirl.create(:user_with_group) }
let(:inventory_root_group) { FactoryGirl.create(:inventory_root_group) }
let(:ems) do
FactoryGirl.create(:automation_manager_ansible_tower, :inventory_root_groups => [inventory_root_group])
end
let(:config_script) { FactoryGirl.create(:configuration_script) }
let(:script_source) { FactoryGirl.create(:configuration_script_source, :manager => ems) }
let(:playbook) do
FactoryGirl.create(:configuration_script_payload,
:configuration_script_source => script_source,
:manager => ems,
:inventory_root_group => inventory_root_group,
:type => 'ManageIQ::Providers::AnsibleTower::AutomationManager::Playbook')
end
let(:service_template_catalog) { FactoryGirl.create(:service_template_catalog) }
let(:catalog_item_options) do
{
:name => 'test_ansible_catalog_item',
:description => 'test ansible',
:service_template_catalog_id => service_template_catalog.id,
:config_info => {
:provision => {
:new_dialog_name => 'test_dialog',
:hosts => 'many',
:credential_id => auth_one.id,
:network_credential_id => auth_two.id,
:playbook_id => playbook.id,
},
}
}
end

let(:catalog_item_options_two) do
{
:name => 'playbook service',
:display => 'false',
:service_template_catalog_id => service_template_catalog.id,
:description => 'a description',
:config_info => {
:provision => {
:new_dialog_name => 'playbook dialog',
:playbook_id => playbook.id,
:extra_vars => {
'key1' => 'val1',
'key2' => 'val2'
}
},
:reconfigure => {
:new_dialog_name => 'playbook dialog reconfigure',
:playbook_id => 5,
},
:retirement => {
:new_dialog_name => 'playbook dialog retirement',
:playbook_id => 3,
},
}
}
end

it '#create_job_templates' do
expect(described_class).to receive(:create_job_template).exactly(3).times.and_return(job_template)
options_hash = described_class.send(:create_job_templates, catalog_item_options_two[:name], catalog_item_options_two[:description], catalog_item_options_two[:config_info], 'system')
[:provision, :retirement, :reconfigure].each do |action|
expect(options_hash[action.to_sym][:configuration_template]).to eq job_template
end
end

it '#create_job_template' do
expect(described_class).to receive(:build_parameter_list).and_return([ems, {}])
expect(ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript).to receive(:create_in_provider_queue).once.with(ems.id, {}, 'system')
expect(MiqTask).to receive(:wait_for_taskid).with(any_args).once.and_return(instance_double('MiqTask', :task_results => {}, :status => 'Ok'))

described_class.send(:create_job_template, catalog_item_options[:name], catalog_item_options[:description], catalog_item_options[:config_info], 'system')
end

it 'create_job_template exception' do
expect(described_class).to receive(:build_parameter_list).and_return([ems, {}])
expect(ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript).to receive(:create_in_provider_queue).once.with(ems.id, {}, 'system')
expect(MiqTask).to receive(:wait_for_taskid).with(any_args).once.and_raise(Exception, 'bad job template')

expect { described_class.send(:create_job_template, catalog_item_options[:name], catalog_item_options[:description], catalog_item_options[:config_info], 'system') }.to raise_error(Exception)
end

it '#build_parameter_list' do
name = catalog_item_options[:name]
catalog_extra_vars = catalog_item_options_two
description = catalog_item_options[:description]
info = catalog_item_options[:config_info][:provision]
_tower, params = described_class.send(:build_parameter_list, name, description, info)
_tower_two, params_two = described_class.send(:build_parameter_list, catalog_extra_vars[:name], catalog_extra_vars[:description], catalog_extra_vars[:config_info][:provision])

expect(params).to have_attributes(
:name => name,
:description => description,
:credential => '6',
:network_credential => '10'
)

expect(params.keys).to_not include(:extra_vars, :cloud_credentials)
expect(params_two.keys).to include(:extra_vars)
expect(JSON.parse(params_two[:extra_vars])).to have_attributes(
'key1' => 'val1',
'key2' => 'val2'
)
end
end
end

0 comments on commit fc185c2

Please sign in to comment.