foreman_remote_execution 3.0.2 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +2 -1
  3. data/.rubocop.yml +80 -50
  4. data/.rubocop_todo.yml +113 -73
  5. data/Gemfile +4 -0
  6. data/app/controllers/api/v2/foreign_input_sets_controller.rb +3 -2
  7. data/app/controllers/api/v2/job_invocations_controller.rb +12 -7
  8. data/app/controllers/api/v2/job_templates_controller.rb +3 -2
  9. data/app/controllers/api/v2/remote_execution_features_controller.rb +3 -2
  10. data/app/controllers/api/v2/template_invocations_controller.rb +5 -2
  11. data/app/controllers/cockpit_controller.rb +1 -0
  12. data/app/controllers/concerns/foreman/controller/parameters/foreign_input_set.rb +1 -1
  13. data/app/controllers/concerns/foreman/controller/parameters/job_template.rb +4 -4
  14. data/app/controllers/job_invocations_controller.rb +10 -6
  15. data/app/controllers/job_templates_controller.rb +1 -1
  16. data/app/controllers/remote_execution_features_controller.rb +3 -2
  17. data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +16 -5
  18. data/app/helpers/job_invocations_chart_helper.rb +13 -10
  19. data/app/helpers/job_invocations_helper.rb +19 -6
  20. data/app/helpers/remote_execution_helper.rb +49 -48
  21. data/app/lib/actions/remote_execution/run_host_job.rb +5 -6
  22. data/app/lib/actions/remote_execution/run_hosts_job.rb +2 -2
  23. data/app/lib/foreman_remote_execution/renderer/scope/input.rb +1 -0
  24. data/app/lib/proxy_api/remote_execution_ssh.rb +6 -0
  25. data/app/models/concerns/foreman_remote_execution/errors_flattener.rb +0 -2
  26. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +4 -6
  27. data/app/models/concerns/foreman_remote_execution/nic_extensions.rb +1 -0
  28. data/app/models/concerns/foreman_remote_execution/orchestration/ssh.rb +63 -0
  29. data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +5 -0
  30. data/app/models/foreign_input_set.rb +3 -2
  31. data/app/models/host_status/execution_status.rb +9 -1
  32. data/app/models/input_template_renderer.rb +1 -1
  33. data/app/models/job_invocation.rb +10 -12
  34. data/app/models/job_invocation_composer.rb +20 -14
  35. data/app/models/job_invocation_task_group.rb +1 -1
  36. data/app/models/job_template.rb +3 -3
  37. data/app/models/remote_execution_feature.rb +0 -2
  38. data/app/models/remote_execution_provider.rb +4 -2
  39. data/app/models/setting/remote_execution.rb +54 -56
  40. data/app/models/ssh_execution_provider.rb +2 -2
  41. data/app/models/targeting.rb +1 -0
  42. data/app/models/template_invocation.rb +2 -3
  43. data/app/views/api/v2/job_invocations/base.json.rabl +1 -1
  44. data/app/views/api/v2/job_invocations/main.json.rabl +7 -4
  45. data/app/views/job_invocations/_card_results.html.erb +1 -0
  46. data/app/views/job_invocations/_card_target_hosts.html.erb +12 -0
  47. data/app/views/job_invocations/_card_user_input.html.erb +1 -1
  48. data/app/views/job_invocations/_form.html.erb +3 -2
  49. data/app/views/job_invocations/_host_status_td.html.erb +1 -1
  50. data/app/views/job_invocations/_rerun_taxonomies.html.erb +22 -0
  51. data/app/views/job_invocations/_tab_overview.html.erb +1 -1
  52. data/app/views/job_invocations/_user_input.html.erb +1 -1
  53. data/app/views/job_invocations/show.html.erb +3 -1
  54. data/config/routes.rb +2 -1
  55. data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +1 -0
  56. data/db/migrate/20180110104432_rename_template_invocation_permission.rb +1 -0
  57. data/db/seeds.d/50-notification_blueprints.rb +4 -4
  58. data/db/seeds.d/90-bookmarks.rb +1 -0
  59. data/extra/cockpit/foreman-cockpit-session +7 -2
  60. data/foreman_remote_execution.gemspec +1 -1
  61. data/lib/foreman_remote_execution/engine.rb +20 -17
  62. data/lib/foreman_remote_execution/version.rb +1 -1
  63. data/locale/action_names.rb +4 -3
  64. data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  65. data/locale/de/foreman_remote_execution.po +65 -16
  66. data/locale/en/foreman_remote_execution.po +63 -15
  67. data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  68. data/locale/en_GB/foreman_remote_execution.po +64 -15
  69. data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  70. data/locale/es/foreman_remote_execution.po +66 -17
  71. data/locale/foreman_remote_execution.pot +193 -148
  72. data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  73. data/locale/fr/foreman_remote_execution.po +66 -17
  74. data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  75. data/locale/ja/foreman_remote_execution.po +66 -17
  76. data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  77. data/locale/ko/foreman_remote_execution.po +65 -15
  78. data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  79. data/locale/pt_BR/foreman_remote_execution.po +66 -17
  80. data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  81. data/locale/ru/foreman_remote_execution.po +65 -18
  82. data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  83. data/locale/zh_CN/foreman_remote_execution.po +66 -17
  84. data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  85. data/locale/zh_TW/foreman_remote_execution.po +65 -16
  86. data/package.json +2 -3
  87. data/test/benchmark/run_hosts_job_benchmark.rb +1 -1
  88. data/test/factories/foreman_remote_execution_factories.rb +1 -1
  89. data/test/functional/api/v2/job_invocations_controller_test.rb +51 -23
  90. data/test/functional/api/v2/job_templates_controller_test.rb +1 -1
  91. data/test/functional/api/v2/remote_execution_features_controller_test.rb +2 -2
  92. data/test/functional/api/v2/template_invocations_controller_test.rb +4 -4
  93. data/test/functional/job_invocations_controller_test.rb +23 -11
  94. data/test/functional/job_templates_controller_test.rb +1 -1
  95. data/test/models/orchestration/ssh_test.rb +56 -0
  96. data/test/unit/actions/run_hosts_job_test.rb +8 -8
  97. data/test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb +3 -3
  98. data/test/unit/concerns/host_extensions_test.rb +26 -19
  99. data/test/unit/concerns/nic_extensions_test.rb +1 -1
  100. data/test/unit/execution_task_status_mapper_test.rb +10 -10
  101. data/test/unit/input_template_renderer_test.rb +77 -77
  102. data/test/unit/job_invocation_composer_test.rb +100 -96
  103. data/test/unit/job_invocation_test.rb +29 -29
  104. data/test/unit/job_template_effective_user_test.rb +3 -3
  105. data/test/unit/job_template_test.rb +31 -31
  106. data/test/unit/remote_execution_feature_test.rb +19 -19
  107. data/test/unit/remote_execution_provider_test.rb +33 -30
  108. data/test/unit/renderer_scope_input.rb +6 -6
  109. data/test/unit/targeting_test.rb +6 -6
  110. data/test/unit/template_invocation_input_value_test.rb +3 -3
  111. data/webpack/index.js +0 -15
  112. metadata +8 -4
