Skip to content

Commit

Permalink
Merge pull request #86 from jameswnl/workflow
Browse files Browse the repository at this point in the history
Integrate with Tower Workflow
  • Loading branch information
agrare committed Jun 7, 2018
2 parents da4c956 + a64a321 commit b9876bd
Show file tree
Hide file tree
Showing 11 changed files with 1,513 additions and 15,223 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class ManageIQ::Providers::AnsibleTower::AutomationManager < ManageIQ::Providers

require_nested :ConfigurationScript
require_nested :ConfigurationScriptSource
require_nested :ConfigurationWorkflow
require_nested :ConfiguredSystem
require_nested :EventCatcher
require_nested :EventParser
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationWorkflow <
ManageIQ::Providers::ExternalAutomationManager::ConfigurationWorkflow

include ManageIQ::Providers::AnsibleTower::Shared::AutomationManager::ConfigurationWorkflow
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module ManageIQ::Providers::AnsibleTower::Shared::AutomationManager::ConfigurationWorkflow
extend ActiveSupport::Concern

include ProviderObjectMixin

module ClassMethods
def provider_collection(manager)
manager.with_provider_connection do |connection|
connection.api.workflow_job_templates
end
end
end

def run(vars = {})
options = vars.merge(merge_extra_vars(vars[:extra_vars]))

with_provider_object do |jt|
jt.launch(options)
end
end

def merge_extra_vars(external)
{:extra_vars => variables.merge(external || {}).to_json}
end

def provider_object(connection = nil)
(connection || connection_source.connect).api.workflow_job_templates.find(manager_ref)
end

FRIENDLY_NAME = 'Ansible Tower Workflow Job Template'.freeze
end
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def job_templates
connection.api.job_templates.all
end

def configuration_workflows
connection.api.workflow_job_templates.all
end

def projects
connection.api.projects.all
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ def parse
configuration_scripts
configuration_script_sources
credentials
configuration_workflows
end

def inventory_root_groups
Expand Down Expand Up @@ -109,4 +110,14 @@ def credentials
end
end
end

def configuration_workflows
collector.configuration_workflows.each do |job_template|
inventory_object = persister.configuration_workflows.find_or_build(job_template.id.to_s)
inventory_object.description = job_template.description
inventory_object.name = job_template.name
inventory_object.survey_spec = job_template.survey_spec_hash
inventory_object.variables = job_template.extra_vars_hash
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module ManageIQ::Providers::AnsibleTower::Shared::Inventory::Persister::Automati
has_automation_manager_configuration_scripts
has_automation_manager_configuration_script_sources
has_automation_manager_configuration_script_payloads :model_class => ManageIQ::Providers::Inflector.provider_module(self)::AutomationManager::Playbook
has_automation_manager_configuration_workflows
has_automation_manager_configured_systems
has_automation_manager_inventory_root_groups
has_vms :parent => nil, :arel => Vm, :strategy => :local_db_find_references
Expand Down
2 changes: 1 addition & 1 deletion manageiq-providers-ansible_tower.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Gem::Specification.new do |s|

s.files = Dir["{app,config,lib}/**/*"]

s.add_runtime_dependency "ansible_tower_client", "~> 0.13.0"
s.add_runtime_dependency "ansible_tower_client", "~> 0.15"

s.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
s.add_development_dependency "simplecov"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
describe ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationWorkflow do
let(:provider_with_authentication) { FactoryGirl.create(:provider_ansible_tower, :with_authentication) }
let(:manager_with_authentication) { provider_with_authentication.managers.first }
let(:manager_with_configuration_workflows) { FactoryGirl.create(:automation_manager_ansible_tower, :provider, :configuration_workflow) }

it_behaves_like 'ansible configuration_workflow'
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require 'ansible_tower_client'
require 'faraday'

