foreman_remote_execution 4.6.0 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby_ci.yml +7 -0
- data/app/controllers/job_invocations_controller.rb +1 -1
- data/app/controllers/ui_job_wizard_controller.rb +7 -0
- data/app/graphql/types/job_invocation.rb +16 -0
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +5 -1
- data/app/helpers/remote_execution_helper.rb +9 -3
- data/app/lib/actions/remote_execution/run_host_job.rb +5 -1
- data/app/lib/actions/remote_execution/run_hosts_job.rb +1 -1
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +2 -0
- data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +6 -0
- data/app/models/host_proxy_invocation.rb +4 -0
- data/app/models/host_status/execution_status.rb +3 -3
- data/app/models/job_invocation.rb +9 -6
- data/app/models/job_invocation_composer.rb +4 -4
- data/app/models/job_template.rb +1 -1
- data/app/models/remote_execution_feature.rb +5 -1
- data/app/models/setting/remote_execution.rb +2 -2
- data/app/models/targeting.rb +5 -1
- data/app/views/job_invocations/index.html.erb +1 -1
- data/app/views/templates/ssh/module_action.erb +1 -0
- data/app/views/templates/ssh/power_action.erb +2 -0
- data/app/views/templates/ssh/puppet_run_once.erb +1 -0
- data/db/migrate/2021051713291621250977_add_host_proxy_invocations.rb +12 -0
- data/foreman_remote_execution.gemspec +2 -3
- data/lib/foreman_remote_execution/engine.rb +3 -2
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/test/graphql/queries/job_invocation_query_test.rb +31 -0
- data/test/graphql/queries/job_invocations_query_test.rb +35 -0
- data/test/unit/concerns/host_extensions_test.rb +4 -4
- data/test/unit/input_template_renderer_test.rb +1 -89
- data/test/unit/job_invocation_composer_test.rb +15 -13
- data/test/unit/job_invocation_test.rb +1 -1
- data/webpack/JobWizard/JobWizard.js +28 -8
- data/webpack/JobWizard/JobWizard.scss +39 -0
- data/webpack/JobWizard/JobWizardConstants.js +10 -0
- data/webpack/JobWizard/JobWizardSelectors.js +9 -0
- data/webpack/JobWizard/__tests__/fixtures.js +104 -2
- data/webpack/JobWizard/__tests__/integration.test.js +13 -85
- data/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js +21 -4
- data/webpack/JobWizard/steps/AdvancedFields/DescriptionField.js +67 -0
- data/webpack/JobWizard/steps/AdvancedFields/Fields.js +73 -59
- data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +135 -16
- data/webpack/JobWizard/steps/AdvancedFields/__tests__/DescriptionField.test.js +23 -0
- data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.test.js +122 -51
- data/webpack/JobWizard/steps/Schedule/QueryType.js +48 -0
- data/webpack/JobWizard/steps/Schedule/RepeatOn.js +61 -0
- data/webpack/JobWizard/steps/Schedule/ScheduleType.js +25 -0
- data/webpack/JobWizard/steps/Schedule/StartEndDates.js +51 -0
- data/webpack/JobWizard/steps/Schedule/__tests__/StartEndDates.test.js +22 -0
- data/webpack/JobWizard/steps/Schedule/index.js +41 -0
- data/webpack/JobWizard/steps/form/FormHelpers.js +1 -0
- data/webpack/JobWizard/steps/form/Formatter.js +149 -0
- data/webpack/JobWizard/steps/form/NumberInput.js +33 -0
- data/webpack/JobWizard/steps/form/SelectField.js +14 -2
- data/webpack/JobWizard/steps/form/__tests__/Formatter.test.js.example +76 -0
- data/webpack/__mocks__/foremanReact/components/SearchBar.js +18 -1
- data/webpack/react_app/components/RecentJobsCard/JobStatusIcon.js +43 -0
- data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +72 -66
- data/webpack/react_app/components/RecentJobsCard/RecentJobsTable.js +98 -0
- data/webpack/react_app/components/RecentJobsCard/constants.js +11 -0
- data/webpack/react_app/components/RecentJobsCard/styles.scss +11 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap +1 -0
- data/webpack/react_app/extend/fillRecentJobsCard.js +1 -1
- metadata +25 -16
- data/app/models/concerns/foreman_remote_execution/orchestration/ssh.rb +0 -70
- data/test/models/orchestration/ssh_test.rb +0 -56
- data/webpack/JobWizard/__tests__/JobWizard.test.js +0 -13
- data/webpack/JobWizard/__tests__/__snapshots__/JobWizard.test.js.snap +0 -32
- data/webpack/JobWizard/steps/AdvancedFields/__tests__/__snapshots__/AdvancedFields.test.js.snap +0 -249
- data/webpack/JobWizard/steps/CategoryAndTemplate/__snapshots__/CategoryAndTemplate.test.js.snap +0 -113
- data/webpack/JobWizard/steps/form/__tests__/GroupedSelectField.test.js +0 -38
- data/webpack/JobWizard/steps/form/__tests__/SelectField.test.js +0 -23
- data/webpack/JobWizard/steps/form/__tests__/__snapshots__/GroupedSelectField.test.js.snap +0 -37
- data/webpack/JobWizard/steps/form/__tests__/__snapshots__/SelectField.test.js.snap +0 -23
- data/webpack/react_app/components/RecentJobsCard/styles.css +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 742978171c8d62de9fdf9e14b2be742235dc1cce90c0c522871d65a90ee1f612
|
4
|
+
data.tar.gz: caae67492773457e26461ae6e39addec2cc1b105bf387a9cf0dbfc667ad25102
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e40d5600dbe09f3ea875179a3ac44a4046ffd8615efe5c88f364828e7bd21b24d2d2a7f5f8ea09954f2f00056bc6d867efc22f7b82b0189de766f225101ae896
|
7
|
+
data.tar.gz: 6875df7248f14be5a915f7b3001cd6d4a50476f84824b0118747d4ba7b2993b977cf85cfe5f9cdde8706b2d2cb4fea20c1770988405adebf09683cc966ba9e70
|
@@ -71,3 +71,10 @@ jobs:
|
|
71
71
|
run: |
|
72
72
|
bundle exec rake test:foreman_remote_execution
|
73
73
|
bundle exec rake test TEST="test/unit/foreman/access_permissions_test.rb"
|
74
|
+
- name: 'Upload logs'
|
75
|
+
uses: actions/upload-artifact@v2
|
76
|
+
if: failure()
|
77
|
+
with:
|
78
|
+
name: logs
|
79
|
+
path: log/*.log
|
80
|
+
retention-days: 5
|
@@ -67,7 +67,7 @@ class JobInvocationsController < ApplicationController
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def index
|
70
|
-
@job_invocations = resource_base_search_and_page.
|
70
|
+
@job_invocations = resource_base_search_and_page.preload(:task, :targeting).order('job_invocations.id DESC')
|
71
71
|
end
|
72
72
|
|
73
73
|
# refreshes the form
|
@@ -10,9 +10,12 @@ class UiJobWizardController < ::Api::V2::BaseController
|
|
10
10
|
|
11
11
|
def template
|
12
12
|
job_template = JobTemplate.authorized.find(params[:id])
|
13
|
+
advanced_template_inputs, template_inputs = map_template_inputs(job_template.template_inputs_with_foreign).partition { |x| x["advanced"] }
|
13
14
|
render :json => {
|
14
15
|
:job_template => job_template,
|
15
16
|
:effective_user => job_template.effective_user,
|
17
|
+
:template_inputs => template_inputs,
|
18
|
+
:advanced_template_inputs => advanced_template_inputs,
|
16
19
|
}
|
17
20
|
end
|
18
21
|
|
@@ -20,6 +23,10 @@ class UiJobWizardController < ::Api::V2::BaseController
|
|
20
23
|
nested_resource || 'job_template'
|
21
24
|
end
|
22
25
|
|
26
|
+
def map_template_inputs(template_inputs_with_foreign)
|
27
|
+
template_inputs_with_foreign.map { |input| input.attributes.merge({:resource_type => input.resource_type&.tableize }) }
|
28
|
+
end
|
29
|
+
|
23
30
|
def resource_class
|
24
31
|
JobTemplate
|
25
32
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Types
|
2
|
+
class JobInvocation < BaseObject
|
3
|
+
description 'A Job Invocation'
|
4
|
+
|
5
|
+
global_id_field :id
|
6
|
+
field :job_category, String
|
7
|
+
field :description, String
|
8
|
+
field :time_span, Integer
|
9
|
+
field :start_at, GraphQL::Types::ISO8601DateTime
|
10
|
+
field :status_label, String
|
11
|
+
|
12
|
+
belongs_to :triggering, Types::Triggering
|
13
|
+
belongs_to :task, Types::Task
|
14
|
+
field :recurring_logic, Types::RecurringLogic
|
15
|
+
end
|
16
|
+
end
|
@@ -7,7 +7,9 @@ module ForemanRemoteExecution
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def multiple_actions
|
10
|
-
|
10
|
+
res = super
|
11
|
+
res += [ [_('Schedule Remote Job'), new_job_invocation_path, false] ] if authorized_for(controller: :job_invocations, action: :new)
|
12
|
+
res
|
11
13
|
end
|
12
14
|
|
13
15
|
def schedule_job_multi_button(*args)
|
@@ -21,12 +23,14 @@ module ForemanRemoteExecution
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def rex_host_features(*args)
|
26
|
+
return unless authorized_for(controller: :job_invocations, action: :create)
|
24
27
|
RemoteExecutionFeature.with_host_action_button.order(:label).map do |feature|
|
25
28
|
link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [args.first.id], :feature => feature.label), :method => :post)
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
32
|
def schedule_job_button(*args)
|
33
|
+
return unless authorized_for(controller: :job_invocations, action: :new)
|
30
34
|
link_to(_('Schedule Remote Job'), new_job_invocation_path(:host_ids => [args.first.id]), :id => :run_button, :class => 'btn btn-default')
|
31
35
|
end
|
32
36
|
|
@@ -7,6 +7,10 @@ module RemoteExecutionHelper
|
|
7
7
|
@job_hosts_authorizer ||= Authorizer.new(User.current, :collection => @hosts)
|
8
8
|
end
|
9
9
|
|
10
|
+
def host_tasks_authorizer
|
11
|
+
@host_tasks_authorizer ||= Authorizer.new(User.current, :collection => @job_invocation.sub_tasks)
|
12
|
+
end
|
13
|
+
|
10
14
|
def host_counter(label, count)
|
11
15
|
content_tag(:div, :class => 'host_counter') do
|
12
16
|
content_tag(:div, label, :class => 'header') + content_tag(:div, count.to_s, :class => 'count')
|
@@ -36,7 +40,7 @@ module RemoteExecutionHelper
|
|
36
40
|
'data-method': 'get', id: "#{host.name}-actions-rerun" } }
|
37
41
|
end
|
38
42
|
|
39
|
-
if host_task.present? && authorized_for(hash_for_foreman_tasks_task_path(host_task).merge(auth_object: host_task, permission: :view_foreman_tasks))
|
43
|
+
if host_task.present? && authorized_for(hash_for_foreman_tasks_task_path(host_task).merge(auth_object: host_task, permission: :view_foreman_tasks, authorizer: host_tasks_authorizer))
|
40
44
|
links << { title: _('Host task'),
|
41
45
|
action: { href: foreman_tasks_task_path(host_task),
|
42
46
|
'data-method': 'get', id: "#{host.name}-actions-task" } }
|
@@ -109,12 +113,14 @@ module RemoteExecutionHelper
|
|
109
113
|
:class => 'btn btn-danger',
|
110
114
|
:title => _('Try to cancel the job on a host'),
|
111
115
|
:disabled => !task.cancellable?,
|
112
|
-
:method => :post
|
116
|
+
:method => :post,
|
117
|
+
:remote => true)
|
113
118
|
buttons << link_to(_('Abort Job'), abort_foreman_tasks_task_path(task),
|
114
119
|
:class => 'btn btn-danger',
|
115
120
|
:title => _('Try to abort the job on a host without waiting for its result'),
|
116
121
|
:disabled => !task.cancellable?,
|
117
|
-
:method => :post
|
122
|
+
:method => :post,
|
123
|
+
:remote => true)
|
118
124
|
end
|
119
125
|
buttons
|
120
126
|
end
|
@@ -47,12 +47,16 @@ module Actions
|
|
47
47
|
script = renderer.render
|
48
48
|
raise _('Failed rendering template: %s') % renderer.error_message unless script
|
49
49
|
|
50
|
+
first_execution = host.executed_through_proxies.where(:id => proxy.id).none?
|
51
|
+
host.executed_through_proxies << proxy if first_execution
|
52
|
+
|
50
53
|
additional_options = { :hostname => provider.find_ip_or_hostname(host),
|
51
54
|
:script => script,
|
52
55
|
:execution_timeout_interval => job_invocation.execution_timeout_interval,
|
53
56
|
:secrets => secrets(host, job_invocation, provider),
|
54
57
|
:use_batch_triggering => true,
|
55
|
-
:use_concurrency_control => options[:use_concurrency_control]
|
58
|
+
:use_concurrency_control => options[:use_concurrency_control],
|
59
|
+
:first_execution => first_execution }
|
56
60
|
action_options = provider.proxy_command_options(template_invocation, host)
|
57
61
|
.merge(additional_options)
|
58
62
|
|
@@ -72,7 +72,7 @@ module Actions
|
|
72
72
|
|
73
73
|
def total_count
|
74
74
|
# For compatibility with already existing tasks
|
75
|
-
return output[:total_count] unless output.has_key?(:host_count) || task.pending?
|
75
|
+
return output[:total_count] || hosts.count unless output.has_key?(:host_count) || task.pending?
|
76
76
|
|
77
77
|
output[:host_count] || hosts.count
|
78
78
|
end
|
@@ -6,6 +6,8 @@ module ForemanRemoteExecution
|
|
6
6
|
has_many :template_invocations, :dependent => :destroy, :foreign_key => 'host_id'
|
7
7
|
has_one :execution_status_object, :class_name => 'HostStatus::ExecutionStatus', :foreign_key => 'host_id', :dependent => :destroy
|
8
8
|
has_many :run_host_job_tasks, :through => :template_invocations
|
9
|
+
has_many :host_proxy_invocations, :foreign_key => 'host_id', :dependent => :destroy
|
10
|
+
has_many :executed_through_proxies, :through => :host_proxy_invocations, :source => 'smart_proxy'
|
9
11
|
|
10
12
|
scoped_search :relation => :run_host_job_tasks, :on => :result, :rename => 'job_invocation.result',
|
11
13
|
:ext_method => :search_by_job_invocation,
|
@@ -64,11 +64,11 @@ class HostStatus::ExecutionStatus < HostStatus::Status
|
|
64
64
|
|
65
65
|
case status
|
66
66
|
when OK
|
67
|
-
[ "foreman_tasks_tasks.state = 'stopped' AND result = 'success'" ]
|
67
|
+
[ "foreman_tasks_tasks.state = 'stopped' AND foreman_tasks_tasks.result = 'success'" ]
|
68
68
|
when CANCELLED
|
69
|
-
[ "foreman_tasks_tasks.state = 'stopped' AND result = 'cancelled'" ]
|
69
|
+
[ "foreman_tasks_tasks.state = 'stopped' AND foreman_tasks_tasks.result = 'cancelled'" ]
|
70
70
|
when ERROR
|
71
|
-
[ "foreman_tasks_tasks.state = 'stopped' AND (result = 'error' OR result = 'warning')" ]
|
71
|
+
[ "foreman_tasks_tasks.state = 'stopped' AND (foreman_tasks_tasks.result = 'error' OR foreman_tasks_tasks.result = 'warning')" ]
|
72
72
|
when QUEUED
|
73
73
|
[ "foreman_tasks_tasks.state = 'scheduled' OR foreman_tasks_tasks.state IS NULL" ]
|
74
74
|
when RUNNING
|
@@ -65,8 +65,6 @@ class JobInvocation < ApplicationRecord
|
|
65
65
|
scoped_search :on => 'pattern_template_name', :rename => 'pattern_template_name', :operators => ['= '],
|
66
66
|
:complete_value => false, :only_explicit => true, :ext_method => :search_by_pattern_template
|
67
67
|
|
68
|
-
scope :with_task, -> { references(:task) }
|
69
|
-
|
70
68
|
scoped_search :relation => :recurring_logic, :on => 'id', :rename => 'recurring_logic.id'
|
71
69
|
|
72
70
|
scoped_search :relation => :recurring_logic, :on => 'id', :rename => 'recurring',
|
@@ -99,7 +97,7 @@ class JobInvocation < ApplicationRecord
|
|
99
97
|
def self.search_by_status(key, operator, value)
|
100
98
|
conditions = HostStatus::ExecutionStatus::ExecutionTaskStatusMapper.sql_conditions_for(value)
|
101
99
|
conditions[0] = "NOT (#{conditions[0]})" if operator == '<>'
|
102
|
-
{ :conditions => sanitize_sql_for_conditions(conditions), :
|
100
|
+
{ :conditions => sanitize_sql_for_conditions(conditions), :joins => :task }
|
103
101
|
end
|
104
102
|
|
105
103
|
def self.search_by_recurring_logic(key, operator, value)
|
@@ -193,11 +191,16 @@ class JobInvocation < ApplicationRecord
|
|
193
191
|
end
|
194
192
|
|
195
193
|
def total_hosts_count
|
194
|
+
count = _('N/A')
|
195
|
+
|
196
196
|
if targeting.resolved?
|
197
|
-
task&.main_action
|
198
|
-
|
199
|
-
|
197
|
+
count = if task&.main_action.respond_to?(:total_count)
|
198
|
+
task.main_action.total_count
|
199
|
+
else
|
200
|
+
targeting.hosts.count
|
201
|
+
end
|
200
202
|
end
|
203
|
+
count
|
201
204
|
end
|
202
205
|
|
203
206
|
def pattern_template_invocation_for_host(host)
|
@@ -209,7 +209,7 @@ class JobInvocationComposer
|
|
209
209
|
def format_datetime(datetime)
|
210
210
|
return datetime if datetime.blank?
|
211
211
|
|
212
|
-
Time.parse(datetime).strftime('%Y-%m-%d %H:%M')
|
212
|
+
Time.parse(datetime).utc.strftime('%Y-%m-%d %H:%M')
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
@@ -296,7 +296,7 @@ class JobInvocationComposer
|
|
296
296
|
attr_reader :feature_label, :feature, :provided_inputs
|
297
297
|
|
298
298
|
def initialize(feature_label, hosts, provided_inputs = {})
|
299
|
-
@feature = RemoteExecutionFeature.feature(feature_label)
|
299
|
+
@feature = RemoteExecutionFeature.feature!(feature_label)
|
300
300
|
@provided_inputs = provided_inputs
|
301
301
|
translator = HostIdsTranslator.new(hosts)
|
302
302
|
@host_bookmark = translator.bookmark
|
@@ -405,7 +405,7 @@ class JobInvocationComposer
|
|
405
405
|
job_invocation.effective_user_password = params[:effective_user_password]
|
406
406
|
|
407
407
|
if @reruns && job_invocation.targeting.static?
|
408
|
-
job_invocation.targeting.
|
408
|
+
job_invocation.targeting.assign_host_ids(JobInvocation.find(@reruns).targeting.host_ids)
|
409
409
|
job_invocation.targeting.mark_resolved!
|
410
410
|
end
|
411
411
|
|
@@ -513,7 +513,7 @@ class JobInvocationComposer
|
|
513
513
|
end
|
514
514
|
|
515
515
|
def available_bookmarks
|
516
|
-
Bookmark.
|
516
|
+
Bookmark.my_bookmarks.where(:controller => ['hosts', 'dashboard'])
|
517
517
|
end
|
518
518
|
|
519
519
|
def targeted_hosts
|
data/app/models/job_template.rb
CHANGED
@@ -20,7 +20,11 @@ class RemoteExecutionFeature < ApplicationRecord
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.feature(label)
|
23
|
-
self.find_by(label: label)
|
23
|
+
self.find_by(label: label)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.feature!(label)
|
27
|
+
feature(label) || raise(::Foreman::Exception.new(N_('Unknown remote execution feature %s'), label))
|
24
28
|
end
|
25
29
|
|
26
30
|
def self.register(label, name, options = {})
|
@@ -70,13 +70,13 @@ class Setting::RemoteExecution < Setting
|
|
70
70
|
self.set('remote_execution_form_job_template',
|
71
71
|
N_('Choose a job template that is pre-selected in job invocation form'),
|
72
72
|
'Run Command - SSH Default',
|
73
|
-
|
73
|
+
N_('Form Job Template'),
|
74
74
|
nil,
|
75
75
|
{ :collection => proc { Hash[JobTemplate.unscoped.map { |template| [template.name, template.name] }] } }),
|
76
76
|
self.set('remote_execution_job_invocation_report_template',
|
77
77
|
N_('Select a report template used for generating a report for a particular remote execution job'),
|
78
78
|
'Jobs - Invocation report template',
|
79
|
-
|
79
|
+
N_('Job Invocation Report Template'),
|
80
80
|
nil,
|
81
81
|
{ :collection => proc { self.job_invocation_report_templates_select } }),
|
82
82
|
]
|
data/app/models/targeting.rb
CHANGED
@@ -46,9 +46,13 @@ class Targeting < ApplicationRecord
|
|
46
46
|
# pluck(:id) returns duplicate results for HostCollections
|
47
47
|
host_ids = User.as(user.login) { Host.authorized(RESOLVE_PERMISSION, Host).search_for(search_query).order(:name, :id).pluck(:id).uniq }
|
48
48
|
host_ids.shuffle!(random: Random.new) if randomized_ordering
|
49
|
+
self.assign_host_ids(host_ids)
|
50
|
+
self.save(:validate => false)
|
51
|
+
end
|
52
|
+
|
53
|
+
def assign_host_ids(host_ids)
|
49
54
|
# this can be optimized even more, by introducing bulk insert
|
50
55
|
self.targeting_hosts.build(host_ids.map { |id| { :host_id => id } })
|
51
|
-
self.save(:validate => false)
|
52
56
|
end
|
53
57
|
|
54
58
|
def dynamic?
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<% @job_invocations.each do |invocation| %>
|
22
22
|
<tr>
|
23
23
|
<td class="text_warp"><%= link_to_if_authorized invocation_description(invocation), hash_for_job_invocation_path(invocation).merge(:auth_object => invocation, :permission => :view_job_invocations, :authorizer => authorizer) %></td>
|
24
|
-
<td><%= trunc_with_tooltip(invocation
|
24
|
+
<td><%= trunc_with_tooltip(invocation.targeting.search_query, 15) %></td>
|
25
25
|
<td><%= link_to_invocation_task_if_authorized(invocation) %></td>
|
26
26
|
<td><%= invocation_result(invocation, :success_count) %></td>
|
27
27
|
<td><%= invocation_result(invocation, :failed_count) %></td>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class AddHostProxyInvocations < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
# rubocop:disable Rails/CreateTableWithTimestamps
|
4
|
+
create_table :host_proxy_invocations do |t|
|
5
|
+
t.references :host, :null => false
|
6
|
+
t.references :smart_proxy, :null => false
|
7
|
+
end
|
8
|
+
# rubocop:enable Rails/CreateTableWithTimestamps
|
9
|
+
|
10
|
+
add_index :host_proxy_invocations, [:host_id, :smart_proxy_id], unique: true
|
11
|
+
end
|
12
|
+
end
|
@@ -16,8 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
'management functionality with remote management functionality.'
|
17
17
|
|
18
18
|
s.files = `git ls-files`.split("\n").reject do |file|
|
19
|
-
file.start_with?('scripts'
|
20
|
-
file == 'foreman_remote_execution_core.gemspec'
|
19
|
+
file.start_with?('scripts')
|
21
20
|
end
|
22
21
|
|
23
22
|
s.test_files = `git ls-files test`.split("\n")
|
@@ -25,7 +24,7 @@ Gem::Specification.new do |s|
|
|
25
24
|
|
26
25
|
s.add_dependency 'deface'
|
27
26
|
s.add_dependency 'dynflow', '>= 1.0.2', '< 2.0.0'
|
28
|
-
s.add_dependency 'foreman-tasks', '>=
|
27
|
+
s.add_dependency 'foreman-tasks', '>= 5.0.0'
|
29
28
|
|
30
29
|
s.add_development_dependency 'factory_bot_rails', '~> 4.8.0'
|
31
30
|
s.add_development_dependency 'rdoc'
|
@@ -152,6 +152,9 @@ module ForemanRemoteExecution
|
|
152
152
|
ctx.permit :execution
|
153
153
|
end
|
154
154
|
|
155
|
+
register_graphql_query_field :job_invocations, '::Types::JobInvocation', :collection_field
|
156
|
+
register_graphql_query_field :job_invocation, '::Types::JobInvocation', :record_field
|
157
|
+
|
155
158
|
extend_template_helpers ForemanRemoteExecution::RendererMethods
|
156
159
|
|
157
160
|
extend_rabl_template 'api/v2/smart_proxies/main', 'api/v2/smart_proxies/pubkey'
|
@@ -201,12 +204,10 @@ module ForemanRemoteExecution
|
|
201
204
|
|
202
205
|
Host::Managed.prepend ForemanRemoteExecution::HostExtensions
|
203
206
|
Host::Managed.include ForemanTasks::Concerns::HostActionSubject
|
204
|
-
Host::Managed.include ForemanRemoteExecution::Orchestration::SSH
|
205
207
|
|
206
208
|
(Nic::Base.descendants + [Nic::Base]).each do |klass|
|
207
209
|
klass.send(:include, ForemanRemoteExecution::NicExtensions)
|
208
210
|
end
|
209
|
-
Nic::Managed.include ForemanRemoteExecution::Orchestration::SSH
|
210
211
|
|
211
212
|
Bookmark.include ForemanRemoteExecution::BookmarkExtensions
|
212
213
|
HostsHelper.prepend ForemanRemoteExecution::HostsHelperExtensions
|