@@ -2,7 +2,7 @@ class JobInvocationTaskGroup < ::ForemanTasks::TaskGroup
2
2
 
3
3
  has_one :job_invocation, :foreign_key => :task_group_id, :dependent => :nullify
4
4
 
5
- alias resource job_invocation
5
+ alias_method :resource, :job_invocation
6
6
 
7
7
  def resource_name
8
8
  N_('Job Invocation')
@@ -7,8 +7,8 @@ class JobTemplate < ::Template
7
7
  end
8
8
 
9
9
  attr_exportable :job_category, :description_format,
10
- :foreign_input_sets, :provider_type,
11
- { :kind => ->(template) { template.class.name.underscore } }.merge(taxonomy_exportable)
10
+ :foreign_input_sets, :provider_type,
11
+ { :kind => ->(template) { template.class.name.underscore } }.merge(taxonomy_exportable)
12
12
 
13
13
  include Authorizable
14
14
  extend FriendlyId
@@ -65,7 +65,7 @@ class JobTemplate < ::Template
65
65
 
66
66
  def import_raw!(contents, options = {})
67
67
  template = import_raw(contents, options)
68
- template.save! if template
68
+ template&.save!
69
69
  template
70
70
  end
71
71
 
@@ -23,7 +23,6 @@ class RemoteExecutionFeature < ApplicationRecord
23
23
  self.find_by(label: label) || raise(::Foreman::Exception.new(N_('Unknown remote execution feature %s'), label))