shared_examples_for "ansible configuration_workflow" do
let(:api) { double(:api, :workflow_job_templates => double(:workflow_job_templates)) }
let(:connection) { double(:connection, :api => api) }
let(:job) { AnsibleTowerClient::WorkflowJob.new(connection.api, "id" => 1) }
let(:workflow_job_template) { AnsibleTowerClient::WorkflowJobTemplate.new(connection.api, "limit" => "", "id" => 1, "url" => "api/workflow_job_templates/1/", "name" => "template", "description" => "description", "extra_vars" => {:instance_ids => ['i-3434']}) }
let(:manager) { manager_with_configuration_workflows }
context "#run" do
before do
allow_any_instance_of(Provider).to receive_messages(:connect => connection)
allow(api.workflow_job_templates).to receive(:find) { workflow_job_template }
end

it "launches the referenced ansible workflow job template" do
expect(workflow_job_template).to receive(:launch).with(:extra_vars => "{\"instance_ids\":[\"i-3434\"]}").and_return(job)
expect(manager.configuration_workflows.first.run).to be_a AnsibleTowerClient::WorkflowJob
end

it "accepts different variables to launch a job template against" do
added_extras = {:extra_vars => {:some_key => :some_value}}
expect(workflow_job_template).to receive(:launch).with(:extra_vars=>"{\"instance_ids\":[\"i-3434\"],\"some_key\":\"some_value\"}").and_return(job)
expect(manager.configuration_workflows.first.run(added_extras)).to be_a AnsibleTowerClient::WorkflowJob
end
end

context "#merge_extra_vars" do
it "merges internal and external hashes to send out to the tower gem" do
config_workflow = manager.configuration_workflows.first
external = {:some_key => :some_value}
internal = config_workflow.variables
expect(internal).to be_a Hash
expect(config_workflow.merge_extra_vars(external)).to eq(:extra_vars => "{\"instance_ids\":[\"i-3434\"],\"some_key\":\"some_value\"}")
end

it "merges an internal hash and an empty hash to send out to the tower gem" do
config_workflow = manager.configuration_workflows.first
external = nil
expect(config_workflow.merge_extra_vars(external)).to eq(:extra_vars => "{\"instance_ids\":[\"i-3434\"]}")
end

it "merges an empty internal hash and a hash to send out to the tower gem" do
external = {:some_key => :some_value}
internal = {}
config_workflow = manager.configuration_workflows.first
config_workflow.variables = internal
expect(config_workflow.merge_extra_vars(external)).to eq(:extra_vars => "{\"some_key\":\"some_value\"}")
end

it "merges all empty arguments to send out to the tower gem" do
external = nil
internal = {}
config_workflow = manager.configuration_workflows.first
config_workflow.variables = internal
expect(config_workflow.merge_extra_vars(external)).to eq(:extra_vars => "{}")
end
end
end
45 changes: 23 additions & 22 deletions spec/support/ansible_shared/automation_manager/refresher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
# replace with your working credentials
# ruby -pi -e 'gsub /example.com/, "yourdomain.com"; gsub /testuser:secret/, "admin:smartvm"' spec/vcr_cassettes/manageiq/providers/ansible_tower/automation_manager/*.yml

let(:tower_url) { ENV['TOWER_URL'] || "https://dev-ansible-tower3.example.com/api/v1/" }
let(:tower_url) { ENV['TOWER_URL'] || "https://example.com/api/v1/" }
let(:auth_userid) { ENV['TOWER_USER'] || 'testuser' }
let(:auth_password) { ENV['TOWER_PASSWORD'] || 'secret' }

Expand All @@ -62,13 +62,14 @@
it "will remove all objects if an empty collection is returned by tower" do
mock_api = double
mock_collection = double(:all => [])
allow(mock_api).to receive(:version).and_return('3.0')
allow(mock_api).to receive(:version).and_return('3.2.2')
allow(mock_api).to receive_messages(
:inventories => mock_collection,
:hosts => mock_collection,
:job_templates => mock_collection,
:projects => mock_collection,
:credentials => mock_collection,
:inventories => mock_collection,
:hosts => mock_collection,
:job_templates => mock_collection,
:workflow_job_templates => mock_collection,
:projects => mock_collection,
:credentials => mock_collection,
)
allow(automation_manager.provider).to receive_message_chain(:connect, :api).and_return(mock_api)
automation_manager.configuration_script_sources.create!
Expand Down Expand Up @@ -101,23 +102,23 @@

