foreman_remote_execution 13.0.0 → 13.1.0
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.
- checksums.yaml +4 -4
- data/.eslintrc +4 -1
- data/.github/workflows/release.yml +4 -2
- data/app/lib/actions/remote_execution/run_host_job.rb +0 -14
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +8 -0
- data/app/models/job_invocation_composer.rb +4 -3
- data/app/views/api/v2/job_invocations/base.json.rabl +5 -3
- 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/version.rb +1 -1
- data/package.json +6 -6
- data/test/unit/job_invocation_composer_test.rb +31 -3
- 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/JobWizardPageRerun.js +3 -0
- data/webpack/JobWizard/StartsBeforeErrorAlert.js +1 -0
- data/webpack/JobWizard/index.js +1 -0
- 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 +16 -3
- data/webpack/JobWizard/steps/HostsAndInputs/HostPreviewModal.js +5 -1
- data/webpack/JobWizard/steps/HostsAndInputs/SelectedChips.js +8 -1
- data/webpack/JobWizard/steps/HostsAndInputs/index.js +7 -2
- data/webpack/JobWizard/steps/ReviewDetails/index.js +4 -0
- 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 +1 -0
- data/webpack/JobWizard/steps/form/SelectField.js +1 -0
- data/webpack/JobWizard/steps/form/WizardTitle.js +6 -1
- 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 +9 -6
@@ -48,6 +48,7 @@ const JobWizardPageRerun = ({
|
|
48
48
|
searchable={false}
|
49
49
|
toolbarButtons={
|
50
50
|
<Button
|
51
|
+
ouiaId="job-wizard-rerun-old-form-button"
|
51
52
|
variant="link"
|
52
53
|
component="a"
|
53
54
|
href={`/old/job_invocations/${id}/rerun${search}`}
|
@@ -71,6 +72,7 @@ const JobWizardPageRerun = ({
|
|
71
72
|
<React.Fragment>
|
72
73
|
{jobOrganization?.id !== currentOrganization?.id && (
|
73
74
|
<Alert
|
75
|
+
ouiaId="job-wizard-alert-organization"
|
74
76
|
isInline
|
75
77
|
className="job-wizard-alert"
|
76
78
|
variant="warning"
|
@@ -85,6 +87,7 @@ const JobWizardPageRerun = ({
|
|
85
87
|
)}
|
86
88
|
{jobLocation?.id !== currentLocation?.id && (
|
87
89
|
<Alert
|
90
|
+
ouiaId="job-wizard-alert-location"
|
88
91
|
isInline
|
89
92
|
className="job-wizard-alert"
|
90
93
|
variant="warning"
|
data/webpack/JobWizard/index.js
CHANGED
@@ -56,7 +56,12 @@ export const DescriptionField = ({
|
|
56
56
|
}
|
57
57
|
fieldId="description"
|
58
58
|
helperText={
|
59
|
-
<Button
|
59
|
+
<Button
|
60
|
+
ouiaId="description-preview-button"
|
61
|
+
variant="link"
|
62
|
+
isInline
|
63
|
+
onClick={togglePreview}
|
64
|
+
>
|
60
65
|
{isPreview
|
61
66
|
? __('Edit job description template')
|
62
67
|
: __('Preview job description')}
|
@@ -68,6 +73,7 @@ export const DescriptionField = ({
|
|
68
73
|
<div>
|
69
74
|
{/* div wrapper so the tooltip will be shown in chrome */}
|
70
75
|
<TextInput
|
76
|
+
ouiaId="description-preview"
|
71
77
|
aria-label="description preview"
|
72
78
|
id="description-preview"
|
73
79
|
value={generatedDesc}
|
@@ -77,6 +83,7 @@ export const DescriptionField = ({
|
|
77
83
|
</Tooltip>
|
78
84
|
) : (
|
79
85
|
<TextInput
|
86
|
+
ouiaId="description-edit"
|
80
87
|
aria-label="description edit"
|
81
88
|
type="text"
|
82
89
|
autoComplete="description"
|
@@ -19,6 +19,7 @@ export const EffectiveUserField = ({ value, setValue, defaultValue }) => (
|
|
19
19
|
labelInfo={<ResetDefault setValue={setValue} defaultValue={defaultValue} />}
|
20
20
|
>
|
21
21
|
<TextInput
|
22
|
+
ouiaId="effective-user"
|
22
23
|
aria-label="effective user"
|
23
24
|
autoComplete="effective-user"
|
24
25
|
id="effective-user"
|
@@ -86,6 +87,7 @@ export const PasswordField = ({ value, setValue }) => (
|
|
86
87
|
fieldId="job-password"
|
87
88
|
>
|
88
89
|
<TextInput
|
90
|
+
ouiaId="job-password"
|
89
91
|
aria-label="job password"
|
90
92
|
autoComplete="new-password" // to prevent firefox from autofilling the user password
|
91
93
|
id="job-password"
|
@@ -109,6 +111,7 @@ export const KeyPassphraseField = ({ value, setValue }) => (
|
|
109
111
|
fieldId="key-passphrase"
|
110
112
|
>
|
111
113
|
<TextInput
|
114
|
+
ouiaId="key-passphrase"
|
112
115
|
aria-label="key passphrase"
|
113
116
|
autoComplete="key-passphrase"
|
114
117
|
id="key-passphrase"
|
@@ -132,6 +135,7 @@ export const EffectiveUserPasswordField = ({ value, setValue }) => (
|
|
132
135
|
fieldId="effective-user-password"
|
133
136
|
>
|
134
137
|
<TextInput
|
138
|
+
ouiaId="effective-user-password"
|
135
139
|
aria-label="effective userpassword"
|
136
140
|
autoComplete="effective-user-password"
|
137
141
|
id="effective-user-password"
|
@@ -186,6 +190,7 @@ export const ExecutionOrderingField = ({ isRandomizedOrdering, setValue }) => (
|
|
186
190
|
isInline
|
187
191
|
>
|
188
192
|
<Radio
|
193
|
+
ouiaId="execution-order-alphabetical"
|
189
194
|
aria-label="execution order alphabetical"
|
190
195
|
isChecked={!isRandomizedOrdering}
|
191
196
|
name="execution-order"
|
@@ -194,6 +199,7 @@ export const ExecutionOrderingField = ({ isRandomizedOrdering, setValue }) => (
|
|
194
199
|
label={__('Alphabetical')}
|
195
200
|
/>
|
196
201
|
<Radio
|
202
|
+
ouiaId="execution-order-randomized"
|
197
203
|
aria-label="execution order randomized"
|
198
204
|
isChecked={isRandomizedOrdering}
|
199
205
|
name="execution-order"
|
@@ -216,6 +222,7 @@ export const SSHUserField = ({ value, setValue, defaultValue }) => (
|
|
216
222
|
labelInfo={<ResetDefault setValue={setValue} defaultValue={defaultValue} />}
|
217
223
|
>
|
218
224
|
<TextInput
|
225
|
+
ouiaId="ssh-user"
|
219
226
|
aria-label="ssh user"
|
220
227
|
autoComplete="ssh-user"
|
221
228
|
id="ssh-user"
|
@@ -71,7 +71,12 @@ export const CategoryAndTemplate = ({
|
|
71
71
|
return (
|
72
72
|
<>
|
73
73
|
<WizardTitle title={WIZARD_TITLES.categoryAndTemplate} />
|
74
|
-
<Text
|
74
|
+
<Text
|
75
|
+
ouiaId="category-and-template-required-fields"
|
76
|
+
component={TextVariants.p}
|
77
|
+
>
|
78
|
+
{__('All fields are required.')}
|
79
|
+
</Text>
|
75
80
|
<Form>
|
76
81
|
<SelectField
|
77
82
|
label={__('Job category')}
|
@@ -95,7 +100,11 @@ export const CategoryAndTemplate = ({
|
|
95
100
|
placeholderText={allTemplatesError ? __('Not available') : ''}
|
96
101
|
/>
|
97
102
|
{!isEmpty(missingPermissions) && (
|
98
|
-
<Alert
|
103
|
+
<Alert
|
104
|
+
ouiaId="category-and-template-access-denied"
|
105
|
+
variant="warning"
|
106
|
+
title={__('Access denied')}
|
107
|
+
>
|
99
108
|
<span>
|
100
109
|
{__(
|
101
110
|
`Missing the required permissions: ${missingPermissions.join(
|
@@ -106,7 +115,11 @@ export const CategoryAndTemplate = ({
|
|
106
115
|
</Alert>
|
107
116
|
)}
|
108
117
|
{isError && (
|
109
|
-
<Alert
|
118
|
+
<Alert
|
119
|
+
variant="danger"
|
120
|
+
title={__('Errors:')}
|
121
|
+
ouiaId="category-and-template-errors"
|
122
|
+
>
|
110
123
|
{categoryError && isEmpty(missingPermissions) && (
|
111
124
|
<span>
|
112
125
|
{__('Categories list failed with:')} {categoryError}
|
@@ -5,6 +5,7 @@ import URI from 'urijs';
|
|
5
5
|
import { List, ListItem, Modal, Button } from '@patternfly/react-core';
|
6
6
|
import { translate as __, sprintf } from 'foremanReact/common/I18n';
|
7
7
|
import { foremanUrl } from 'foremanReact/common/helpers';
|
8
|
+
import { HOSTS_PATH } from 'foremanReact/routes/Hosts/constants';
|
8
9
|
import { selectHosts, selectHostCount } from '../../JobWizardSelectors';
|
9
10
|
import { HOSTS_TO_PREVIEW_AMOUNT } from '../../JobWizardConstants';
|
10
11
|
|
@@ -15,6 +16,7 @@ export const HostPreviewModal = ({ isOpen, setIsOpen, searchQuery }) => {
|
|
15
16
|
|
16
17
|
return (
|
17
18
|
<Modal
|
19
|
+
ouiaId="host-preview-modal"
|
18
20
|
title={__('Preview Hosts')}
|
19
21
|
isOpen={isOpen}
|
20
22
|
onClose={() => setIsOpen(false)}
|
@@ -24,8 +26,9 @@ export const HostPreviewModal = ({ isOpen, setIsOpen, searchQuery }) => {
|
|
24
26
|
{hosts.map(host => (
|
25
27
|
<ListItem key={host.name}>
|
26
28
|
<Button
|
29
|
+
ouiaId={`host-preview-${host}`}
|
27
30
|
component="a"
|
28
|
-
href={foremanUrl(
|
31
|
+
href={foremanUrl(`${HOSTS_PATH}/${host.name}`)}
|
29
32
|
variant="link"
|
30
33
|
target="_blank"
|
31
34
|
rel="noreferrer"
|
@@ -38,6 +41,7 @@ export const HostPreviewModal = ({ isOpen, setIsOpen, searchQuery }) => {
|
|
38
41
|
{hostsCount > HOSTS_TO_PREVIEW_AMOUNT && (
|
39
42
|
<ListItem>
|
40
43
|
<Button
|
44
|
+
ouiaId="host-preview-more"
|
41
45
|
component="a"
|
42
46
|
href={url.addSearch({ search: searchQuery })}
|
43
47
|
variant="link"
|
@@ -14,6 +14,7 @@ const SelectedChip = ({ selected, setSelected, categoryName, setLabel }) => {
|
|
14
14
|
return (
|
15
15
|
<>
|
16
16
|
<ChipGroup
|
17
|
+
ouiaId="hosts-chip-group"
|
17
18
|
className="hosts-chip-group"
|
18
19
|
categoryName={categoryName}
|
19
20
|
isClosable
|
@@ -26,6 +27,7 @@ const SelectedChip = ({ selected, setSelected, categoryName, setLabel }) => {
|
|
26
27
|
>
|
27
28
|
{selected.map((result, index) => (
|
28
29
|
<Chip
|
30
|
+
ouiaId={`${categoryName}-${result.id}`}
|
29
31
|
key={index}
|
30
32
|
id={`${categoryName}-${result.id}`}
|
31
33
|
onClick={() => deleteItem(result.id)}
|
@@ -93,7 +95,12 @@ export const SelectedChips = ({
|
|
93
95
|
setLabel={setLabel}
|
94
96
|
/>
|
95
97
|
{showClear && (
|
96
|
-
<Button
|
98
|
+
<Button
|
99
|
+
ouiaId="clear-chips"
|
100
|
+
variant="link"
|
101
|
+
className="clear-chips"
|
102
|
+
onClick={clearAll}
|
103
|
+
>
|
97
104
|
{__('Clear all filters')}
|
98
105
|
</Button>
|
99
106
|
)}
|
@@ -229,9 +229,10 @@ const HostsAndInputs = ({
|
|
229
229
|
clearSearch={clearSearch}
|
230
230
|
setLabel={setLabel}
|
231
231
|
/>
|
232
|
-
<Text>
|
232
|
+
<Text ouiaId="host-preview-label">
|
233
233
|
{__('Apply to')}{' '}
|
234
234
|
<Button
|
235
|
+
ouiaId="host-preview-open-button"
|
235
236
|
variant="link"
|
236
237
|
isInline
|
237
238
|
onClick={() => setHostPreviewOpen(true)}
|
@@ -247,7 +248,11 @@ const HostsAndInputs = ({
|
|
247
248
|
setValue={setTemplateValues}
|
248
249
|
/>
|
249
250
|
{!isEmpty(missingPermissions) && (
|
250
|
-
<Alert
|
251
|
+
<Alert
|
252
|
+
ouiaId="host-access-denied"
|
253
|
+
variant="warning"
|
254
|
+
title={__('Access denied')}
|
255
|
+
>
|
251
256
|
<span>
|
252
257
|
{__(
|
253
258
|
`Missing the required permissions: ${missingPermissions.join(
|
@@ -46,6 +46,7 @@ const ReviewDetails = ({
|
|
46
46
|
// eslint-disable-next-line react/prop-types
|
47
47
|
const StepButton = ({ stepName, children }) => (
|
48
48
|
<Button
|
49
|
+
ouiaId={`step-button-${stepName}`}
|
49
50
|
variant="link"
|
50
51
|
isInline
|
51
52
|
onClick={() => {
|
@@ -91,6 +92,7 @@ const ReviewDetails = ({
|
|
91
92
|
<div>
|
92
93
|
{hostsCount} {__('hosts')}{' '}
|
93
94
|
<Button
|
95
|
+
ouiaId="view-host-names"
|
94
96
|
variant="link"
|
95
97
|
isInline
|
96
98
|
onClick={() => setHostPreviewOpen(true)}
|
@@ -140,6 +142,7 @@ const ReviewDetails = ({
|
|
140
142
|
),
|
141
143
|
value: isAdvancedShown ? (
|
142
144
|
<Button
|
145
|
+
ouiaId="hide-advanced-fields"
|
143
146
|
variant="link"
|
144
147
|
isInline
|
145
148
|
onClick={() => {
|
@@ -150,6 +153,7 @@ const ReviewDetails = ({
|
|
150
153
|
</Button>
|
151
154
|
) : (
|
152
155
|
<Button
|
156
|
+
ouiaId="show-advanced-fields"
|
153
157
|
variant="link"
|
154
158
|
isInline
|
155
159
|
onClick={() => {
|
@@ -15,6 +15,7 @@ export const QueryType = ({ isTypeStatic, setIsTypeStatic }) => (
|
|
15
15
|
)}
|
16
16
|
>
|
17
17
|
<Radio
|
18
|
+
ouiaId="query-type-static"
|
18
19
|
isChecked={isTypeStatic}
|
19
20
|
name="query-type"
|
20
21
|
onChange={() => setIsTypeStatic(true)}
|
@@ -25,6 +26,7 @@ export const QueryType = ({ isTypeStatic, setIsTypeStatic }) => (
|
|
25
26
|
</FormGroup>
|
26
27
|
<FormGroup fieldId="query-type-dynamic">
|
27
28
|
<Radio
|
29
|
+
ouiaId="query-type-dynamic"
|
28
30
|
isChecked={!isTypeStatic}
|
29
31
|
name="query-type"
|
30
32
|
onChange={() => setIsTypeStatic(false)}
|
@@ -34,6 +34,7 @@ export const RepeatHour = ({ repeatData, setRepeatData }) => {
|
|
34
34
|
isRequired
|
35
35
|
>
|
36
36
|
<Select
|
37
|
+
ouiaId="repeat-on-hourly"
|
37
38
|
id="repeat-on-hourly"
|
38
39
|
variant={SelectVariant.typeahead}
|
39
40
|
typeAheadAriaLabel="repeat-at-minute-typeahead"
|
@@ -75,6 +76,7 @@ export const RepeatHour = ({ repeatData, setRepeatData }) => {
|
|
75
76
|
</Select>
|
76
77
|
{isAlertOpen && (
|
77
78
|
<Alert
|
79
|
+
ouiaId="repeat-on-hourly-alert"
|
78
80
|
variant="danger"
|
79
81
|
isInline
|
80
82
|
title={__('Minute can only be a number between 0-59')}
|
@@ -19,6 +19,7 @@ export const RepeatMonth = ({ repeatData, setRepeatData, setValid }) => {
|
|
19
19
|
<>
|
20
20
|
<FormGroup label={__('Days')} isRequired>
|
21
21
|
<TextInput
|
22
|
+
ouiaId="repeat-on-monthly-days"
|
22
23
|
isRequired
|
23
24
|
validated={days ? ValidatedOptions.noval : ValidatedOptions.error}
|
24
25
|
aria-label="days"
|
@@ -44,6 +44,7 @@ export const RepeatWeek = ({ repeatData, setRepeatData, setValid }) => {
|
|
44
44
|
<div id="repeat-on-weekly">
|
45
45
|
{days.map((day, index) => (
|
46
46
|
<Checkbox
|
47
|
+
ouiaId={`repeat-on-day-${index}`}
|
47
48
|
aria-label={`${day} checkbox`}
|
48
49
|
key={index}
|
49
50
|
isChecked={daysOfWeek?.[index]}
|
@@ -61,6 +61,7 @@ export const ScheduleFuture = ({
|
|
61
61
|
}
|
62
62
|
/>
|
63
63
|
<Button
|
64
|
+
ouiaId="clear-datetime-start-button"
|
64
65
|
variant="link"
|
65
66
|
isInline
|
66
67
|
className="clear-datetime-button"
|
@@ -101,6 +102,7 @@ export const ScheduleFuture = ({
|
|
101
102
|
variant="link"
|
102
103
|
isInline
|
103
104
|
className="clear-datetime-button"
|
105
|
+
ouiaId="clear-datetime-end-button"
|
104
106
|
onClick={() =>
|
105
107
|
setScheduleValue(current => ({
|
106
108
|
...current,
|
@@ -89,6 +89,7 @@ export const ScheduleRecurring = ({
|
|
89
89
|
<div className="pf-c-form">
|
90
90
|
<FormGroup fieldId="schedule-starts-now">
|
91
91
|
<Radio
|
92
|
+
ouiaId="schedule-start-now"
|
92
93
|
isChecked={!isFuture}
|
93
94
|
onChange={() =>
|
94
95
|
setScheduleValue(current => ({
|
@@ -105,6 +106,7 @@ export const ScheduleRecurring = ({
|
|
105
106
|
</FormGroup>
|
106
107
|
<FormGroup fieldId="start-at-date">
|
107
108
|
<Radio
|
109
|
+
ouiaId="schedule-start-at-date"
|
108
110
|
isChecked={isFuture}
|
109
111
|
onChange={() =>
|
110
112
|
setScheduleValue(current => ({
|
@@ -161,6 +163,7 @@ export const ScheduleRecurring = ({
|
|
161
163
|
<div className="pf-c-form">
|
162
164
|
<FormGroup fieldId="schedule-ends-never">
|
163
165
|
<Radio
|
166
|
+
ouiaId="schedule-never-ends"
|
164
167
|
isChecked={isNeverEnds}
|
165
168
|
onChange={() =>
|
166
169
|
setScheduleValue(current => ({
|
@@ -184,6 +187,7 @@ export const ScheduleRecurring = ({
|
|
184
187
|
helperTextInvalidIcon={<ExclamationCircleIcon />}
|
185
188
|
>
|
186
189
|
<Radio
|
190
|
+
ouiaId="schedule-ends-on-date"
|
187
191
|
isChecked={!!ends}
|
188
192
|
onChange={() =>
|
189
193
|
setScheduleValue(current => ({
|
@@ -216,6 +220,7 @@ export const ScheduleRecurring = ({
|
|
216
220
|
</FormGroup>
|
217
221
|
<FormGroup fieldId="ends-after">
|
218
222
|
<Radio
|
223
|
+
ouiaId="schedule-ends-after"
|
219
224
|
isChecked={repeatAmount === 0 || !!repeatAmount}
|
220
225
|
onChange={() =>
|
221
226
|
setScheduleValue(current => ({
|
@@ -239,6 +244,7 @@ export const ScheduleRecurring = ({
|
|
239
244
|
className="schedule-radio-repeat-text"
|
240
245
|
>
|
241
246
|
<TextInput
|
247
|
+
ouiaId="repeat-amount"
|
242
248
|
id="repeat-amount"
|
243
249
|
value={repeatAmount || ''}
|
244
250
|
type="number"
|
@@ -24,6 +24,7 @@ export const ScheduleType = ({
|
|
24
24
|
label={__('Select the type of execution')}
|
25
25
|
>
|
26
26
|
<Radio
|
27
|
+
ouiaId="schedule-type-now"
|
27
28
|
isChecked={scheduleType === SCHEDULE_TYPES.NOW}
|
28
29
|
name="schedule-type-now"
|
29
30
|
id="schedule-type-now"
|
@@ -43,6 +44,7 @@ export const ScheduleType = ({
|
|
43
44
|
</FormGroup>
|
44
45
|
<FormGroup fieldId="schedule-type-future">
|
45
46
|
<Radio
|
47
|
+
ouiaId="schedule-type-future"
|
46
48
|
isChecked={scheduleType === SCHEDULE_TYPES.FUTURE}
|
47
49
|
onChange={() => {
|
48
50
|
setScheduleValue(current => ({
|
@@ -61,6 +63,7 @@ export const ScheduleType = ({
|
|
61
63
|
</FormGroup>
|
62
64
|
<FormGroup fieldId="schedule-type-recurring">
|
63
65
|
<Radio
|
66
|
+
ouiaId="schedule-type-recurring"
|
64
67
|
isChecked={scheduleType === SCHEDULE_TYPES.RECURRING}
|
65
68
|
onChange={() => {
|
66
69
|
setScheduleValue(current => ({
|
@@ -3,7 +3,12 @@ import PropTypes from 'prop-types';
|
|
3
3
|
import { Title } from '@patternfly/react-core';
|
4
4
|
|
5
5
|
export const WizardTitle = ({ title, ...props }) => (
|
6
|
-
<Title
|
6
|
+
<Title
|
7
|
+
ouiaId="wizard-title"
|
8
|
+
headingLevel="h2"
|
9
|
+
className="wizard-title"
|
10
|
+
{...props}
|
11
|
+
>
|
7
12
|
{title}
|
8
13
|
</Title>
|
9
14
|
);
|
@@ -0,0 +1 @@
|
|
1
|
+
export const HOSTS_PATH = '/new/hosts';
|
@@ -53,6 +53,7 @@ const FeaturesDropdown = ({
|
|
53
53
|
?.filter(feature => feature.host_action_button)
|
54
54
|
?.map(({ name, label, id, description }) => (
|
55
55
|
<DropdownItem
|
56
|
+
ouiaId={`schedule-a-job-dropdown-item-${id}`}
|
56
57
|
onClick={() => dispatch(runFeature(hostId, label, name, hostSearch))}
|
57
58
|
key={id}
|
58
59
|
description={description}
|
@@ -64,18 +64,21 @@ const RecentJobsCard = ({ hostDetails: { name, id } }) => {
|
|
64
64
|
onSelect={handleTabClick}
|
65
65
|
>
|
66
66
|
<Tab
|
67
|
+
ouiaId="finished-tab"
|
67
68
|
eventKey={FINISHED_TAB}
|
68
69
|
title={<TabTitleText>{__('Finished')}</TabTitleText>}
|
69
70
|
>
|
70
71
|
<RecentJobsTable hostId={id} status="failed+or+status%3D+succeeded" />
|
71
72
|
</Tab>
|
72
73
|
<Tab
|
74
|
+
ouiaId="running-tab"
|
73
75
|
eventKey={RUNNING_TAB}
|
74
76
|
title={<TabTitleText>{__('Running')}</TabTitleText>}
|
75
77
|
>
|
76
78
|
<RecentJobsTable hostId={id} status="running" />
|
77
79
|
</Tab>
|
78
80
|
<Tab
|
81
|
+
ouiaId="scheduled-tab"
|
79
82
|
eventKey={SCHEDULED_TAB}
|
80
83
|
title={<TabTitleText>{__('Scheduled')}</TabTitleText>}
|
81
84
|
>
|
@@ -42,6 +42,7 @@ const RecentJobsTable = ({ status, hostId }) => {
|
|
42
42
|
>
|
43
43
|
{!!jobs?.length && (
|
44
44
|
<TableComposable
|
45
|
+
ouiaId="recent-jobs-table"
|
45
46
|
aria-label="recent-jobs-table"
|
46
47
|
variant="compact"
|
47
48
|
borders="compactBorderless"
|
@@ -55,7 +56,7 @@ const RecentJobsTable = ({ status, hostId }) => {
|
|
55
56
|
start_at: startAt,
|
56
57
|
description,
|
57
58
|
}) => (
|
58
|
-
<Tr key={id}>
|
59
|
+
<Tr ouiaId="recent-jobs-table-row" key={id}>
|
59
60
|
<Td modifier="truncate" key={`name-${id}`}>
|
60
61
|
<a href={foremanUrl(`/job_invocations/${id}`)}>
|
61
62
|
{description}
|
@@ -36,6 +36,7 @@ const RexPull = ({ isLoading, onChange, pluginValues, configParams }) => (
|
|
36
36
|
fieldId="registration_setup_remote_execution_pull"
|
37
37
|
>
|
38
38
|
<FormSelect
|
39
|
+
ouiaId="registration_setup_remote_execution_pull"
|
39
40
|
value={pluginValues.setupRemoteExecutionPull}
|
40
41
|
onChange={setupRemoteExecutionPull =>
|
41
42
|
onChange({ setupRemoteExecutionPull })
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 13.
|
4
|
+
version: 13.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Remote Execution team
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|
@@ -436,8 +436,10 @@ files:
|
|
436
436
|
- test/unit/template_invocation_input_value_test.rb
|
437
437
|
- webpack/JobInvocationDetail/JobInvocationActions.js
|
438
438
|
- webpack/JobInvocationDetail/JobInvocationConstants.js
|
439
|
+
- webpack/JobInvocationDetail/JobInvocationDetail.scss
|
439
440
|
- webpack/JobInvocationDetail/JobInvocationOverview.js
|
440
441
|
- webpack/JobInvocationDetail/JobInvocationSelectors.js
|
442
|
+
- webpack/JobInvocationDetail/JobInvocationSystemStatusChart.js
|
441
443
|
- webpack/JobInvocationDetail/index.js
|
442
444
|
- webpack/JobWizard/Footer.js
|
443
445
|
- webpack/JobWizard/JobWizard.js
|
@@ -518,6 +520,7 @@ files:
|
|
518
520
|
- webpack/__mocks__/foremanReact/redux/API/APISelectors.js
|
519
521
|
- webpack/__mocks__/foremanReact/redux/API/index.js
|
520
522
|
- webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors.js
|
523
|
+
- webpack/__mocks__/foremanReact/routes/Hosts/constants.js
|
521
524
|
- webpack/__mocks__/foremanReact/routes/RouterSelector.js
|
522
525
|
- webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js
|
523
526
|
- webpack/global_index.js
|
@@ -576,7 +579,7 @@ homepage: https://github.com/theforeman/foreman_remote_execution
|
|
576
579
|
licenses:
|
577
580
|
- GPL-3.0
|
578
581
|
metadata: {}
|
579
|
-
post_install_message:
|
582
|
+
post_install_message:
|
580
583
|
rdoc_options: []
|
581
584
|
require_paths:
|
582
585
|
- lib
|
@@ -594,8 +597,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
594
597
|
- !ruby/object:Gem::Version
|
595
598
|
version: '0'
|
596
599
|
requirements: []
|
597
|
-
rubygems_version: 3.3.
|
598
|
-
signing_key:
|
600
|
+
rubygems_version: 3.3.27
|
601
|
+
signing_key:
|
599
602
|
specification_version: 4
|
600
603
|
summary: A plugin bringing remote execution to the Foreman, completing the config
|
601
604
|
management functionality with remote management functionality.
|