24
24
  end
25
25
 
26
- # rubocop:disable Metrics/PerceivedComplexity
27
26
  def self.register(label, name, options = {})
28
27
  begin
29
28
  return false unless RemoteExecutionFeature.table_exists?
@@ -61,5 +60,4 @@ class RemoteExecutionFeature < ApplicationRecord
61
60
  return feature
62
61
  end
63
62
  end
64
- # rubocop:enable Metrics/PerceivedComplexity
65
63
  end
@@ -89,9 +89,11 @@ class RemoteExecutionProvider
89
89
  host.host_param(setting.to_s) || Setting[setting]
90
90
  end
91
91
 
92
- def ssh_password(_host) end
92
+ def ssh_password(_host)
93
+ end
93
94
 
94
- def ssh_key_passphrase(_host) end
95
+ def ssh_key_passphrase(_host)
96
+ end
95
97
 
96
98
  def proxy_action_class
97
99
  ForemanRemoteExecutionCore::Actions::RunScript
@@ -2,79 +2,77 @@ class Setting::RemoteExecution < Setting
2
2
 
3
3
  ::Setting::BLANK_ATTRS.concat %w{remote_execution_ssh_password remote_execution_ssh_key_passphrase remote_execution_sudo_password remote_execution_cockpit_url remote_execution_form_job_template}
4
4
 
5
- # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
6
5
  def self.default_settings
7
6
  [
8
7
  self.set('remote_execution_fallback_proxy',
9
- N_('Search the host for any proxy with Remote Execution, useful when the host has no subnet or the subnet does not have an execution proxy'),
10
- false,
11
- N_('Fallback to Any Proxy')),
8
+ N_('Search the host for any proxy with Remote Execution, useful when the host has no subnet or the subnet does not have an execution proxy'),
9
+ false,
10
+ N_('Fallback to Any Proxy')),
12
11
  self.set('remote_execution_global_proxy',
13
- N_('Search for remote execution proxy outside of the proxies assigned to the host. ' +
14
- "The search will be limited to the host's organization and location."),
15
- true,
16
- N_('Enable Global Proxy')),
12
+ N_('Search for remote execution proxy outside of the proxies assigned to the host. ' +
13
+ "The search will be limited to the host's organization and location."),
14
+ true,
15
+ N_('Enable Global Proxy')),
17
16
  self.set('remote_execution_ssh_user',
18
- N_('Default user to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_user.'),
19
- 'root',
20
- N_('SSH User')),
17
+ N_('Default user to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_user.'),
18
+ 'root',
19
+ N_('SSH User')),
21
20
  self.set('remote_execution_effective_user',
22
- N_('Default user to use for executing the script. If the user differs from the SSH user, su or sudo is used to switch the user.'),
23
- 'root',
24
- N_('Effective User')),
21
+ N_('Default user to use for executing the script. If the user differs from the SSH user, su or sudo is used to switch the user.'),
22
+ 'root',
23
+ N_('Effective User')),
25
24
  self.set('remote_execution_effective_user_method',
26
- N_('What command should be used to switch to the effective user. One of %s') % SSHExecutionProvider::EFFECTIVE_USER_METHODS.inspect,
27
- 'sudo',
28
- N_('Effective User Method'),
29
- nil,
30
- { :collection => proc { Hash[SSHExecutionProvider::EFFECTIVE_USER_METHODS.map { |method| [method, method] }] } }),
25
+ N_('What command should be used to switch to the effective user. One of %s') % SSHExecutionProvider::EFFECTIVE_USER_METHODS.inspect,
26
+ 'sudo',
27
+ N_('Effective User Method'),
28
+ nil,
29
+ { :collection => proc { Hash[SSHExecutionProvider::EFFECTIVE_USER_METHODS.map { |method| [method, method] }] } }),
31
30
  self.set('remote_execution_sudo_password', N_("Sudo password"), '', N_("Sudo password"), nil, {:encrypted => true}),
