Class: Actions::ProxyAction

Inherits:
Base
  • Object
show all
Includes:
Dynflow::Action::Cancellable, Dynflow::Action::Timeouts
Defined in:
app/lib/actions/proxy_action.rb

Defined Under Namespace

Classes: CallbackData

Instance Method Summary collapse

Methods inherited from Base

#already_running?, #humanized_errors, #humanized_input, #humanized_name, #humanized_output, #task, #task_input, #task_output

Instance Method Details

#cancel_proxy_taskObject



72
73
74
75
76
77
78
79
80
# File 'app/lib/actions/proxy_action.rb', line 72

def cancel_proxy_task
  if output[:cancel_sent]
    error! ForemanTasks::Task::TaskCancelledException.new(_("Cancel enforced: the task might be still running on the proxy"))
  else
    proxy.cancel_task(output[:proxy_task_id])
    output[:cancel_sent] = true
    suspend
  end
end

#check_task_statusObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'app/lib/actions/proxy_action.rb', line 55

def check_task_status
  if output[:proxy_task_id]
    response = proxy.status_of_task(output[:proxy_task_id])
    if %w(stopped paused).include? response['state']
      if response['result'] == 'error'
        raise ::Foreman::Exception, _("The smart proxy task '#{output[:proxy_task_id]}' failed.")
      else
        on_data(response['actions'].find { |block_action| block_action['class'] == proxy_action_name }['output'])
      end
    else
      suspend
    end
  else
    process_timeout
  end
end

#default_connection_optionsObject



129
130
131
132
133
134
135
# File 'app/lib/actions/proxy_action.rb', line 129

def default_connection_options
  # Fails if the plan is not finished within 60 seconds from the first task trigger attempt on the smart proxy
  # If the triggering fails, it retries 3 more times with 15 second delays
  { :retry_interval => Setting['foreman_tasks_proxy_action_retry_interval'] || 15,
    :retry_count    => Setting['foreman_tasks_proxy_action_retry_count' ]   || 4,
    :timeout        => Setting['foreman_tasks_proxy_action_start_timeout']  || 60 }
end

#metadataObject



109
110
111
112
# File 'app/lib/actions/proxy_action.rb', line 109

def 
  output[:metadata] ||= {}
  output[:metadata]
end

#metadata=(thing) ⇒ Object



114
115
116
117
# File 'app/lib/actions/proxy_action.rb', line 114

def metadata=(thing)
  output[:metadata] ||= {}
  output[:metadata] = thing
end

#on_data(data) ⇒ Object



88
89
90
# File 'app/lib/actions/proxy_action.rb', line 88

def on_data(data)
  output[:proxy_output] = data
end

#on_resumeObject



82
83
84
85
# File 'app/lib/actions/proxy_action.rb', line 82

def on_resume
  # TODO: add logic to load the data from the external action
  suspend
end

#plan(proxy, options) ⇒ Object



15
16
17
18
19
# File 'app/lib/actions/proxy_action.rb', line 15

def plan(proxy, options)
  options[:connection_options] ||= {}
  default_connection_options.each { |key, value| options[:connection_options][key] ||= value }
  plan_self(options.merge(:proxy_url => proxy.url))
end

#proxyObject



97
98
99
# File 'app/lib/actions/proxy_action.rb', line 97

def proxy
  ProxyAPI::ForemanDynflow::DynflowProxy.new(:url => input[:proxy_url])
end

#proxy_action_nameObject

Raises:

  • (NotImplemented)


93
94
95
# File 'app/lib/actions/proxy_action.rb', line 93

def proxy_action_name
  raise NotImplemented
end

#proxy_outputObject



101
102
103
# File 'app/lib/actions/proxy_action.rb', line 101

def proxy_output
  output[:proxy_output]
end

#proxy_output=(output) ⇒ Object



105
106
107
# File 'app/lib/actions/proxy_action.rb', line 105

def proxy_output=(output)
  output[:proxy_output] = output
end

#run(event = nil) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/lib/actions/proxy_action.rb', line 21

def run(event = nil)
  with_connection_error_handling(event) do |event|
    case event
    when nil
      if output[:proxy_task_id]
        on_resume
      else
        trigger_proxy_task
      end
      suspend
    when ::Dynflow::Action::Skip
      # do nothing
    when ::Dynflow::Action::Cancellable::Cancel
      cancel_proxy_task
    when CallbackData
      on_data(event.data)
    when ::Dynflow::Action::Timeouts::Timeout
      check_task_status
    else
      raise "Unexpected event #{event.inspect}"
    end
  end
end

#set_timeout!Object



123
124
125
126
127
# File 'app/lib/actions/proxy_action.rb', line 123

def set_timeout!
  time = Time.now + input[:connection_options][:timeout]
  schedule_timeout(time)
  [:timeout] = time.to_s
end

#timeout_set?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'app/lib/actions/proxy_action.rb', line 119

def timeout_set?
  ![:timeout].nil?
end

#trigger_proxy_taskObject



45
46
47
48
49
50
51
52
53
# File 'app/lib/actions/proxy_action.rb', line 45

def trigger_proxy_task
  suspend do |_suspended_action|
    set_timeout! unless timeout_set?
    response = proxy.trigger_task(proxy_action_name,
                                  input.merge(:callback => { :task_id => task.id,
                                                             :step_id => run_step_id }))
    output[:proxy_task_id] = response["task_id"]
  end
end