foreman_remote_execution 12.0.5 → 13.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc +4 -1
- data/.github/workflows/js_ci.yml +1 -1
- data/.github/workflows/release.yml +4 -2
- data/.github/workflows/ruby_ci.yml +16 -81
- data/.packit.yaml +8 -3
- data/app/assets/javascripts/foreman_remote_execution/locale/de/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/en/foreman_remote_execution.js +22 -4
- data/app/assets/javascripts/foreman_remote_execution/locale/en_GB/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/es/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/fr/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/ja/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/ka/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/ko/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/pt_BR/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/ru/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/zh_CN/foreman_remote_execution.js +23 -14
- data/app/assets/javascripts/foreman_remote_execution/locale/zh_TW/foreman_remote_execution.js +23 -14
- data/app/controllers/ui_job_wizard_controller.rb +1 -1
- data/app/helpers/job_invocations_helper.rb +1 -1
- data/app/helpers/remote_execution_helper.rb +2 -2
- data/app/lib/actions/remote_execution/proxy_action.rb +1 -1
- data/app/lib/actions/remote_execution/run_host_job.rb +9 -17
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +8 -0
- data/app/models/host_status/execution_status.rb +2 -2
- data/app/models/job_invocation_composer.rb +4 -3
- data/app/views/api/v2/job_invocations/base.json.rabl +5 -3
- data/app/views/job_invocations/_preview_hosts_list.html.erb +1 -1
- data/app/views/job_invocations/show.html.erb +12 -5
- data/app/views/job_invocations/show.js.erb +8 -1
- data/app/views/job_invocations/welcome.html.erb +1 -1
- data/app/views/template_invocations/_refresh.js.erb +10 -4
- data/app/views/template_invocations/show.html.erb +2 -2
- data/app/views/templates/script/convert2rhel_analyze.erb +1 -12
- data/app/views/templates/script/package_action.erb +11 -1
- data/app/views/templates/script/puppet_run_once.erb +3 -3
- data/lib/foreman_remote_execution/engine.rb +1 -1
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/de/foreman_remote_execution.po +24 -6
- data/locale/en/foreman_remote_execution.po +24 -6
- data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en_GB/foreman_remote_execution.po +24 -6
- data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/es/foreman_remote_execution.po +24 -6
- data/locale/foreman_remote_execution.pot +170 -142
- data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/fr/foreman_remote_execution.po +24 -6
- data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ja/foreman_remote_execution.po +24 -6
- data/locale/ka/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ka/foreman_remote_execution.po +24 -6
- data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ko/foreman_remote_execution.po +24 -6
- data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/pt_BR/foreman_remote_execution.po +24 -6
- data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ru/foreman_remote_execution.po +24 -6
- data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_CN/foreman_remote_execution.po +24 -6
- data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_TW/foreman_remote_execution.po +24 -6
- data/package.json +7 -11
- data/test/functional/api/v2/job_invocations_controller_test.rb +7 -7
- data/test/functional/api/v2/template_invocations_controller_test.rb +3 -3
- data/test/helpers/remote_execution_helper_test.rb +8 -7
- data/test/unit/actions/run_host_job_test.rb +1 -1
- data/test/unit/actions/run_hosts_job_test.rb +11 -11
- data/test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb +5 -5
- data/test/unit/concerns/host_extensions_test.rb +34 -34
- data/test/unit/concerns/nic_extensions_test.rb +1 -1
- data/test/unit/execution_task_status_mapper_test.rb +10 -10
- data/test/unit/input_template_renderer_test.rb +53 -49
- data/test/unit/job_invocation_composer_test.rb +109 -81
- data/test/unit/job_invocation_test.rb +25 -25
- data/test/unit/job_template_effective_user_test.rb +3 -3
- data/test/unit/job_template_test.rb +28 -28
- data/test/unit/remote_execution_feature_test.rb +14 -14
- data/test/unit/remote_execution_provider_test.rb +39 -39
- data/test/unit/renderer_scope_input_test.rb +6 -6
- data/test/unit/targeting_test.rb +32 -32
- data/webpack/JobInvocationDetail/JobInvocationConstants.js +10 -0
- data/webpack/JobInvocationDetail/JobInvocationDetail.scss +38 -0
- data/webpack/JobInvocationDetail/JobInvocationOverview.js +13 -25
- data/webpack/JobInvocationDetail/JobInvocationSystemStatusChart.js +153 -0
- data/webpack/JobInvocationDetail/index.js +48 -10
- data/webpack/JobWizard/Footer.js +5 -1
- data/webpack/JobWizard/JobWizardConstants.js +4 -0
- data/webpack/JobWizard/JobWizardPageRerun.js +3 -0
- data/webpack/JobWizard/JobWizardSelectors.js +31 -3
- data/webpack/JobWizard/PermissionDenied.js +64 -0
- data/webpack/JobWizard/StartsBeforeErrorAlert.js +1 -0
- data/webpack/JobWizard/__tests__/fixtures.js +3 -3
- data/webpack/JobWizard/autofill.js +8 -4
- data/webpack/JobWizard/index.js +41 -1
- data/webpack/JobWizard/steps/AdvancedFields/DescriptionField.js +8 -1
- data/webpack/JobWizard/steps/AdvancedFields/Fields.js +7 -0
- data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js +41 -7
- data/webpack/JobWizard/steps/HostsAndInputs/HostPreviewModal.js +7 -3
- data/webpack/JobWizard/steps/HostsAndInputs/SelectGQL.js +1 -0
- data/webpack/JobWizard/steps/HostsAndInputs/SelectedChips.js +21 -7
- data/webpack/JobWizard/steps/HostsAndInputs/hosts.gql +1 -0
- data/webpack/JobWizard/steps/HostsAndInputs/index.js +27 -2
- data/webpack/JobWizard/steps/ReviewDetails/index.js +7 -2
- data/webpack/JobWizard/steps/Schedule/PurposeField.js +1 -0
- data/webpack/JobWizard/steps/Schedule/QueryType.js +2 -0
- data/webpack/JobWizard/steps/Schedule/RepeatCron.js +1 -0
- data/webpack/JobWizard/steps/Schedule/RepeatHour.js +2 -0
- data/webpack/JobWizard/steps/Schedule/RepeatMonth.js +1 -0
- data/webpack/JobWizard/steps/Schedule/RepeatWeek.js +1 -0
- data/webpack/JobWizard/steps/Schedule/ScheduleFuture.js +2 -0
- data/webpack/JobWizard/steps/Schedule/ScheduleRecurring.js +6 -0
- data/webpack/JobWizard/steps/Schedule/ScheduleType.js +3 -0
- data/webpack/JobWizard/steps/form/FormHelpers.js +1 -0
- data/webpack/JobWizard/steps/form/GroupedSelectField.js +1 -0
- data/webpack/JobWizard/steps/form/NumberInput.js +1 -0
- data/webpack/JobWizard/steps/form/ResourceSelect.js +1 -0
- data/webpack/JobWizard/steps/form/SearchSelect.js +4 -1
- data/webpack/JobWizard/steps/form/SelectField.js +1 -0
- data/webpack/JobWizard/steps/form/WizardTitle.js +6 -1
- data/webpack/JobWizard/steps/form/__tests__/SelectSearch.test.js +2 -0
- data/webpack/__mocks__/foremanReact/routes/Hosts/constants.js +1 -0
- data/webpack/react_app/components/FeaturesDropdown/index.js +1 -0
- data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +3 -0
- data/webpack/react_app/components/RecentJobsCard/RecentJobsTable.js +2 -1
- data/webpack/react_app/components/RegistrationExtension/RexInterface.js +1 -0
- data/webpack/react_app/components/RegistrationExtension/RexPull.js +1 -0
- data/webpack/react_app/components/RegistrationExtension/__tests__/__snapshots__/RexInterface.test.js.snap +1 -0
- metadata +10 -6
@@ -79,6 +79,9 @@ msgstr "要使用執行這 script 的使用者。如果使用者與 SSH 使用
|
|
79
79
|
msgid "Abort Job"
|
80
80
|
msgstr ""
|
81
81
|
|
82
|
+
msgid "Access denied"
|
83
|
+
msgstr ""
|
84
|
+
|
82
85
|
msgid "Actions"
|
83
86
|
msgstr "動作"
|
84
87
|
|
@@ -124,6 +127,9 @@ msgstr "於"
|
|
124
127
|
msgid "At minute"
|
125
128
|
msgstr ""
|
126
129
|
|
130
|
+
msgid "Awaiting start"
|
131
|
+
msgstr ""
|
132
|
+
|
127
133
|
msgid "Back"
|
128
134
|
msgstr ""
|
129
135
|
|
@@ -370,9 +376,6 @@ msgstr ""
|
|
370
376
|
msgid "Ends"
|
371
377
|
msgstr "結束"
|
372
378
|
|
373
|
-
msgid "Error"
|
374
|
-
msgstr "錯誤"
|
375
|
-
|
376
379
|
msgid "Error loading data from proxy"
|
377
380
|
msgstr "從代理載入資料時發生錯誤"
|
378
381
|
|
@@ -703,6 +706,9 @@ msgstr "手動選擇"
|
|
703
706
|
msgid "Minute can only be a number between 0-59"
|
704
707
|
msgstr ""
|
705
708
|
|
709
|
+
msgid "Missing the required permissions: ${missingPermissions.join( ', ' )}"
|
710
|
+
msgstr ""
|
711
|
+
|
706
712
|
msgid "Monthly"
|
707
713
|
msgstr "每個月"
|
708
714
|
|
@@ -733,9 +739,6 @@ msgstr ""
|
|
733
739
|
msgid "No Target Hosts"
|
734
740
|
msgstr ""
|
735
741
|
|
736
|
-
msgid "No execution finished yet"
|
737
|
-
msgstr "尚無執行完成"
|
738
|
-
|
739
742
|
msgid "No hosts found."
|
740
743
|
msgstr "找不到主機。"
|
741
744
|
|
@@ -751,6 +754,9 @@ msgstr "沒有範本定義至功能 %{feature_name}"
|
|
751
754
|
msgid "Not all required inputs have values. Missing inputs: %s"
|
752
755
|
msgstr "並不是所需的輸入都有值。缺少的輸入:%s"
|
753
756
|
|
757
|
+
msgid "Not available"
|
758
|
+
msgstr ""
|
759
|
+
|
754
760
|
msgid "Not yet"
|
755
761
|
msgstr ""
|
756
762
|
|
@@ -802,6 +808,9 @@ msgstr ""
|
|
802
808
|
msgid "Perform no more executions after this time"
|
803
809
|
msgstr "此時間之後不再進行任何執行"
|
804
810
|
|
811
|
+
msgid "Permission Denied"
|
812
|
+
msgstr ""
|
813
|
+
|
805
814
|
msgid "Please enter a search query"
|
806
815
|
msgstr ""
|
807
816
|
|
@@ -811,6 +820,9 @@ msgstr ""
|
|
811
820
|
msgid "Please refine your search."
|
812
821
|
msgstr ""
|
813
822
|
|
823
|
+
msgid "Please request the required permissions listed below from a Foreman administrator:"
|
824
|
+
msgstr ""
|
825
|
+
|
814
826
|
msgid "Please select at least one host"
|
815
827
|
msgstr ""
|
816
828
|
|
@@ -844,6 +856,9 @@ msgstr ""
|
|
844
856
|
msgid "Problem with previewing the template: %{error}. Note that you must save template input changes before you try to preview it."
|
845
857
|
msgstr "預覽範本時發生問題:%{error}。請注意,您必須在預覽範本前,先儲存範本輸入的變更。"
|
846
858
|
|
859
|
+
msgid "Proceed Anyway"
|
860
|
+
msgstr ""
|
861
|
+
|
847
862
|
msgid "Provider type"
|
848
863
|
msgstr "供應商種類"
|
849
864
|
|
@@ -1458,6 +1473,9 @@ msgstr ""
|
|
1458
1473
|
msgid "You are not allowed to see the currently assigned template. Saving the form now would unassign the template."
|
1459
1474
|
msgstr "您不能看到目前指定的範本。現在儲存表單會取消指定範本。"
|
1460
1475
|
|
1476
|
+
msgid "You are not authorized to perform this action."
|
1477
|
+
msgstr ""
|
1478
|
+
|
1461
1479
|
msgid "You have %s results to display. Showing first %s results"
|
1462
1480
|
msgstr ""
|
1463
1481
|
|
data/package.json
CHANGED
@@ -8,10 +8,7 @@
|
|
8
8
|
"test": "tfm-test --plugin",
|
9
9
|
"test:watch": "tfm-test --plugin --watchAll",
|
10
10
|
"test:current": "tfm-test --plugin --watch",
|
11
|
-
"publish-coverage": "tfm-publish-coverage"
|
12
|
-
"stories": "tfm-stories --plugin",
|
13
|
-
"stories:build": "tfm-build-stories --plugin",
|
14
|
-
"stories:deploy": "surge --project .storybook-dist"
|
11
|
+
"publish-coverage": "tfm-publish-coverage"
|
15
12
|
},
|
16
13
|
"repository": {
|
17
14
|
"type": "git",
|
@@ -21,13 +18,12 @@
|
|
21
18
|
"url": "http://projects.theforeman.org/projects/foreman_remote_execution/issues"
|
22
19
|
},
|
23
20
|
"devDependencies": {
|
24
|
-
"@adobe/css-tools": "~4.2.0",
|
25
21
|
"@babel/core": "^7.7.0",
|
26
|
-
"@theforeman/builder": "
|
27
|
-
"@theforeman/eslint-plugin-foreman": "
|
28
|
-
"@theforeman/eslint-plugin-rules": "
|
29
|
-
"@theforeman/test": "
|
30
|
-
"@theforeman/vendor-dev": "
|
22
|
+
"@theforeman/builder": ">= 12.0.1",
|
23
|
+
"@theforeman/eslint-plugin-foreman": ">= 12.0.1",
|
24
|
+
"@theforeman/eslint-plugin-rules": ">= 12.0.2",
|
25
|
+
"@theforeman/test": ">= 12.0.1",
|
26
|
+
"@theforeman/vendor-dev": ">= 12.0.1",
|
31
27
|
"babel-eslint": "^10.0.0",
|
32
28
|
"eslint": "^6.8.0",
|
33
29
|
"prettier": "^1.19.1",
|
@@ -36,6 +32,6 @@
|
|
36
32
|
"graphql": "^15.5.0"
|
37
33
|
},
|
38
34
|
"peerDependencies": {
|
39
|
-
"@theforeman/vendor": "
|
35
|
+
"@theforeman/vendor": ">= 12.0.1"
|
40
36
|
}
|
41
37
|
}
|
@@ -272,7 +272,7 @@ module Api
|
|
272
272
|
assert_equal result['complete'], false
|
273
273
|
assert_equal result['delayed'], true
|
274
274
|
assert_nil result['output']
|
275
|
-
|
275
|
+
assert_in_delta start_time.to_f, Time.parse(result['start_at']).to_f, 0.001
|
276
276
|
assert_response :success
|
277
277
|
end
|
278
278
|
|
@@ -334,8 +334,8 @@ module Api
|
|
334
334
|
assert_response :success
|
335
335
|
result = ActiveSupport::JSON.decode(@response.body)
|
336
336
|
targeting = Targeting.find(result['targeting_id'])
|
337
|
-
|
338
|
-
|
337
|
+
assert_equal users(:admin).id, targeting.user_id
|
338
|
+
assert_equal @invocation.targeting.search_query, targeting.search_query
|
339
339
|
end
|
340
340
|
|
341
341
|
test 'should not raise an exception when reruning failed has no hosts' do
|
@@ -350,8 +350,8 @@ module Api
|
|
350
350
|
assert_response :success
|
351
351
|
result = ActiveSupport::JSON.decode(@response.body)
|
352
352
|
targeting = Targeting.find(result['targeting_id'])
|
353
|
-
|
354
|
-
|
353
|
+
assert_equal users(:admin).id, targeting.user_id
|
354
|
+
assert_equal 'name ^ ()', targeting.search_query
|
355
355
|
end
|
356
356
|
|
357
357
|
test 'should rerun failed only' do
|
@@ -369,8 +369,8 @@ module Api
|
|
369
369
|
result = ActiveSupport::JSON.decode(@response.body)
|
370
370
|
targeting = Targeting.find(result['targeting_id'])
|
371
371
|
hostnames = @invocation.template_invocations.map { |ti| ti.host.name }
|
372
|
-
|
373
|
-
|
372
|
+
assert_equal users(:admin).id, targeting.user_id
|
373
|
+
assert_equal "name ^ (#{hostnames.join(',')})", targeting.search_query
|
374
374
|
end
|
375
375
|
|
376
376
|
test 'should return 404 if template is not found' do
|
@@ -13,8 +13,8 @@ module Api
|
|
13
13
|
test 'should get template invocations belonging to job invocation' do
|
14
14
|
get :template_invocations, params: { :id => @job.id }
|
15
15
|
invocations = ActiveSupport::JSON.decode(@response.body)
|
16
|
-
|
17
|
-
|
16
|
+
assert_equal @job.template_invocations.count, invocations['results'].count
|
17
|
+
assert_equal @job.template_invocations.count, invocations['total']
|
18
18
|
|
19
19
|
expected_result = {
|
20
20
|
'id' => @template_invocation.id,
|
@@ -25,7 +25,7 @@ module Api
|
|
25
25
|
'job_invocation_id' => @job.id,
|
26
26
|
'run_host_job_task_id' => @template_invocation.run_host_job_task_id,
|
27
27
|
}
|
28
|
-
|
28
|
+
assert_equal [expected_result], invocations['results']
|
29
29
|
assert_response :success
|
30
30
|
end
|
31
31
|
end
|
@@ -14,13 +14,14 @@ class RemoteExecutionHelperTest < ActionView::TestCase
|
|
14
14
|
|
15
15
|
it 'ensures the line sets end with new line' do
|
16
16
|
new_line_sets = normalize_line_sets(line_sets)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
expected_output = ["one\r\n",
|
18
|
+
"two\r\n",
|
19
|
+
"\r\nthree\r\n",
|
20
|
+
"four\r\n",
|
21
|
+
"\r\n\r\n",
|
22
|
+
"five\r\n",
|
23
|
+
"Exit status: 0"]
|
24
|
+
assert_equal(expected_output, new_line_sets.map { |s| s['output'] })
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
@@ -53,7 +53,7 @@ module ForemanRemoteExecution
|
|
53
53
|
exception = assert_raises do
|
54
54
|
action.send(:verify_permissions, template_invocation.host, template_invocation)
|
55
55
|
end
|
56
|
-
|
56
|
+
assert_includes exception.message, "infrastructure host #{template_invocation.host.name}"
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -65,13 +65,13 @@ module ForemanRemoteExecution
|
|
65
65
|
delayed
|
66
66
|
assert_not targeting.resolved?
|
67
67
|
planned
|
68
|
-
|
68
|
+
assert_includes targeting.hosts, host
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'resolves the hosts on static targeting in delay' do
|
72
72
|
assert_not targeting.resolved?
|
73
73
|
delayed
|
74
|
-
|
74
|
+
assert_includes targeting.hosts, host
|
75
75
|
# Verify Targeting#resolve_hosts! won't be hit again
|
76
76
|
targeting.expects(:resolve_hosts!).never
|
77
77
|
planned
|
@@ -79,7 +79,7 @@ module ForemanRemoteExecution
|
|
79
79
|
|
80
80
|
it 'resolves the hosts on static targeting in plan phase if not resolved yet' do
|
81
81
|
planned
|
82
|
-
|
82
|
+
assert_includes targeting.hosts, host
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -91,16 +91,16 @@ module ForemanRemoteExecution
|
|
91
91
|
|
92
92
|
it 'uses the BindJobInvocation middleware' do
|
93
93
|
planned
|
94
|
-
|
94
|
+
assert_equal job_invocation.task_id, uuid
|
95
95
|
end
|
96
96
|
|
97
97
|
# In plan phase this is handled by #action_subject
|
98
98
|
# which is expected in tests
|
99
99
|
it 'sets input in delay phase when delayed' do
|
100
100
|
job_invocation_hash = delayed.input[:job_invocation]
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
assert_equal job_invocation_hash['id'], job_invocation.id
|
102
|
+
assert_equal job_invocation_hash['name'], job_invocation.job_category
|
103
|
+
assert_equal job_invocation_hash['description'], job_invocation.description
|
104
104
|
planned # To make the expectations happy
|
105
105
|
end
|
106
106
|
|
@@ -108,7 +108,7 @@ module ForemanRemoteExecution
|
|
108
108
|
it 'defaults to Setting[foreman_tasks_proxy_batch_size]' do
|
109
109
|
Setting.expects(:[]).with('foreman_tasks_proxy_batch_size').returns(14)
|
110
110
|
planned
|
111
|
-
|
111
|
+
assert_equal 14, planned.proxy_batch_size
|
112
112
|
end
|
113
113
|
|
114
114
|
it 'gets the provider value' do
|
@@ -116,7 +116,7 @@ module ForemanRemoteExecution
|
|
116
116
|
provider.expects(:proxy_batch_size).returns(15)
|
117
117
|
JobTemplate.any_instance.expects(:provider).returns(provider)
|
118
118
|
|
119
|
-
|
119
|
+
assert_equal 15, planned.proxy_batch_size
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
@@ -124,12 +124,12 @@ module ForemanRemoteExecution
|
|
124
124
|
let(:level) { 5 }
|
125
125
|
|
126
126
|
it 'can be disabled' do
|
127
|
-
|
127
|
+
assert_nil planned.concurrency_limit
|
128
128
|
end
|
129
129
|
|
130
130
|
it 'can limit concurrency level' do
|
131
131
|
job_invocation.expects(:concurrency_level).twice.returns(level)
|
132
|
-
|
132
|
+
assert_equal level, planned.concurrency_limit
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
@@ -13,17 +13,17 @@ class ForemanRemoteExecutionForemanTasksCleanerExtensionsTest < ActiveSupport::T
|
|
13
13
|
it 'tries to delete associated job invocations' do
|
14
14
|
job = FactoryBot.create(:job_invocation, :with_task)
|
15
15
|
ForemanTasks::Cleaner.new(:filter => "id = #{job.task.id}").delete
|
16
|
-
JobInvocation.where(:id => job.id)
|
16
|
+
assert_empty JobInvocation.where(:id => job.id)
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'removes orphaned job invocations' do
|
20
20
|
job = FactoryBot.create(:job_invocation, :with_task)
|
21
|
-
|
21
|
+
assert_equal 1, JobInvocation.where(:id => job.id).count
|
22
22
|
job.task.delete
|
23
23
|
job.reload
|
24
|
-
|
25
|
-
|
24
|
+
assert_nil job.task
|
25
|
+
refute_nil job.task_id
|
26
26
|
ForemanTasks::Cleaner.new(:filter => '').delete
|
27
|
-
JobInvocation.where(:id => job.id)
|
27
|
+
assert_empty JobInvocation.where(:id => job.id)
|
28
28
|
end
|
29
29
|
end
|
@@ -17,39 +17,39 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'has ssh user in the parameters' do
|
20
|
-
|
20
|
+
assert_equal Setting[:remote_execution_ssh_user], host.host_param('remote_execution_ssh_user')
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'can override ssh user' do
|
24
24
|
host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_ssh_user', :value => 'amy')
|
25
|
-
|
25
|
+
assert_equal 'amy', host.host_param('remote_execution_ssh_user')
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'has effective user method in the parameters' do
|
29
|
-
|
29
|
+
assert_equal Setting[:remote_execution_effective_user_method], host.host_param('remote_execution_effective_user_method')
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'can override effective user method' do
|
33
33
|
host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_effective_user_method', :value => 'su')
|
34
|
-
|
34
|
+
assert_equal 'su', host.host_param('remote_execution_effective_user_method')
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'has ssh keys in the parameters' do
|
38
|
-
|
38
|
+
assert_includes host.remote_execution_ssh_keys, sshkey
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'merges ssh keys from host parameters and proxies' do
|
42
42
|
key = 'ssh-rsa not-even-a-key something@somewhere.com'
|
43
43
|
host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_ssh_keys', :value => [key])
|
44
|
-
|
45
|
-
|
44
|
+
assert_includes host.host_param('remote_execution_ssh_keys'), key
|
45
|
+
assert_includes host.host_param('remote_execution_ssh_keys'), sshkey
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'merges ssh key as a string from host parameters and proxies' do
|
49
49
|
key = 'ssh-rsa not-even-a-key something@somewhere.com'
|
50
50
|
host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_ssh_keys', :value => key)
|
51
|
-
|
52
|
-
|
51
|
+
assert_includes host.host_param('remote_execution_ssh_keys'), key
|
52
|
+
assert_includes host.host_param('remote_execution_ssh_keys'), sshkey
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'has ssh keys in the parameters even when no user specified' do
|
@@ -57,7 +57,7 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
57
57
|
FactoryBot.create(:smart_proxy, :ssh)
|
58
58
|
host.interfaces.first.subnet.remote_execution_proxies.clear
|
59
59
|
User.current = nil
|
60
|
-
|
60
|
+
assert_includes host.remote_execution_ssh_keys, sshkey
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -67,12 +67,12 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
67
67
|
it 'should only have one execution interface' do
|
68
68
|
host.interfaces << FactoryBot.build(:nic_managed)
|
69
69
|
host.interfaces.each { |interface| interface.execution = true }
|
70
|
-
|
71
|
-
|
70
|
+
assert_predicate host, :valid?
|
71
|
+
assert_equal 1, host.interfaces.count(&:execution?)
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'returns the execution interface' do
|
75
|
-
|
75
|
+
assert_kind_of Nic::Managed, host.execution_interface
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -91,16 +91,16 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
91
91
|
|
92
92
|
it 'finds hosts for job_invocation.id' do
|
93
93
|
found_ids = Host.search_for("job_invocation.id = #{job.id}").map(&:id).sort
|
94
|
-
|
94
|
+
assert_equal job.template_invocations_host_ids.sort, found_ids
|
95
95
|
end
|
96
96
|
|
97
97
|
it 'finds hosts by job_invocation.result' do
|
98
98
|
success, failed = job.template_invocations
|
99
99
|
.partition { |template| template.run_host_job_task.result == 'success' }
|
100
100
|
found_ids = Host.search_for('job_invocation.result = success').map(&:id)
|
101
|
-
|
101
|
+
assert_equal success.map(&:host_id), found_ids
|
102
102
|
found_ids = Host.search_for('job_invocation.result = failed').map(&:id)
|
103
|
-
|
103
|
+
assert_equal failed.map(&:host_id), found_ids
|
104
104
|
end
|
105
105
|
|
106
106
|
it 'finds hosts by job_invocation.id and job_invocation.result' do
|
@@ -108,24 +108,24 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
108
108
|
job
|
109
109
|
job2
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
111
|
+
assert_equal 2, Host.search_for("job_invocation.id = #{job.id}").count
|
112
|
+
assert_equal 2, Host.search_for("job_invocation.id = #{job2.id}").count
|
113
|
+
assert_equal 2, Host.search_for('job_invocation.result = success').count
|
114
|
+
assert_equal 2, Host.search_for('job_invocation.result = failed').count
|
115
115
|
|
116
116
|
success, failed = job.template_invocations
|
117
117
|
.partition { |template| template.run_host_job_task.result == 'success' }
|
118
118
|
found_ids = Host.search_for("job_invocation.id = #{job.id} AND job_invocation.result = success").map(&:id)
|
119
|
-
|
119
|
+
assert_equal success.map(&:host_id), found_ids
|
120
120
|
found_ids = Host.search_for("job_invocation.id = #{job.id} AND job_invocation.result = failed").map(&:id)
|
121
|
-
|
121
|
+
assert_equal failed.map(&:host_id), found_ids
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
125
|
describe 'proxy determination strategies' do
|
126
126
|
context 'subnet strategy' do
|
127
127
|
let(:host) { FactoryBot.build(:host, :with_execution) }
|
128
|
-
it { host.remote_execution_proxies(provider)[:subnet]
|
128
|
+
it { assert_includes host.remote_execution_proxies(provider)[:subnet], host.subnet.remote_execution_proxies.first }
|
129
129
|
end
|
130
130
|
|
131
131
|
context 'fallback strategy' do
|
@@ -138,7 +138,7 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
138
138
|
end
|
139
139
|
|
140
140
|
it 'returns a fallback proxy' do
|
141
|
-
host.remote_execution_proxies(provider)[:fallback]
|
141
|
+
assert_includes host.remote_execution_proxies(provider)[:fallback], host.subnet.tftp
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
@@ -149,7 +149,7 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
149
149
|
end
|
150
150
|
|
151
151
|
it 'returns no proxy' do
|
152
|
-
host.remote_execution_proxies(provider)[:fallback]
|
152
|
+
assert_empty host.remote_execution_proxies(provider)[:fallback]
|
153
153
|
end
|
154
154
|
end
|
155
155
|
end
|
@@ -167,15 +167,15 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
167
167
|
it 'returns correct proxies confined by taxonomies' do
|
168
168
|
proxy_in_taxonomies
|
169
169
|
proxy_no_taxonomies
|
170
|
-
host.remote_execution_proxies(provider)[:global]
|
171
|
-
host.remote_execution_proxies(provider)[:global]
|
170
|
+
assert_includes host.remote_execution_proxies(provider)[:global], proxy_in_taxonomies
|
171
|
+
refute_includes host.remote_execution_proxies(provider)[:global], proxy_no_taxonomies
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
175
|
context 'disabled' do
|
176
176
|
before { Setting[:remote_execution_global_proxy] = false }
|
177
177
|
it 'returns no proxy' do
|
178
|
-
host.remote_execution_proxies(provider)[:global]
|
178
|
+
assert_empty host.remote_execution_proxies(provider)[:global]
|
179
179
|
end
|
180
180
|
end
|
181
181
|
end
|
@@ -195,8 +195,8 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
195
195
|
setup_user('view', 'hosts')
|
196
196
|
|
197
197
|
hosts = ::Host::Managed.execution_scope
|
198
|
-
hosts
|
199
|
-
hosts
|
198
|
+
assert_includes hosts, host
|
199
|
+
refute_includes hosts, infra_host
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
@@ -204,15 +204,15 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
|
|
204
204
|
it 'finds the host as admin' do
|
205
205
|
assert User.current.admin?
|
206
206
|
hosts = ::Host::Managed.execution_scope
|
207
|
-
hosts
|
208
|
-
hosts
|
207
|
+
assert_includes hosts, host
|
208
|
+
assert_includes hosts, infra_host
|
209
209
|
end
|
210
210
|
|
211
211
|
it 'finds the host as user with needed permissions' do
|
212
212
|
setup_user('execute_jobs_on', 'infrastructure_hosts')
|
213
213
|
hosts = ::Host::Managed.execution_scope
|
214
|
-
hosts
|
215
|
-
hosts
|
214
|
+
assert_includes hosts, host
|
215
|
+
assert_includes hosts, infra_host
|
216
216
|
end
|
217
217
|
end
|
218
218
|
end
|
@@ -4,6 +4,6 @@ class ForemanRemoteExecutionNicExtensionsTest < ActiveSupport::TestCase
|
|
4
4
|
let(:host) { FactoryBot.create(:host) }
|
5
5
|
|
6
6
|
it 'sets the first primary interface as the execution interface' do
|
7
|
-
|
7
|
+
assert_equal host.interfaces.first, host.execution_interface
|
8
8
|
end
|
9
9
|
end
|
@@ -5,11 +5,11 @@ class ExecutionTaskStatusMapperTest < ActiveSupport::TestCase
|
|
5
5
|
let(:subject) { HostStatus::ExecutionStatus::ExecutionTaskStatusMapper }
|
6
6
|
|
7
7
|
it 'accepts status number as well as string representation' do
|
8
|
-
|
8
|
+
assert_equal subject.sql_conditions_for('failed'), subject.sql_conditions_for(HostStatus::ExecutionStatus::ERROR)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'does not find any task for unknown state' do
|
12
|
-
|
12
|
+
assert_equal [ '1 = 0' ], subject.sql_conditions_for(-1)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -22,12 +22,12 @@ class ExecutionTaskStatusMapperTest < ActiveSupport::TestCase
|
|
22
22
|
describe 'is queued' do
|
23
23
|
context 'when there is no task' do
|
24
24
|
before { subject.task = nil }
|
25
|
-
specify {
|
25
|
+
specify { assert_equal HostStatus::ExecutionStatus::QUEUED, subject.status }
|
26
26
|
end
|
27
27
|
|
28
28
|
context 'when the task is scheduled in future' do
|
29
29
|
before { subject.task.state = 'scheduled' }
|
30
|
-
specify {
|
30
|
+
specify { assert_equal HostStatus::ExecutionStatus::QUEUED, subject.status }
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -37,19 +37,19 @@ class ExecutionTaskStatusMapperTest < ActiveSupport::TestCase
|
|
37
37
|
describe 'is succeeded' do
|
38
38
|
context 'without error' do
|
39
39
|
before { subject.task.result = 'success' }
|
40
|
-
specify {
|
40
|
+
specify { assert_equal HostStatus::ExecutionStatus::OK, subject.status }
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
describe 'is failed' do
|
45
45
|
context 'with error' do
|
46
46
|
before { subject.task.result = 'error' }
|
47
|
-
specify {
|
47
|
+
specify { assert_equal HostStatus::ExecutionStatus::ERROR, subject.status }
|
48
48
|
end
|
49
49
|
|
50
50
|
context 'without error but just with warning (sub task failed)' do
|
51
51
|
before { subject.task.result = 'warning' }
|
52
|
-
specify {
|
52
|
+
specify { assert_equal HostStatus::ExecutionStatus::ERROR, subject.status }
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -58,7 +58,7 @@ class ExecutionTaskStatusMapperTest < ActiveSupport::TestCase
|
|
58
58
|
before { subject.task.state = 'running' }
|
59
59
|
|
60
60
|
describe 'is pending' do
|
61
|
-
specify {
|
61
|
+
specify { assert_equal HostStatus::ExecutionStatus::RUNNING, subject.status }
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -73,7 +73,7 @@ class ExecutionTaskStatusMapperTest < ActiveSupport::TestCase
|
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'returns ok label' do
|
76
|
-
|
76
|
+
assert_equal HostStatus::ExecutionStatus::STATUS_NAMES[HostStatus::ExecutionStatus::OK], subject
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -84,7 +84,7 @@ class ExecutionTaskStatusMapperTest < ActiveSupport::TestCase
|
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'returns failed label' do
|
87
|
-
|
87
|
+
assert_equal HostStatus::ExecutionStatus::STATUS_NAMES[HostStatus::ExecutionStatus::ERROR], subject
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|