32
31
  self.set('remote_execution_sync_templates',
33
- N_('Whether we should sync templates from disk when running db:seed.'),
34
- true,
35
- N_('Sync Job Templates')),
32
+ N_('Whether we should sync templates from disk when running db:seed.'),
33
+ true,
34
+ N_('Sync Job Templates')),
36
35
  self.set('remote_execution_ssh_port',
37
- N_('Port to use for SSH communication. Default port 22. You may override per host by setting a parameter called remote_execution_ssh_port.'),
38
- '22',
39
- N_('SSH Port')),
36
+ N_('Port to use for SSH communication. Default port 22. You may override per host by setting a parameter called remote_execution_ssh_port.'),
37
+ '22',
38
+ N_('SSH Port')),
40
39
  self.set('remote_execution_connect_by_ip',
41
- N_('Should the ip addresses on host interfaces be preferred over the fqdn? '\
42
- 'It is useful, when DNS not resolving the fqdns properly. You may override this per host by setting a parameter called remote_execution_connect_by_ip.'),
43
- false,
44
- N_('Connect by IP')),
40
+ N_('Should the ip addresses on host interfaces be preferred over the fqdn? '\
41
+ 'It is useful when DNS not resolving the fqdns properly. You may override this per host by setting a parameter called remote_execution_connect_by_ip. '\
42
+ 'This setting only applies to IPv4. When the host has only an IPv6 address on the interface used for remote execution, hostname will be used even if this setting is set to true.'),
43
+ false,
44
+ N_('Connect by IP')),
45
45
  self.set('remote_execution_ssh_password',
46
- N_('Default password to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_password'),
47
- nil,
48
- N_('Default SSH password'),
49
- nil,
50
- { :encrypted => true }),
46
+ N_('Default password to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_password'),
47
+ nil,
48
+ N_('Default SSH password'),
49
+ nil,
50
+ { :encrypted => true }),
51
51
  self.set('remote_execution_ssh_key_passphrase',
52
- N_('Default key passphrase to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_key_passphrase'),
53
- nil,
54
- N_('Default SSH key passphrase'),
55
- nil,
56
- { :encrypted => true }),
52
+ N_('Default key passphrase to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_key_passphrase'),
53
+ nil,
54
+ N_('Default SSH key passphrase'),
55
+ nil,
56
+ { :encrypted => true }),
57
57
  self.set('remote_execution_workers_pool_size',
58
- N_('Amount of workers in the pool to handle the execution of the remote execution jobs. Restart of the dynflowd/foreman-tasks service is required.'),
59
- 5,
60
- N_('Workers pool size')),
58
+ N_('Amount of workers in the pool to handle the execution of the remote execution jobs. Restart of the dynflowd/foreman-tasks service is required.'),
59
+ 5,
60
+ N_('Workers pool size')),
61
61
  self.set('remote_execution_cleanup_working_dirs',
62
- N_('When enabled, working directories will be removed after task completion. You may override this per host by setting a parameter called remote_execution_cleanup_working_dirs.'),
63
- true,
64
- N_('Cleanup working directories')),
62
+ N_('When enabled, working directories will be removed after task completion. You may override this per host by setting a parameter called remote_execution_cleanup_working_dirs.'),
63
+ true,
64
+ N_('Cleanup working directories')),
65
65
  self.set('remote_execution_cockpit_url',
66
- N_('Where to find the Cockpit instance for the Web Console button. By default, no button is shown.'),
67
- nil,
68
- N_('Cockpit URL'),
69
- nil),
66
+ N_('Where to find the Cockpit instance for the Web Console button. By default, no button is shown.'),
67
+ nil,
68
+ N_('Cockpit URL'),
69
+ nil),
70
70
  self.set('remote_execution_form_job_template',
71
- N_('Choose a job template that is pre-selected in job invocation form'),
72
- 'Run Command - SSH Default',
73
- _('Form Job Template'),
74
- nil,
75
- { :collection => proc { Hash[JobTemplate.unscoped.map { |template| [template.name, template.name] }] } })
71
+ N_('Choose a job template that is pre-selected in job invocation form'),
72
+ 'Run Command - SSH Default',
73
+ _('Form Job Template'),
74
+ nil,
75
+ { :collection => proc { Hash[JobTemplate.unscoped.map { |template| [template.name, template.name] }] } }),
76
76
  ]