def assert_counts
expect(Provider.count).to eq(1)
expect(automation_manager).to have_attributes(:api_version => "3.0.1")
expect(automation_manager.configured_systems.count).to eq(131)
expect(automation_manager.configuration_scripts.count).to eq(120)
expect(automation_manager.inventory_groups.count).to eq(30)
expect(automation_manager.configuration_script_sources.count).to eq(34)
expect(automation_manager.configuration_script_payloads.count).to eq(2721)
expect(automation_manager.credentials.count).to eq(62)
expect(automation_manager).to have_attributes(:api_version => "3.2.2")
expect(automation_manager.configured_systems.count).to eq(3)
expect(automation_manager.configuration_scripts.count).to eq(7)
expect(automation_manager.inventory_groups.count).to eq(3)
expect(automation_manager.configuration_script_sources.count).to eq(10)
expect(automation_manager.configuration_script_payloads.count).to eq(130)
expect(automation_manager.credentials.count).to eq(15)
end

def assert_credentials
expect(expected_configuration_script.authentications.count).to eq(3)

# vault_credential
vault_credential = Authentication.all.find_by(:type => manager_class::VaultCredential)
vault_credential = Authentication.all.find_by(:type => manager_class::VaultCredential, :manager_ref => "2")
expect(vault_credential.options.keys).to match_array([:vault_password])
expect(vault_credential.options[:vault_password]).not_to be_empty
expect(vault_credential.name).to eq("Demo Creds 2")
expect(vault_credential.name).to eq("vault-test")

# machine_credential
machine_credential = expected_configuration_script.authentications.find_by(
Expand Down Expand Up @@ -199,7 +200,7 @@ def assert_configured_system
expect(expected_configured_system).to have_attributes(
:type => manager_class::ConfiguredSystem.name,
:hostname => "hello_vm",
:manager_ref => "252",
:manager_ref => "98",
:virtual_instance_ref => "4233080d-7467-de61-76c9-c8307b6e4830",
)
expect(expected_configured_system.counterpart).to eq(expected_counterpart_vm)
Expand All @@ -210,21 +211,21 @@ def assert_configuration_script_with_nil_survey_spec
expect(expected_configuration_script).to have_attributes(
:name => "hello_template",
:description => "test job",
:manager_ref => "604",
:manager_ref => "341",
:survey_spec => {},
:variables => {},
)
# expect(expected_configuration_script.inventory_root_group).to have_attributes(:ems_ref => "1")
# expect(expected_configuration_script.inventory_root_group).to have_attributes(:ems_ref => "43")
expect(expected_configuration_script.parent.name).to eq('hello_world.yml')
# expect(expected_configuration_script.parent.configuration_script_source.manager_ref).to eq('37')
expect(expected_configuration_script.parent.configuration_script_source.manager_ref).to eq('340')
end

def assert_configuration_script_with_survey_spec
system = automation_manager.configuration_scripts.where(:name => "hello_template_with_survey").first
expect(system).to have_attributes(
:name => "hello_template_with_survey",
:description => "test job with survey spec",
:manager_ref => "605",
:manager_ref => "342",
:variables => {}
)
survey = system.survey_spec
Expand All @@ -235,7 +236,7 @@ def assert_configuration_script_with_survey_spec
def assert_inventory_root_group
expect(expected_inventory_root_group).to have_attributes(
:name => "hello_inventory",
:ems_ref => "115",
:ems_ref => "99",
:type => "ManageIQ::Providers::AutomationManager::InventoryRootGroup",
)
end
Expand Down
Loading

0 comments on commit b9876bd

Please sign in to comment.