foreman_remote_execution 4.3.0 → 4.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/job_invocations_controller.rb +27 -22
  3. data/app/controllers/foreman_remote_execution/concerns/api/v2/registration_commands_controller_extensions.rb +19 -0
  4. data/app/controllers/job_invocations_controller.rb +1 -1
  5. data/app/controllers/job_templates_controller.rb +4 -4
  6. data/app/controllers/ui_job_wizard_controller.rb +12 -0
  7. data/app/helpers/job_invocations_helper.rb +2 -2
  8. data/app/helpers/remote_execution_helper.rb +35 -8
  9. data/app/lib/actions/remote_execution/run_host_job.rb +37 -7
  10. data/app/lib/foreman_remote_execution/provider_input.rb +29 -0
  11. data/app/lib/foreman_remote_execution/renderer/scope/input.rb +1 -0
  12. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +7 -5
  13. data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +6 -0
  14. data/app/models/host_proxy_invocation.rb +4 -0
  15. data/app/models/host_status/execution_status.rb +5 -5
  16. data/app/models/invocation_provider_input_value.rb +12 -0
  17. data/app/models/job_invocation.rb +35 -12
  18. data/app/models/job_invocation_composer.rb +74 -19
  19. data/app/models/remote_execution_provider.rb +18 -3
  20. data/app/models/setting/remote_execution.rb +11 -1
  21. data/app/models/ssh_execution_provider.rb +4 -4
  22. data/app/models/targeting.rb +5 -1
  23. data/app/models/template_invocation.rb +2 -0
  24. data/app/overrides/execution_interface.rb +8 -8
  25. data/app/overrides/subnet_proxies.rb +6 -6
  26. data/app/services/renderer_methods.rb +12 -0
  27. data/app/views/job_invocations/_form.html.erb +8 -0
  28. data/app/views/job_invocations/index.html.erb +1 -1
  29. data/config/routes.rb +1 -0
  30. data/db/migrate/20180110104432_rename_template_invocation_permission.rb +1 -1
  31. data/db/migrate/20190111153330_remove_remote_execution_without_proxy_setting.rb +4 -4
  32. data/db/migrate/20210312074713_add_provider_inputs.rb +10 -0
  33. data/db/migrate/2021051713291621250977_add_host_proxy_invocations.rb +12 -0
  34. data/extra/cockpit/foreman-cockpit-session +6 -6
  35. data/foreman_remote_execution.gemspec +1 -1
  36. data/lib/foreman_remote_execution/engine.rb +14 -12
  37. data/lib/foreman_remote_execution/version.rb +1 -1
  38. data/lib/tasks/foreman_remote_execution_tasks.rake +1 -18
  39. data/locale/action_names.rb +1 -0
  40. data/locale/de/foreman_remote_execution.po +77 -27
  41. data/locale/en/foreman_remote_execution.po +77 -27
  42. data/locale/en_GB/foreman_remote_execution.po +77 -27
  43. data/locale/es/foreman_remote_execution.po +77 -27
  44. data/locale/foreman_remote_execution.pot +241 -163
  45. data/locale/fr/foreman_remote_execution.po +77 -27
  46. data/locale/ja/foreman_remote_execution.po +77 -27
  47. data/locale/ko/foreman_remote_execution.po +77 -27
  48. data/locale/pt_BR/foreman_remote_execution.po +77 -27
  49. data/locale/ru/foreman_remote_execution.po +77 -27
  50. data/locale/zh_CN/foreman_remote_execution.po +77 -27
  51. data/locale/zh_TW/foreman_remote_execution.po +77 -27
  52. data/package.json +4 -2
  53. data/test/functional/api/v2/job_invocations_controller_test.rb +14 -1
  54. data/test/helpers/remote_execution_helper_test.rb +16 -0
  55. data/test/unit/job_invocation_composer_test.rb +100 -3
  56. data/test/unit/job_invocation_report_template_test.rb +57 -0
  57. data/test/unit/job_invocation_test.rb +1 -1
  58. data/webpack/JobWizard/JobWizard.js +75 -11
  59. data/webpack/JobWizard/JobWizard.scss +14 -0
  60. data/webpack/JobWizard/JobWizardConstants.js +6 -0
  61. data/webpack/JobWizard/JobWizardSelectors.js +38 -0
  62. data/webpack/JobWizard/__tests__/JobWizard.test.js +13 -0
  63. data/webpack/JobWizard/__tests__/__snapshots__/JobWizard.test.js.snap +32 -0
  64. data/webpack/JobWizard/__tests__/__snapshots__/integration.test.js.snap +43 -0
  65. data/webpack/JobWizard/__tests__/fixtures.js +26 -0
  66. data/webpack/JobWizard/__tests__/integration.test.js +156 -0
  67. data/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js +93 -0
  68. data/webpack/JobWizard/steps/AdvancedFields/Fields.js +181 -0
  69. data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +25 -0
  70. data/webpack/JobWizard/steps/AdvancedFields/__tests__/__snapshots__/AdvancedFields.test.js.snap +249 -0
  71. data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js +109 -0
  72. data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.test.js +52 -0
  73. data/webpack/JobWizard/steps/CategoryAndTemplate/__snapshots__/CategoryAndTemplate.test.js.snap +113 -0
  74. data/webpack/JobWizard/steps/CategoryAndTemplate/index.js +94 -0
  75. data/webpack/JobWizard/steps/form/FormHelpers.js +19 -0
  76. data/webpack/JobWizard/steps/form/GroupedSelectField.js +91 -0
  77. data/webpack/JobWizard/steps/form/SelectField.js +48 -0
  78. data/webpack/JobWizard/steps/form/__tests__/GroupedSelectField.test.js +38 -0
  79. data/webpack/JobWizard/steps/form/__tests__/SelectField.test.js +23 -0
  80. data/webpack/JobWizard/steps/form/__tests__/__snapshots__/GroupedSelectField.test.js.snap +37 -0
  81. data/webpack/JobWizard/steps/form/__tests__/__snapshots__/SelectField.test.js.snap +23 -0
  82. data/webpack/__mocks__/foremanReact/common/helpers.js +1 -0
  83. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +21 -2
  84. data/webpack/__mocks__/foremanReact/redux/API/index.js +5 -0
  85. data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +10 -0
  86. data/webpack/global_index.js +6 -0
  87. data/webpack/index.js +3 -4
  88. data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +83 -0
  89. data/webpack/react_app/components/RecentJobsCard/constants.js +1 -0
  90. data/webpack/react_app/components/RecentJobsCard/index.js +1 -0
  91. data/webpack/react_app/components/RecentJobsCard/styles.css +15 -0
  92. data/webpack/react_app/components/RegistrationExtension/RexInterface.js +50 -0
  93. data/webpack/react_app/components/RegistrationExtension/__tests__/RexInterface.test.js +9 -0
  94. data/webpack/react_app/components/RegistrationExtension/__tests__/__snapshots__/RexInterface.test.js.snap +35 -0
  95. data/webpack/react_app/components/TargetingHosts/__tests__/TargetingHostsSelectors.test.js +8 -3
  96. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsSelectors.test.js.snap +7 -2
  97. data/webpack/react_app/extend/fillRecentJobsCard.js +11 -0
  98. data/webpack/react_app/extend/fillregistrationAdvanced.js +11 -0
  99. data/webpack/react_app/extend/reducers.js +5 -0
  100. metadata +49 -8
  101. data/app/models/concerns/foreman_remote_execution/orchestration/ssh.rb +0 -70
  102. data/app/views/api/v2/registration/_form.html.erb +0 -12
  103. data/test/models/orchestration/ssh_test.rb +0 -56
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useSelector } from 'react-redux';
4
+ import { Title, Form } from '@patternfly/react-core';
5
+ import { translate as __ } from 'foremanReact/common/I18n';
6
+ import { selectJobTemplate } from '../../JobWizardSelectors';
7
+ import {
8
+ EffectiveUserField,
9
+ TimeoutToKillField,
10
+ PasswordField,
11
+ KeyPassphraseField,
12
+ EffectiveUserPasswordField,
13
+ ConcurrencyLevelField,
14
+ TimeSpanLevelField,
15
+ } from './Fields';
16
+
17
+ export const AdvancedFields = ({ advancedValues, setAdvancedValues }) => {
18
+ const jobTemplate = useSelector(selectJobTemplate);
19
+ const effectiveUser = jobTemplate.effective_user;
20
+ return (
21
+ <>
22
+ <Title headingLevel="h2" className="advanced-fields-title">
23
+ {__('Advanced Fields')}
24
+ </Title>
25
+ <Form>
26
+ {effectiveUser?.overridable && (
27
+ <EffectiveUserField
28
+ value={advancedValues.effectiveUserValue}
29
+ setValue={newValue =>
30
+ setAdvancedValues({
31
+ effectiveUserValue: newValue,
32
+ })
33
+ }
34
+ />
35
+ )}
36
+ <TimeoutToKillField
37
+ value={advancedValues.timeoutToKill}
38
+ setValue={newValue =>
39
+ setAdvancedValues({
40
+ timeoutToKill: newValue,
41
+ })
42
+ }
43
+ />
44
+ <PasswordField
45
+ value={advancedValues.password}
46
+ setValue={newValue =>
47
+ setAdvancedValues({
48
+ password: newValue,
49
+ })
50
+ }
51
+ />
52
+ <KeyPassphraseField
53
+ value={advancedValues.keyPassphrase}
54
+ setValue={newValue =>
55
+ setAdvancedValues({
56
+ keyPassphrase: newValue,
57
+ })
58
+ }
59
+ />
60
+ <EffectiveUserPasswordField
61
+ value={advancedValues.effectiveUserPassword}
62
+ setValue={newValue =>
63
+ setAdvancedValues({
64
+ effectiveUserPassword: newValue,
65
+ })
66
+ }
67
+ />
68
+ <ConcurrencyLevelField
69
+ value={advancedValues.concurrencyLevel}
70
+ setValue={newValue =>
71
+ setAdvancedValues({
72
+ concurrencyLevel: newValue,
73
+ })
74
+ }
75
+ />
76
+ <TimeSpanLevelField
77
+ value={advancedValues.timeSpan}
78
+ setValue={newValue =>
79
+ setAdvancedValues({
80
+ timeSpan: newValue,
81
+ })
82
+ }
83
+ />
84
+ </Form>
85
+ </>
86
+ );
87
+ };
88
+
89
+ AdvancedFields.propTypes = {
90
+ advancedValues: PropTypes.object.isRequired,
91
+ setAdvancedValues: PropTypes.func.isRequired,
92
+ };
93
+ export default AdvancedFields;
@@ -0,0 +1,181 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { FormGroup, TextInput } from '@patternfly/react-core';
4
+ import { translate as __ } from 'foremanReact/common/I18n';
5
+ import { helpLabel } from '../form/FormHelpers';
6
+
7
+ export const EffectiveUserField = ({ value, setValue }) => (
8
+ <FormGroup
9
+ label={__('Effective user')}
10
+ labelIcon={helpLabel(
11
+ __(
12
+ 'A user to be used for executing the script. If it differs from the SSH user, su or sudo is used to switch the accounts.'
13
+ ),
14
+ 'effective-user'
15
+ )}
16
+ fieldId="effective-user"
17
+ >
18
+ <TextInput
19
+ autoComplete="effective-user"
20
+ id="effective-user"
21
+ type="text"
22
+ value={value}
23
+ onChange={newValue => setValue(newValue)}
24
+ />
25
+ </FormGroup>
26
+ );
27
+
28
+ export const TimeoutToKillField = ({ value, setValue }) => (
29
+ <FormGroup
30
+ label={__('Timeout to kill')}
31
+ labelIcon={helpLabel(
32
+ __(
33
+ 'Time in seconds from the start on the remote host after which the job should be killed.'
34
+ ),
35
+ 'timeout-to-kill'
36
+ )}
37
+ fieldId="timeout-to-kill"
38
+ >
39
+ <TextInput
40
+ type="number"
41
+ value={value}
42
+ placeholder={__('For example: 1, 2, 3, 4, 5...')}
43
+ autoComplete="timeout-to-kill"
44
+ id="timeout-to-kill"
45
+ onChange={newValue => setValue(newValue)}
46
+ />
47
+ </FormGroup>
48
+ );
49
+
50
+ export const PasswordField = ({ value, setValue }) => (
51
+ <FormGroup
52
+ label={__('Password')}
53
+ labelIcon={helpLabel(
54
+ __(
55
+ 'Password is stored encrypted in DB until the job finishes. For future or recurring executions, it is removed after the last execution.'
56
+ ),
57
+ 'password'
58
+ )}
59
+ fieldId="password"
60
+ >
61
+ <TextInput
62
+ autoComplete="password"
63
+ id="password"
64
+ type="password"
65
+ placeholder="*****"
66
+ value={value}
67
+ onChange={newValue => setValue(newValue)}
68
+ />
69
+ </FormGroup>
70
+ );
71
+
72
+ export const KeyPassphraseField = ({ value, setValue }) => (
73
+ <FormGroup
74
+ label={__('Private key passphrase')}
75
+ labelIcon={helpLabel(
76
+ __(
77
+ 'Key passphrase is only applicable for SSH provider. Other providers ignore this field. Passphrase is stored encrypted in DB until the job finishes. For future or recurring executions, it is removed after the last execution.'
78
+ ),
79
+ 'key-passphrase'
80
+ )}
81
+ fieldId="key-passphrase"
82
+ >
83
+ <TextInput
84
+ autoComplete="key-passphrase"
85
+ id="key-passphrase"
86
+ type="password"
87
+ placeholder="*****"
88
+ value={value}
89
+ onChange={newValue => setValue(newValue)}
90
+ />
91
+ </FormGroup>
92
+ );
93
+
94
+ export const EffectiveUserPasswordField = ({ value, setValue }) => (
95
+ <FormGroup
96
+ label={__('Effective user password')}
97
+ labelIcon={helpLabel(
98
+ __(
99
+ 'Effective user password is only applicable for SSH provider. Other providers ignore this field. Password is stored encrypted in DB until the job finishes. For future or recurring executions, it is removed after the last execution.'
100
+ ),
101
+ 'effective-user-password'
102
+ )}
103
+ fieldId="effective-user-password"
104
+ >
105
+ <TextInput
106
+ autoComplete="effective-user-password"
107
+ id="effective-user-password"
108
+ type="password"
109
+ placeholder="*****"
110
+ value={value}
111
+ onChange={newValue => setValue(newValue)}
112
+ />
113
+ </FormGroup>
114
+ );
115
+
116
+ export const ConcurrencyLevelField = ({ value, setValue }) => (
117
+ <FormGroup
118
+ label={__('Concurrency level')}
119
+ labelIcon={helpLabel(
120
+ __(
121
+ '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.'
122
+ ),
123
+ 'concurrency-level'
124
+ )}
125
+ fieldId="concurrency-level"
126
+ >
127
+ <TextInput
128
+ min={1}
129
+ type="number"
130
+ autoComplete="concurrency-level"
131
+ id="concurrency-level"
132
+ placeholder={__('For example: 1, 2, 3, 4, 5...')}
133
+ value={value}
134
+ onChange={newValue => setValue(newValue)}
135
+ />
136
+ </FormGroup>
137
+ );
138
+
139
+ export const TimeSpanLevelField = ({ value, setValue }) => (
140
+ <FormGroup
141
+ label={__('Time span')}
142
+ labelIcon={helpLabel(
143
+ __(
144
+ '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.'
145
+ ),
146
+ 'time-span'
147
+ )}
148
+ fieldId="time-span"
149
+ >
150
+ <TextInput
151
+ min={1}
152
+ type="number"
153
+ autoComplete="time-span"
154
+ id="time-span"
155
+ placeholder={__('For example: 1, 2, 3, 4, 5...')}
156
+ value={value}
157
+ onChange={newValue => setValue(newValue)}
158
+ />
159
+ </FormGroup>
160
+ );
161
+
162
+ EffectiveUserField.propTypes = {
163
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
164
+ setValue: PropTypes.func.isRequired,
165
+ };
166
+ EffectiveUserField.defaultProps = {
167
+ value: '',
168
+ };
169
+
170
+ TimeoutToKillField.propTypes = EffectiveUserField.propTypes;
171
+ TimeoutToKillField.defaultProps = EffectiveUserField.defaultProps;
172
+ PasswordField.propTypes = EffectiveUserField.propTypes;
173
+ PasswordField.defaultProps = EffectiveUserField.defaultProps;
174
+ KeyPassphraseField.propTypes = EffectiveUserField.propTypes;
175
+ KeyPassphraseField.defaultProps = EffectiveUserField.defaultProps;
176
+ EffectiveUserPasswordField.propTypes = EffectiveUserField.propTypes;
177
+ EffectiveUserPasswordField.defaultProps = EffectiveUserField.defaultProps;
178
+ ConcurrencyLevelField.propTypes = EffectiveUserField.propTypes;
179
+ ConcurrencyLevelField.defaultProps = EffectiveUserField.defaultProps;
180
+ TimeSpanLevelField.propTypes = EffectiveUserField.propTypes;
181
+ TimeSpanLevelField.defaultProps = EffectiveUserField.defaultProps;
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { Provider } from 'react-redux';
3
+ import configureMockStore from 'redux-mock-store';
4
+ import * as patternfly from '@patternfly/react-core';
5
+ import { mount } from '@theforeman/test';
6
+ import { AdvancedFields } from '../AdvancedFields';
7
+
8
+ jest.spyOn(patternfly, 'FormGroup');
9
+ patternfly.FormGroup.mockImplementation(props => (
10
+ <div>{props.navAriaLabel}</div>
11
+ ));
12
+ const mockStore = configureMockStore([]);
13
+ const store = mockStore({
14
+ JOB_TEMPLATE: { response: { effective_user: { overridable: true } } },
15
+ });
16
+ describe('AdvancedFields', () => {
17
+ it('rendring', () => {
18
+ const component = mount(
19
+ <Provider store={store}>
20
+ <AdvancedFields advancedValues={{}} setAdvancedValues={jest.fn()} />
21
+ </Provider>
22
+ );
23
+ expect(component).toMatchSnapshot();
24
+ });
25
+ });
@@ -0,0 +1,249 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`AdvancedFields rendring 1`] = `
4
+ <Provider
5
+ store={
6
+ Object {
7
+ "clearActions": [Function],
8
+ "dispatch": [Function],
9
+ "getActions": [Function],
10
+ "getState": [Function],
11
+ "replaceReducer": [Function],
12
+ "subscribe": [Function],
13
+ }
14
+ }
15
+ >
16
+ <AdvancedFields
17
+ advancedValues={Object {}}
18
+ setAdvancedValues={[MockFunction]}
19
+ >
20
+ <Title
21
+ className="advanced-fields-title"
22
+ headingLevel="h2"
23
+ >
24
+ <h2
25
+ className="pf-c-title pf-m-xl advanced-fields-title"
26
+ >
27
+ Advanced Fields
28
+ </h2>
29
+ </Title>
30
+ <Form>
31
+ <form
32
+ className="pf-c-form"
33
+ noValidate={true}
34
+ >
35
+ <EffectiveUserField
36
+ setValue={[Function]}
37
+ value=""
38
+ >
39
+ <mockConstructor
40
+ fieldId="effective-user"
41
+ label="Effective user"
42
+ labelIcon={
43
+ <Popover
44
+ aria-label="help-text"
45
+ bodyContent="A user to be used for executing the script. If it differs from the SSH user, su or sudo is used to switch the accounts."
46
+ id="effective-user-help"
47
+ >
48
+ <button
49
+ aria-label="open-help-tooltip-button"
50
+ className="pf-c-form__group-label-help"
51
+ onClick={[Function]}
52
+ >
53
+ <HelpIcon
54
+ color="currentColor"
55
+ noVerticalAlign={true}
56
+ size="sm"
57
+ />
58
+ </button>
59
+ </Popover>
60
+ }
61
+ >
62
+ <div />
63
+ </mockConstructor>
64
+ </EffectiveUserField>
65
+ <TimeoutToKillField
66
+ setValue={[Function]}
67
+ value=""
68
+ >
69
+ <mockConstructor
70
+ fieldId="timeout-to-kill"
71
+ label="Timeout to kill"
72
+ labelIcon={
73
+ <Popover
74
+ aria-label="help-text"
75
+ bodyContent="Time in seconds from the start on the remote host after which the job should be killed."
76
+ id="timeout-to-kill-help"
77
+ >
78
+ <button
79
+ aria-label="open-help-tooltip-button"
80
+ className="pf-c-form__group-label-help"
81
+ onClick={[Function]}
82
+ >
83
+ <HelpIcon
84
+ color="currentColor"
85
+ noVerticalAlign={true}
86
+ size="sm"
87
+ />
88
+ </button>
89
+ </Popover>
90
+ }
91
+ >
92
+ <div />
93
+ </mockConstructor>
94
+ </TimeoutToKillField>
95
+ <PasswordField
96
+ setValue={[Function]}
97
+ value=""
98
+ >
99
+ <mockConstructor
100
+ fieldId="password"
101
+ label="Password"
102
+ labelIcon={
103
+ <Popover
104
+ aria-label="help-text"
105
+ bodyContent="Password is stored encrypted in DB until the job finishes. For future or recurring executions, it is removed after the last execution."
106
+ id="password-help"
107
+ >
108
+ <button
109
+ aria-label="open-help-tooltip-button"
110
+ className="pf-c-form__group-label-help"
111
+ onClick={[Function]}
112
+ >
113
+ <HelpIcon
114
+ color="currentColor"
115
+ noVerticalAlign={true}
116
+ size="sm"
117
+ />
118
+ </button>
119
+ </Popover>
120
+ }
121
+ >
122
+ <div />
123
+ </mockConstructor>
124
+ </PasswordField>
125
+ <KeyPassphraseField
126
+ setValue={[Function]}
127
+ value=""
128
+ >
129
+ <mockConstructor
130
+ fieldId="key-passphrase"
131
+ label="Private key passphrase"
132
+ labelIcon={
133
+ <Popover
134
+ aria-label="help-text"
135
+ bodyContent="Key passphrase is only applicable for SSH provider. Other providers ignore this field. Passphrase is stored encrypted in DB until the job finishes. For future or recurring executions, it is removed after the last execution."
136
+ id="key-passphrase-help"
137
+ >
138
+ <button
139
+ aria-label="open-help-tooltip-button"
140
+ className="pf-c-form__group-label-help"
141
+ onClick={[Function]}
142
+ >
143
+ <HelpIcon
144
+ color="currentColor"
145
+ noVerticalAlign={true}
146
+ size="sm"
147
+ />
148
+ </button>
149
+ </Popover>
150
+ }
151
+ >
152
+ <div />
153
+ </mockConstructor>
154
+ </KeyPassphraseField>
155
+ <EffectiveUserPasswordField
156
+ setValue={[Function]}
157
+ value=""
158
+ >
159
+ <mockConstructor
160
+ fieldId="effective-user-password"
161
+ label="Effective user password"
162
+ labelIcon={
163
+ <Popover
164
+ aria-label="help-text"
165
+ bodyContent="Effective user password is only applicable for SSH provider. Other providers ignore this field. Password is stored encrypted in DB until the job finishes. For future or recurring executions, it is removed after the last execution."
166
+ id="effective-user-password-help"
167
+ >
168
+ <button
169
+ aria-label="open-help-tooltip-button"
170
+ className="pf-c-form__group-label-help"
171
+ onClick={[Function]}
172
+ >
173
+ <HelpIcon
174
+ color="currentColor"
175
+ noVerticalAlign={true}
176
+ size="sm"
177
+ />
178
+ </button>
179
+ </Popover>
180
+ }
181
+ >
182
+ <div />
183
+ </mockConstructor>
184
+ </EffectiveUserPasswordField>
185
+ <ConcurrencyLevelField
186
+ setValue={[Function]}
187
+ value=""
188
+ >
189
+ <mockConstructor
190
+ fieldId="concurrency-level"
191
+ label="Concurrency level"
192
+ labelIcon={
193
+ <Popover
194
+ aria-label="help-text"
195
+ bodyContent="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."
196
+ id="concurrency-level-help"
197
+ >
198
+ <button
199
+ aria-label="open-help-tooltip-button"
200
+ className="pf-c-form__group-label-help"
201
+ onClick={[Function]}
202
+ >
203
+ <HelpIcon
204
+ color="currentColor"
205
+ noVerticalAlign={true}
206
+ size="sm"
207
+ />
208
+ </button>
209
+ </Popover>
210
+ }
211
+ >
212
+ <div />
213
+ </mockConstructor>
214
+ </ConcurrencyLevelField>
215
+ <TimeSpanLevelField
216
+ setValue={[Function]}
217
+ value=""
218
+ >
219
+ <mockConstructor
220
+ fieldId="time-span"
221
+ label="Time span"
222
+ labelIcon={
223
+ <Popover
224
+ aria-label="help-text"
225
+ bodyContent="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."
226
+ id="time-span-help"
227
+ >
228
+ <button
229
+ aria-label="open-help-tooltip-button"
230
+ className="pf-c-form__group-label-help"
231
+ onClick={[Function]}
232
+ >
233
+ <HelpIcon
234
+ color="currentColor"
235
+ noVerticalAlign={true}
236
+ size="sm"
237
+ />
238
+ </button>
239
+ </Popover>
240
+ }
241
+ >
242
+ <div />
243
+ </mockConstructor>
244
+ </TimeSpanLevelField>
245
+ </form>
246
+ </Form>
247
+ </AdvancedFields>
248
+ </Provider>
249
+ `;