77
77
  end
78
- # rubocop:enable AbcSize
79
- # rubocop:enable Metrics/MethodLength,Metrics/AbcSize
80
78
  end
@@ -32,7 +32,7 @@ class SSHExecutionProvider < RemoteExecutionProvider
32
32
  {
33
33
  :ssh_password => ssh_password(host),
34
34
  :key_passphrase => ssh_key_passphrase(host),
35
- :sudo_password => sudo_password(host)
35
+ :sudo_password => sudo_password(host),
36
36
  }
37
37
  end
38
38
 
@@ -45,7 +45,7 @@ class SSHExecutionProvider < RemoteExecutionProvider
45
45
  :ssh_user => ssh_user(host),
46
46
  :ssh_port => ssh_port(host),
47
47
  :ssh_password => ssh_password(host),
48
- :ssh_key_passphrase => ssh_key_passphrase(host)
48
+ :ssh_key_passphrase => ssh_key_passphrase(host),
49
49
  }
50
50
  end
51
51
 
@@ -61,6 +61,7 @@ class Targeting < ApplicationRecord
61
61
 
62
62
  def self.build_query_from_hosts(ids)
63
63
  return '' if ids.empty?
64
+
64
65
  hosts = Host.where(:id => ids).distinct.pluck(:name)
65
66
  "name ^ (#{hosts.join(', ')})"
66
67
  end
@@ -31,13 +31,12 @@ class TemplateInvocation < ApplicationRecord
31
31
  :error => :failed,
32
32
  :pending => :pending,
33
33
  :success => :success,
34
- :warning => :failed
34
+ :warning => :failed,
35
35
  }.with_indifferent_access
36
36
 
37
- REVERSE_MAP = MAP.reduce({}) do |acc, (key, value)|
37
+ REVERSE_MAP = MAP.each_with_object({}) do |(key, value), acc|
38
38
  acc[value] ||= []
39
39
  acc[value] << key
40
- acc
41
40
  end.with_indifferent_access
42
41
 
43
42
  class << self
@@ -7,7 +7,7 @@ node do |invocation|
7
7
  :succeeded => invocation_count(invocation, :output_key => :success_count),
8
8
  :failed => invocation_count(invocation, :output_key => :failed_count),
9
9
  :pending => invocation_count(invocation, :output_key => :pending_count),
10
- :total => invocation_count(invocation, :output_key => :total_count)
10
+ :total => invocation_count(invocation, :output_key => :total_count),
11
11
  }
12
12
  end
13
13
 
@@ -17,9 +17,9 @@ end
17
17
 
18
18
  child :targeting do
19
19
  attributes :bookmark_id, :search_query, :targeting_type, :user_id, :status, :status_label,
20
- :randomized_ordering
20
+ :randomized_ordering
21
21
 
22
- child :hosts do
22
+ child @hosts do
23
23
  extends 'api/v2/hosts/base'
24
24
  end
25
25
  end
@@ -28,9 +28,12 @@ child :task do
28
28
  attributes :id, :state
29
29
  end
30
30
 
31
- child :template_invocations do
31
+ child @template_invocations do
32
32
  attributes :template_id, :template_name
33
33
  child :input_values do
34
- attributes :template_input_name, :template_input_id, :value
34
+ attributes :template_input_name, :template_input_id
35
+ node :value do |iv|
36
+ iv.template_input.respond_to?(:hidden_value) && iv.template_input.hidden_value? ? '*' * 5 : iv.value
37
+ end
35
38
  end
36
39
  end
@@ -5,6 +5,7 @@
5
5
  </h2>
6
6
  <div class="card-pf-body">
7
7
  <div id='status_chart'>
8
+ <%= react_component('JobInvocationContainer', data: { url: "/job_invocations/chart?id=#{job_invocation.id}" }) %>
8
9
  </div>
9
10
  </div>
10
11
  </div>
@@ -20,6 +20,18 @@
20
20
  <% key = job_invocation.targeting.randomized_ordering ? Targeting::RANDOMIZED : Targeting::ORDERED %>
