diff --git a/app/controllers/foreman_ansible_director/api/v2/ansible_runs_controller.rb b/app/controllers/foreman_ansible_director/api/v2/ansible_runs_controller.rb index 06165d62..400fcc6e 100644 --- a/app/controllers/foreman_ansible_director/api/v2/ansible_runs_controller.rb +++ b/app/controllers/foreman_ansible_director/api/v2/ansible_runs_controller.rb @@ -9,6 +9,9 @@ class AnsibleRunsController < AnsibleDirectorApiController before_action :find_target_host, only: %i[run_all] def run_all + proxy = ::SmartProxy.with_features(::ForemanAnsibleDirector::PROXY_FEATURE).first + raise "No smart proxy with '#{::ForemanAnsibleDirector::PROXY_FEATURE}' feature found" unless proxy + playbook = ForemanAnsibleDirector::Generators::PlaybookGenerator.generate @target_host inventory = ForemanAnsibleDirector::Generators::InventoryGenerator.generate @target_host @@ -17,6 +20,7 @@ def run_all ForemanTasks.async_task( ::ForemanAnsibleDirector::Actions::Proxy::RunPlaybook, proxy_task_id: SecureRandom.uuid, + smart_proxy_id: proxy.id, playbook: playbook, inventory: inventory, content: content, diff --git a/app/lib/foreman_ansible_director/actions/proxy/build_execution_environment.rb b/app/lib/foreman_ansible_director/actions/proxy/build_execution_environment.rb index d31ce836..c1f44b32 100644 --- a/app/lib/foreman_ansible_director/actions/proxy/build_execution_environment.rb +++ b/app/lib/foreman_ansible_director/actions/proxy/build_execution_environment.rb @@ -10,6 +10,7 @@ class BuildExecutionEnvironment < ::ForemanAnsibleDirector::Actions::Base::Ansib input_format do param :proxy_task_id, Integer + param :smart_proxy_id, Integer param :execution_environment_definition, Hash param :execution_environment_id, String end @@ -20,13 +21,16 @@ class BuildExecutionEnvironment < ::ForemanAnsibleDirector::Actions::Base::Ansib def invoke_external_task ::ForemanAnsibleDirector::Proxy::Dynflow::SingleBatchAction.new( input[:proxy_task_id], 'meta', 'Proxy::AnsibleDirector::Actions::Meta::BuildPushEe', + input[:smart_proxy_id], execution_environment: input[:execution_environment_definition] ).request nil end def poll_external_task - task = ::ForemanAnsibleDirector::Proxy::Dynflow::TaskStatus.new(input[:proxy_task_id]).request + task = ::ForemanAnsibleDirector::Proxy::Dynflow::TaskStatus.new( + input[:proxy_task_id], input[:smart_proxy_id] + ).request task_status = ::ForemanAnsibleDirector::Parsers::Proxy::Dynflow::TaskStatusParser.new(task) { progress: task_status.progress, diff --git a/app/lib/foreman_ansible_director/actions/proxy/run_playbook.rb b/app/lib/foreman_ansible_director/actions/proxy/run_playbook.rb index db20c11e..35e342f1 100644 --- a/app/lib/foreman_ansible_director/actions/proxy/run_playbook.rb +++ b/app/lib/foreman_ansible_director/actions/proxy/run_playbook.rb @@ -8,6 +8,7 @@ class RunPlaybook < ::ForemanAnsibleDirector::Actions::Base::AnsibleDirectorActi input_format do param :proxy_task_id, Integer + param :smart_proxy_id, Integer param :inventory, Hash param :playbook, Hash param :content, Array @@ -20,6 +21,7 @@ class RunPlaybook < ::ForemanAnsibleDirector::Actions::Base::AnsibleDirectorActi def invoke_external_task ::ForemanAnsibleDirector::Proxy::Dynflow::SingleBatchAction.new( input[:proxy_task_id], 'ansible-navigator', 'Proxy::AnsibleDirector::Actions::Meta::RunPlaybook', + input[:smart_proxy_id], inventory: input[:inventory], playbook: input[:playbook], content: input[:content], @@ -29,7 +31,9 @@ def invoke_external_task end def poll_external_task - task = ::ForemanAnsibleDirector::Proxy::Dynflow::TaskStatus.new(input[:proxy_task_id]).request + task = ::ForemanAnsibleDirector::Proxy::Dynflow::TaskStatus.new( + input[:proxy_task_id], input[:smart_proxy_id] + ).request task_status = ::ForemanAnsibleDirector::Parsers::Proxy::Dynflow::TaskStatusParser.new(task) { progress: task_status.progress } diff --git a/app/services/foreman_ansible_director/execution_environment_service.rb b/app/services/foreman_ansible_director/execution_environment_service.rb index 1eafc508..348b4675 100644 --- a/app/services/foreman_ansible_director/execution_environment_service.rb +++ b/app/services/foreman_ansible_director/execution_environment_service.rb @@ -49,6 +49,9 @@ def destroy_execution_environment(execution_environment) end def build_execution_environment(execution_environment) + proxy = ::SmartProxy.with_features(::ForemanAnsibleDirector::PROXY_FEATURE).first + raise "No smart proxy with '#{::ForemanAnsibleDirector::PROXY_FEATURE}' feature found" unless proxy + env_definition = { id: execution_environment.id, content: { @@ -71,6 +74,7 @@ def build_execution_environment(execution_environment) ForemanTasks.sync_task( ::ForemanAnsibleDirector::Actions::Proxy::BuildExecutionEnvironment, proxy_task_id: SecureRandom.uuid, + smart_proxy_id: proxy.id, execution_environment_definition: env_definition, execution_environment_id: execution_environment.id ) @@ -78,6 +82,7 @@ def build_execution_environment(execution_environment) ForemanTasks.async_task( ::ForemanAnsibleDirector::Actions::Proxy::BuildExecutionEnvironment, proxy_task_id: SecureRandom.uuid, + smart_proxy_id: proxy.id, execution_environment_definition: env_definition, execution_environment_id: execution_environment.id ) diff --git a/app/services/foreman_ansible_director/proxy/base_client.rb b/app/services/foreman_ansible_director/proxy/base_client.rb index 222c4392..2694be58 100644 --- a/app/services/foreman_ansible_director/proxy/base_client.rb +++ b/app/services/foreman_ansible_director/proxy/base_client.rb @@ -1,28 +1,28 @@ # frozen_string_literal: true -require 'pulpcore_client' module ForemanAnsibleDirector module Proxy - class BaseClient - class << self - def proxy_resource - ssl_config = { - ssl_client_cert: ::ForemanAnsibleDirector::Cert::Certs.ssl_client_cert, - ssl_client_key: ::ForemanAnsibleDirector::Cert::Certs.ssl_client_key, - ssl_ca_file: ::ForemanAnsibleDirector::Cert::Certs.ca_cert_file, - verify_ssl: OpenSSL::SSL::VERIFY_PEER, - } + class BaseClient < ::ProxyAPI::Resource + def initialize(proxy) + @url = proxy.url + super(url: @url) + end + + def launch_dynflow_task(proxy_task_id, operation, action_class, action_input) + payload = { + operation: operation, + input: { + proxy_task_id => { + action_class: action_class, + action_input: action_input, + }, + }, + }.to_json + post(payload, 'dynflow/tasks/launch') + end - # TODO: This should be configurable by the user and use a selector - if Rails.env.development? - return RestClient::Resource.new( - 'http://192.168.121.1:8080' - ) - end - RestClient::Resource.new( - ::SmartProxy.first.url, ssl_config - ) - end + def dynflow_task_status(proxy_task_id) + get("dynflow/tasks/#{proxy_task_id}/status") end end end diff --git a/app/services/foreman_ansible_director/proxy/dynflow/single_batch_action.rb b/app/services/foreman_ansible_director/proxy/dynflow/single_batch_action.rb index 7e439abd..7c6317e5 100644 --- a/app/services/foreman_ansible_director/proxy/dynflow/single_batch_action.rb +++ b/app/services/foreman_ansible_director/proxy/dynflow/single_batch_action.rb @@ -4,9 +4,8 @@ module ForemanAnsibleDirector module Proxy module Dynflow class SingleBatchAction - def initialize(proxy_task_id, operation, action_class, action_input) - proxy_resource = BaseClient.proxy_resource - @resource = proxy_resource['/dynflow/tasks/launch'] + def initialize(proxy_task_id, operation, action_class, smart_proxy_id, action_input) + @client = BaseClient.new(::SmartProxy.find(smart_proxy_id)) @proxy_task_id = proxy_task_id @operation = operation @action_class = action_class @@ -14,15 +13,7 @@ def initialize(proxy_task_id, operation, action_class, action_input) end def request - @resource.post({ - operation: @operation, - input: { - @proxy_task_id => { - action_class: @action_class, - action_input: @action_input, - }, - }, - }.to_json) + @client.launch_dynflow_task(@proxy_task_id, @operation, @action_class, @action_input) end end end diff --git a/app/services/foreman_ansible_director/proxy/dynflow/task_status.rb b/app/services/foreman_ansible_director/proxy/dynflow/task_status.rb index 7b8a21f9..8cb15fc8 100644 --- a/app/services/foreman_ansible_director/proxy/dynflow/task_status.rb +++ b/app/services/foreman_ansible_director/proxy/dynflow/task_status.rb @@ -4,13 +4,13 @@ module ForemanAnsibleDirector module Proxy module Dynflow class TaskStatus - def initialize(proxy_task_id) - proxy_resource = BaseClient.proxy_resource - @resource = proxy_resource["/dynflow/tasks/#{proxy_task_id}/status"] + def initialize(proxy_task_id, smart_proxy_id) + @client = BaseClient.new(::SmartProxy.find(smart_proxy_id)) + @proxy_task_id = proxy_task_id end def request - @resource.get + @client.dynflow_task_status(@proxy_task_id) end end end diff --git a/lib/foreman_ansible_director/engine.rb b/lib/foreman_ansible_director/engine.rb index 2b44e425..db2a3538 100644 --- a/lib/foreman_ansible_director/engine.rb +++ b/lib/foreman_ansible_director/engine.rb @@ -5,6 +5,7 @@ module ForemanAnsibleDirector DYNFLOW_QUEUE = :foreman_ansible_director + PROXY_FEATURE = 'Ansible_Director' class Engine < ::Rails::Engine isolate_namespace ForemanAnsibleDirector engine_name 'foreman_ansible_director' diff --git a/test/services/unit/execution_environment_service_test.rb b/test/services/unit/execution_environment_service_test.rb index 780fd5a9..831cbe72 100644 --- a/test/services/unit/execution_environment_service_test.rb +++ b/test/services/unit/execution_environment_service_test.rb @@ -6,6 +6,11 @@ module Unit class ExecutionEnvironmentServiceTest < ForemanAnsibleDirectorTestCase describe '#create_execution_environment' do + setup do + @proxy = FactoryBot.build_stubbed(:smart_proxy) + ::SmartProxy.stubs(:with_features).with(::ForemanAnsibleDirector::PROXY_FEATURE).returns([@proxy]) + end + test 'creates an execution environment with valid params' do ee = ::ForemanAnsibleDirector::ExecutionEnvironmentService.create_execution_environment( @@ -61,10 +66,24 @@ class ExecutionEnvironmentServiceTest < ForemanAnsibleDirectorTestCase assert_equal initial_count, ::ForemanAnsibleDirector::ExecutionEnvironment.count end + + test 'raises when no proxy with Ansible_Director feature exists' do + ::SmartProxy.stubs(:with_features).with(::ForemanAnsibleDirector::PROXY_FEATURE).returns([]) + assert_raises(RuntimeError) do + ::ForemanAnsibleDirector::ExecutionEnvironmentService.create_execution_environment( + name: 'test_ee', + base_image_url: 'quay.io/ansible/base-ee:latest', + ansible_version: '2.20.0', + organization_id: @organization.id + ) + end + end end describe '#edit_execution_environment' do setup do + @proxy = FactoryBot.build_stubbed(:smart_proxy) + ::SmartProxy.stubs(:with_features).with(::ForemanAnsibleDirector::PROXY_FEATURE).returns([@proxy]) @execution_environment = FactoryBot.create(:execution_environment, organization: @organization) end @@ -193,6 +212,8 @@ class ExecutionEnvironmentServiceTest < ForemanAnsibleDirectorTestCase describe '#build_execution_environment' do setup do + @proxy = FactoryBot.build_stubbed(:smart_proxy) + ::SmartProxy.stubs(:with_features).with(::ForemanAnsibleDirector::PROXY_FEATURE).returns([@proxy]) @execution_environment = FactoryBot.create(:execution_environment, organization: @organization) @collection = FactoryBot.create(:ansible_collection, organization: @organization) @collection_version = FactoryBot.create(:content_unit_version, :for_collection, versionable: @collection) diff --git a/test/services/unit/proxy/base_client_test.rb b/test/services/unit/proxy/base_client_test.rb new file mode 100644 index 00000000..1d8716b4 --- /dev/null +++ b/test/services/unit/proxy/base_client_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'foreman_ansible_director_test_helper' + +module ForemanAnsibleDirectorTests + module Services + module Unit + module Proxy + class BaseClientTest < ForemanAnsibleDirectorTestCase + + describe 'BaseClient.new' do + test 'uses the given proxy url' do + proxy = FactoryBot.create(:smart_proxy) + client = ::ForemanAnsibleDirector::Proxy::BaseClient.new(proxy) + assert_equal proxy.url, client.url + end + + test 'raises when no proxy is given' do + assert_raises(ArgumentError) do + ::ForemanAnsibleDirector::Proxy::BaseClient.new + end + end + end + end + end + end + end +end