lib/plan_executor/orch_client.rb in bolt-1.11.0 vs lib/plan_executor/orch_client.rb in bolt-1.12.0
- old
+ new
@@ -1,32 +1,33 @@
# frozen_string_literal: true
+require 'jsonclient'
+
module PlanExecutor
class OrchClient
- attr_reader :plan_job, :client
+ attr_reader :plan_job, :http
BOLT_COMMAND_TASK = Struct.new(:name).new('bolt_shim::command').freeze
BOLT_SCRIPT_TASK = Struct.new(:name).new('bolt_shim::script').freeze
BOLT_UPLOAD_TASK = Struct.new(:name).new('bolt_shim::upload').freeze
- def initialize(plan_job, client, logger)
+ def initialize(plan_job, http_client, logger)
@plan_job = plan_job
- @client = client
@logger = logger
- @client_url = client.config['service-url']
- logger.debug("Creating orchestrator client for #{@client_url}")
+ @http = http_client
@environment = 'production'
end
def finish_plan(plan_result)
- result = @client.command.plan_finish(
+ body = {
plan_job: @plan_job,
result: plan_result.value || '',
status: plan_result.status
- )
+ }
+ post_command('internal/plan_finish', body)
rescue StandardError => e
- @logger.debug("Failed to finish plan on #{@client_url}: #{e.message}\nResult: #{result.to_json}")
+ @logger.error("Failed to finish plan #{plan_job}: #{e.message}")
end
def run_task_job(targets, task, arguments, options)
# unpack any Sensitive data
arguments = unwrap_sensitive_args(arguments)
@@ -41,10 +42,26 @@
targets.map do |target|
Bolt::Result.from_exception(target, e)
end
end
+ def get(url)
+ response = @http.get(url)
+ if response.status != 200
+ raise Bolt::Error.new(response.body['msg'], response.body['kind'], response.body['details'])
+ end
+ response.body
+ end
+
+ def post_command(url, body)
+ response = @http.post(url, body)
+ if response.status != 202
+ raise Bolt::Error.new(response.body['msg'], response.body['kind'], response.body['details'])
+ end
+ response.body
+ end
+
def send_request(targets, task, arguments, options = {})
description = options['_description']
body = { task: task.name,
environment: @environment,
noop: arguments['_noop'],
@@ -53,11 +70,19 @@
nodes: targets.map(&:host)
} }
body[:description] = description if description
body[:plan_job] = @plan_job if @plan_job
- @client.run_task(body)
+ url = post_command('internal/plan_task', body).dig('job', 'id')
+
+ job = get(url)
+ until %w[stopped finished failed].include?(job['state'])
+ sleep 1
+ job = get(url)
+ end
+
+ get(job.dig('nodes', 'id'))['items']
end
def process_run_results(targets, results)
targets_by_name = Hash[targets.map(&:host).zip(targets)]
results.map do |node_result|
@@ -97,11 +122,12 @@
def run_script(targets, script, arguments, options = {})
content = File.open(script, &:read)
content = Base64.encode64(content)
params = {
'content' => content,
- 'arguments' => arguments
+ 'arguments' => arguments,
+ 'name' => Pathname(script).basename.to_s
}
callback ||= proc {}
results = run_task_job(targets, BOLT_SCRIPT_TASK, params, options, &callback)
results.map! { |result| unwrap_bolt_result(result.target, result) }
results.each do |result|
@@ -202,10 +228,10 @@
Bolt::Result.for_command(target, result.value['stdout'], result.value['stderr'], result.value['exit_code'])
end
def connected?(targets)
- nodes = @client.post('inventory', nodes: targets.map(&:host))
- nodes['items'].all? { |node| node['connected'] }
+ response = @http.post('inventory', nodes: targets.map(&:host))
+ response.body['items'].all? { |node| node['connected'] }
end
end
end