21
21
  <%= _('Execution order') %>: <strong><%= Targeting::ORDERINGS[key].downcase %></strong>
22
22
  </p>
23
+ <p>
24
+ <%= _('Organization') %>:
25
+ <strong>
26
+ <%= show_job_organization(@job_organization) %>
27
+ </strong>
28
+ </p>
29
+ <p>
30
+ <%= _('Location') %>:
31
+ <strong>
32
+ <%= show_job_location(@job_location) %>
33
+ </strong>
34
+ </p>
23
35
  </div>
24
36
  <div class='card-pf-footer'>
25
37
  <p>
@@ -8,7 +8,7 @@
8
8
  <p>
9
9
  <ul>
10
10
  <% template_invocation.input_values.joins(:template_input).each do |input_value| %>
11
- <li><b><%= input_value.template_input.name %></b>: <%= trunc_with_tooltip(input_value.value, 255) %></li>
11
+ <li><b><%= input_value.template_input.name %></b>: <%= trunc_with_tooltip(input_safe_value(input_value), 255) %></li>
12
12
  <% end %>
13
13
  </ul>
14
14
  </p>
@@ -99,8 +99,8 @@
99
99
  </div>
100
100
 
101
101
  <div class="advanced hidden">
102
- <%= number_f f, :concurrency_level, :label => _('Concurrency level'), :placeholder => 'N', :min => 1, :label_help => N_("Run at most N tasks at a time") %>
103
- <%= number_f f, :time_span, :label => _('Time span'), :placeholder => 'N', :min => 1, :label_help => N_("Distribute execution over N seconds") %>
102
+ <%= number_f f, :concurrency_level, :label => _('Concurrency level'), :placeholder => 'N', :min => 1, :label_help => N_("Run at most N tasks at a time. If this is set and proxy batch triggering is enabled, then tasks are triggered on the smart proxy in batches of size 1.") %>
103
+ <%= number_f f, :time_span, :label => _('Time span'), :placeholder => 'N', :min => 1, :label_help => N_("Distribute execution over N seconds. If this is set and proxy batch triggering is enabled, then tasks are triggered on the smart proxy in batches of size 1.") %>
104
104
  </div>
105
105
 
106
106
  <div class="form-group advanced hidden">
@@ -126,5 +126,6 @@
126
126
 
127
127
  <%= render :partial => 'preview_hosts_modal' %>
128
128
 
129
+ <%= render partial: 'rerun_taxonomies' if action_name == 'rerun' %>
129
130
  <%= submit_or_cancel f, false, :cancel_path => job_invocations_path, :disabled => !@composer.rerun_possible? %>
130
131
  <% end %>
@@ -1 +1 @@
1
- <td class="host_status" id="<%= dom_id(host) %>-status" data-refresh_required="<%= task.nil? || task.pending? ? 'true' : '' %>" data-id="<%= host.id %>"><%= template_invocation_status(task) %></td>
1
+ <td class="host_status" id="<%= dom_id(host) %>-status" data-refresh_required="<%= task.nil? || task.pending? ? 'true' : '' %>" data-id="<%= host.id %>"><%= template_invocation_status(task, job_invocation.task) %></td>
@@ -0,0 +1,22 @@
1
+ <% if Organization.current != @job_organization %>
2
+ <div class="form-group">
3
+ <div class="col-md-6">
4
+ <div class="alert alert-warning">
5
+ <span class="pficon pficon-warning-triangle-o"></span>
6
+ <%= _("Current organization %{org_c} is different from job's organization %{org_j}.") % { org_c: show_job_organization(Organization.current),
7
+ org_j: show_job_organization(@job_organization) } %>
8
+ </div>
9
+ </div>
10
+ </div>
11
+ <% end %>
12
+ <% if Location.current != @job_location %>
13
+ <div class="form-group">
14
+ <div class="col-md-6">
15
+ <div class="alert alert-warning">
16
+ <span class="pficon pficon-warning-triangle-o"></span>
17
+ <%= _("Current location %{loc_c} is different from job's location %{loc_j}.") % { loc_c: show_job_location(Location.current),
18
+ loc_j: show_job_location(@job_location) } %>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ <% end %>
@@ -1,7 +1,7 @@
1
1
  <% template_invocations = job_invocation.pattern_template_invocations %>
2
2
  <div class='row'>
3
3
  <div class="col-xs-6 col-sm-6 col-md-6">
4
- <%= render :partial => 'card_results' %>
4
+ <%= render :partial => 'card_results', :locals => { :job_invocation => job_invocation } %>
5
5
  <%= render :partial => 'card_schedule', :locals => { :job_invocation => job_invocation } %>
6
6
  </div>
7
7
  <div class='col-xs-12 col-sm-6 col-md-6'>
@@ -12,7 +12,7 @@
12
12
  <% template_invocation.input_values.joins(:template_input).each do |input_value| %>
13
13
  <tr>
14
14
  <td><b><%= input_value.template_input.name %></b></td>
15
- <td><%= input_value.value %></td>
15
+ <td><%= input_safe_value(input_value) %></td>
16
16
  </tr>
17
17
  <% end %>
18
18
  </tbody>
@@ -1,7 +1,7 @@
1
1
  <% title @job_invocation.description %>
2
2
  <% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
3
3
  <% javascript 'charts', 'foreman_remote_execution/template_invocation' %>
4
- <%= javascript_include_tag *webpack_asset_paths('foreman_remote_execution', :extension => 'js'), "data-turbolinks-track" => true, 'defer' => 'defer' %>
4
+ <% javascript *webpack_asset_paths('foreman_remote_execution', :extension => 'js') %>
5
5
 
6
6
  <%= breadcrumbs name_field: 'description' %>
7
7
 
@@ -19,6 +19,7 @@
19
19
  <% if @job_invocation.recurring_logic.present? %>
20
20
  <li><a href="#recurring_logic" data-toggle="tab"><%= _('Recurring logic') %></a></li>
21
21
  <% end %>
22
+ <%= render_tab_header_for(:main_tabs, subject: @job_invocation) %>
22
23
  </ul>
23
24
 
24
25
  <div class="tab-content">
@@ -38,6 +39,7 @@
38
39
  </div>
39
40
  </div>
40
41
  <% end %>
42
+ <%= render_tab_content_for(:main_tabs, subject: @job_invocation) %>
41
43
  </div>
42
44
 
43
45
  <script id="job_invocation_refresh" data-refresh-url="<%= job_invocation_path(@job_invocation) %>">
@@ -16,7 +16,8 @@ Rails.application.routes.draw do
16
16
  end
17
17
  end
18
18
 
19
- resources :job_invocations, :only => [:new, :create, :show, :index] do
19
+ match 'job_invocations/new', to: 'job_invocations#new', via: [:get, :post], as: 'new_job_invocation'
20
+ resources :job_invocations, :only => [:create, :show, :index] do
20
21
  collection do
21
22
  post 'refresh'
22
23
  get 'chart'
@@ -15,6 +15,7 @@ class AddHostIdToTemplateInvocation < ActiveRecord::Migration[4.2]
15
15
  :'foreman_tasks_locks.resource_id' => template_invocation.id
16
16
  ).first
17
17
  next if task.nil? # skip invocations from very early versions of remote executions
18
+
18
19
  host_id = task.locks.where(:'foreman_tasks_locks.resource_type' => 'Host::Managed').first.resource_id
19
20
  next unless Host.find_by(id: host_id)
20
21
 
@@ -14,6 +14,7 @@ class RenameTemplateInvocationPermission < ActiveRecord::Migration[4.2]
14
14
  def switch_filtering_permission!(old, new)
15
15
  old_permission = Permission.find_by(:name => old)
16
16
  return if old_permission.nil?
17
+
17
18
  new_permission = Permission.find_or_create_by(:name => new,
18
19
  :resource_type => 'TemplateInvocation')
19
20
  old_permission.filterings.each do |filtering|
@@ -9,10 +9,10 @@ blueprints = [
9
9
  links:
10
10
  [
11
11
  path_method: :job_invocation_path,
12
- title: N_('Job Details')
13
- ]
14
- }
15
- }
12
+ title: N_('Job Details'),
13
+ ],
14
+ },
15
+ },
16
16
  ]
17
17
 
18
18
  blueprints.each { |blueprint| UINotifications::Seed.new(blueprint).configure }