foreman_remote_execution 3.3.7 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/app/controllers/job_invocations_controller.rb +22 -8
  4. data/app/lib/actions/remote_execution/run_host_job.rb +1 -1
  5. data/app/lib/actions/remote_execution/run_hosts_job.rb +1 -1
  6. data/app/lib/foreman_remote_execution/renderer/scope/input.rb +35 -0
  7. data/app/models/job_invocation.rb +6 -3
  8. data/app/models/job_invocation_composer.rb +2 -2
  9. data/app/models/remote_execution_provider.rb +2 -2
  10. data/app/models/setting/remote_execution.rb +2 -2
  11. data/app/models/ssh_execution_provider.rb +1 -1
  12. data/app/views/job_invocations/_form.html.erb +1 -1
  13. data/app/views/job_invocations/_tab_hosts.html.erb +1 -20
  14. data/app/views/job_invocations/show.html.erb +3 -0
  15. data/app/views/job_invocations/show.json.erb +2 -1
  16. data/db/migrate/20200623073022_rename_sudo_password_to_effective_user_password.rb +34 -0
  17. data/db/seeds.d/20-permissions.rb +9 -0
  18. data/lib/foreman_remote_execution/engine.rb +4 -10
  19. data/lib/foreman_remote_execution/version.rb +1 -1
  20. data/test/functional/api/v2/job_invocations_controller_test.rb +64 -1
  21. data/test/functional/job_invocations_controller_test.rb +71 -0
  22. data/test/support/remote_execution_helper.rb +5 -0
  23. data/test/unit/actions/run_host_job_test.rb +3 -3
  24. data/test/unit/actions/run_hosts_job_test.rb +1 -1
  25. data/test/unit/job_invocation_composer_test.rb +5 -5
  26. data/test/unit/remote_execution_provider_test.rb +6 -6
  27. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
  28. data/webpack/__mocks__/foremanReact/components/SearchBar.js +2 -0
  29. data/webpack/__mocks__/foremanReact/constants.js +21 -0
  30. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +2 -0
  31. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors.js +1 -0
  32. data/webpack/react_app/components/TargetingHosts/TargetingHosts.js +21 -15
  33. data/webpack/react_app/components/TargetingHosts/TargetingHostsHelpers.js +10 -0
  34. data/webpack/react_app/components/TargetingHosts/TargetingHostsPage.js +62 -0
  35. data/webpack/react_app/components/TargetingHosts/TargetingHostsPage.scss +6 -0
  36. data/webpack/react_app/components/TargetingHosts/TargetingHostsSelectors.js +10 -2
  37. data/webpack/react_app/components/TargetingHosts/__tests__/TargetingHostsPage.test.js +9 -0
  38. data/webpack/react_app/components/TargetingHosts/__tests__/TargetingHostsSelectors.test.js +26 -0
  39. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHosts.test.js.snap +17 -2
  40. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap +68 -0
  41. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsSelectors.test.js.snap +11 -0
  42. data/webpack/react_app/components/TargetingHosts/__tests__/fixtures.js +35 -19
  43. data/webpack/react_app/components/TargetingHosts/index.js +73 -13
  44. metadata +17 -3
  45. data/webpack/react_app/components/TargetingHosts/TargetingHostsActions.js +0 -8
@@ -0,0 +1,68 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TargetingHostsPage renders 1`] = `
4
+ <div
5
+ id="targeting_hosts"
6
+ >
7
+ <Row
8
+ bsClass="row"
9
+ componentClass="div"
10
+ >
11
+ <Col
12
+ bsClass="col"
13
+ className="title_filter"
14
+ componentClass="div"
15
+ md={6}
16
+ >
17
+ <SearchBar
18
+ data={
19
+ Object {
20
+ "autocomplete": Object {
21
+ "id": "targeting_hosts_search",
22
+ "searchQuery": "",
23
+ "url": "/hosts/auto_complete_search",
24
+ "useKeyShortcuts": true,
25
+ },
26
+ "bookmarks": Object {},
27
+ "controller": "hosts",
28
+ }
29
+ }
30
+ onSearch={[Function]}
31
+ />
32
+ </Col>
33
+ </Row>
34
+ <br />
35
+ <TargetingHosts
36
+ apiStatus="RESOLVED"
37
+ items={
38
+ Array [
39
+ Object {
40
+ "actions": Array [],
41
+ "link": "/link",
42
+ "name": "host",
43
+ "status": "success",
44
+ },
45
+ Object {
46
+ "actions": Array [],
47
+ "link": "/link2",
48
+ "name": "host2",
49
+ "status": "success",
50
+ },
51
+ ]
52
+ }
53
+ />
54
+ <PaginationWrapper
55
+ className="targeting-hosts-pagination"
56
+ dropdownButtonId="targeting-hosts-pagination-dropdown"
57
+ itemCount={1}
58
+ onChange={[Function]}
59
+ pagination={
60
+ Object {
61
+ "page": 1,
62
+ "perPage": 20,
63
+ }
64
+ }
65
+ viewType="list"
66
+ />
67
+ </div>
68
+ `;
@@ -0,0 +1,11 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TargetingHostsSelectors should return apiStatus 1`] = `"RESOLVED"`;
4
+
5
+ exports[`TargetingHostsSelectors should return autoRefresh 1`] = `"true"`;
6
+
7
+ exports[`TargetingHostsSelectors should return hosts 1`] = `Array []`;
8
+
9
+ exports[`TargetingHostsSelectors should return intervalExists 1`] = `false`;
10
+
11
+ exports[`TargetingHostsSelectors should return totalHosts 1`] = `0`;
@@ -1,3 +1,18 @@
1
+ const items = [
2
+ {
3
+ name: 'host',
4
+ link: '/link',
5
+ status: 'success',
6
+ actions: [],
7
+ },
8
+ {
9
+ name: 'host2',
10
+ link: '/link2',
11
+ status: 'success',
12
+ actions: [],
13
+ },
14
+ ];
15
+
1
16
  export const HostItemFixtures = {
2
17
  renders: {
3
18
  name: 'Host1',
@@ -15,29 +30,30 @@ export const HostStatusFixtures = {
15
30
 
16
31
  export const TargetingHostsFixtures = {
17
32
  renders: {
18
- status: '',
19
- items: [
20
- {
21
- name: 'host',
22
- link: '/link',
23
- status: 'success',
24
- actions: [],
25
- },
26
- ],
33
+ apiStatus: 'RESOLVED',
34
+ items,
27
35
  },
28
36
  'renders with error': {
29
- status: 'ERROR',
30
- items: [
31
- {
32
- name: 'host',
33
- link: '/link',
34
- status: 'success',
35
- actions: [],
36
- },
37
- ],
37
+ apiStatus: 'ERROR',
38
+ items,
38
39
  },
39
40
  'renders with loading': {
40
- status: '',
41
+ apiStatus: 'PENDING',
41
42
  items: [],
42
43
  },
43
44
  };
45
+
46
+ export const TargetingHostsPageFixtures = {
47
+ renders: {
48
+ handleSearch: () => {},
49
+ searchQuery: '',
50
+ apiStatus: 'RESOLVED',
51
+ items,
52
+ totalHosts: 1,
53
+ pagination: {
54
+ page: 1,
55
+ perPage: 20,
56
+ },
57
+ handlePagination: () => {},
58
+ },
59
+ };
@@ -1,37 +1,97 @@
1
- import React, { useEffect } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { useSelector, useDispatch } from 'react-redux';
3
- import { stopInterval } from 'foremanReact/redux/middlewares/IntervalMiddleware';
4
- import TargetingHosts from './TargetingHosts';
3
+
4
+ import { get } from 'foremanReact/redux/API';
5
+ import { useForemanSettings } from 'foremanReact/Root/Context/ForemanContext';
6
+ import {
7
+ withInterval,
8
+ stopInterval,
9
+ } from 'foremanReact/redux/middlewares/IntervalMiddleware';
5
10
 
6
11
  import {
7
12
  selectItems,
8
- selectStatus,
13
+ selectApiStatus,
9
14
  selectAutoRefresh,
15
+ selectTotalHosts,
16
+ selectIntervalExists,
10
17
  } from './TargetingHostsSelectors';
11
- import { getData } from './TargetingHostsActions';
18
+ import { getApiUrl } from './TargetingHostsHelpers';
12
19
  import { TARGETING_HOSTS } from './TargetingHostsConsts';
20
+ import TargetingHostsPage from './TargetingHostsPage';
13
21
 
14
22
  const WrappedTargetingHosts = () => {
15
23
  const dispatch = useDispatch();
24
+ const { perPage, perPageOptions } = useForemanSettings();
25
+
16
26
  const autoRefresh = useSelector(selectAutoRefresh);
17
27
  const items = useSelector(selectItems);
18
- const status = useSelector(selectStatus);
28
+ const apiStatus = useSelector(selectApiStatus);
29
+ const totalHosts = useSelector(selectTotalHosts);
30
+ const [searchQuery, setSearchQuery] = useState('');
31
+ const [pagination, setPagination] = useState({
32
+ page: 1,
33
+ perPage,
34
+ perPageOptions,
35
+ });
36
+ const [apiUrl, setApiUrl] = useState(getApiUrl(searchQuery, pagination));
37
+ const intervalExists = useSelector(selectIntervalExists);
19
38
 
20
- useEffect(() => {
21
- dispatch(getData());
39
+ const handleSearch = query => {
40
+ const defaultPagination = { page: 1, perPage: pagination.perPage };
41
+ stopApiInterval();
22
42
 
23
- return () => {
43
+ setApiUrl(getApiUrl(query, defaultPagination));
44
+ setSearchQuery(query);
45
+ setPagination(defaultPagination);
46
+ };
47
+
48
+ const handlePagination = args => {
49
+ stopApiInterval();
50
+ setPagination(args);
51
+ setApiUrl(getApiUrl(searchQuery, args));
52
+ };
53
+
54
+ const stopApiInterval = () => {
55
+ if (intervalExists) {
24
56
  dispatch(stopInterval(TARGETING_HOSTS));
25
- };
26
- }, [dispatch]);
57
+ }
58
+ };
59
+
60
+ const getData = url =>
61
+ withInterval(
62
+ get({
63
+ key: TARGETING_HOSTS,
64
+ url,
65
+ handleError: () => {
66
+ dispatch(stopInterval(TARGETING_HOSTS));
67
+ },
68
+ }),
69
+ 1000
70
+ );
27
71
 
28
72
  useEffect(() => {
73
+ dispatch(getData(apiUrl));
74
+
29
75
  if (autoRefresh === 'false') {
30
76
  dispatch(stopInterval(TARGETING_HOSTS));
31
77
  }
32
- }, [autoRefresh, dispatch]);
33
78
 
34
- return <TargetingHosts status={status} items={items} />;
79
+ return () => {
80
+ dispatch(stopInterval(TARGETING_HOSTS));
81
+ };
82
+ }, [dispatch, apiUrl, autoRefresh]);
83
+
84
+ return (
85
+ <TargetingHostsPage
86
+ handleSearch={handleSearch}
87
+ searchQuery={searchQuery}
88
+ apiStatus={apiStatus}
89
+ items={items}
90
+ totalHosts={totalHosts}
91
+ pagination={pagination}
92
+ handlePagination={handlePagination}
93
+ />
94
+ );
35
95
  };
36
96
 
37
97
  export default WrappedTargetingHosts;
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: 3.3.7
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Remote Execution team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-31 00:00:00.000000000 Z
11
+ date: 2020-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -323,7 +323,9 @@ files:
323
323
  - db/migrate/20180411160809_add_sudo_password_to_job_invocation.rb
324
324
  - db/migrate/20180913101042_add_randomized_ordering_to_targeting.rb
325
325
  - db/migrate/20190111153330_remove_remote_execution_without_proxy_setting.rb
326
+ - db/migrate/20200623073022_rename_sudo_password_to_effective_user_password.rb
326
327
  - db/seeds.d/100-assign_features_with_templates.rb
328
+ - db/seeds.d/20-permissions.rb
327
329
  - db/seeds.d/50-notification_blueprints.rb
328
330
  - db/seeds.d/60-ssh_proxy_feature.rb
329
331
  - db/seeds.d/70-job_templates.rb
@@ -377,6 +379,7 @@ files:
377
379
  - test/functional/job_templates_controller_test.rb
378
380
  - test/helpers/remote_execution_helper_test.rb
379
381
  - test/models/orchestration/ssh_test.rb
382
+ - test/support/remote_execution_helper.rb
380
383
  - test/test_plugin_helper.rb
381
384
  - test/unit/actions/run_host_job_test.rb
382
385
  - test/unit/actions/run_hosts_job_test.rb
@@ -395,19 +398,29 @@ files:
395
398
  - test/unit/targeting_test.rb
396
399
  - test/unit/template_invocation_input_value_test.rb
397
400
  - webpack/__mocks__/foremanReact/common/I18n.js
401
+ - webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js
402
+ - webpack/__mocks__/foremanReact/components/SearchBar.js
398
403
  - webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js
399
404
  - webpack/__mocks__/foremanReact/constants.js
405
+ - webpack/__mocks__/foremanReact/redux/API/APISelectors.js
406
+ - webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors.js
400
407
  - webpack/index.js
401
408
  - webpack/react_app/components/TargetingHosts/TargetingHosts.js
402
- - webpack/react_app/components/TargetingHosts/TargetingHostsActions.js
403
409
  - webpack/react_app/components/TargetingHosts/TargetingHostsConsts.js
410
+ - webpack/react_app/components/TargetingHosts/TargetingHostsHelpers.js
411
+ - webpack/react_app/components/TargetingHosts/TargetingHostsPage.js
412
+ - webpack/react_app/components/TargetingHosts/TargetingHostsPage.scss
404
413
  - webpack/react_app/components/TargetingHosts/TargetingHostsSelectors.js
405
414
  - webpack/react_app/components/TargetingHosts/__tests__/HostItem.test.js
406
415
  - webpack/react_app/components/TargetingHosts/__tests__/HostStatus.test.js
407
416
  - webpack/react_app/components/TargetingHosts/__tests__/TargetingHosts.test.js
417
+ - webpack/react_app/components/TargetingHosts/__tests__/TargetingHostsPage.test.js
418
+ - webpack/react_app/components/TargetingHosts/__tests__/TargetingHostsSelectors.test.js
408
419
  - webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostItem.test.js.snap
409
420
  - webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostStatus.test.js.snap
410
421
  - webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHosts.test.js.snap
422
+ - webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap
423
+ - webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsSelectors.test.js.snap
411
424
  - webpack/react_app/components/TargetingHosts/__tests__/fixtures.js
412
425
  - webpack/react_app/components/TargetingHosts/components/HostItem.js
413
426
  - webpack/react_app/components/TargetingHosts/components/HostStatus.js
@@ -460,6 +473,7 @@ test_files:
460
473
  - test/functional/job_templates_controller_test.rb
461
474
  - test/helpers/remote_execution_helper_test.rb
462
475
  - test/models/orchestration/ssh_test.rb
476
+ - test/support/remote_execution_helper.rb
463
477
  - test/test_plugin_helper.rb
464
478
  - test/unit/actions/run_host_job_test.rb
465
479
  - test/unit/actions/run_hosts_job_test.rb
@@ -1,8 +0,0 @@
1
- import { getURI } from 'foremanReact/common/urlHelpers';
2
- import { get } from 'foremanReact/redux/API';
3
- import { withInterval } from 'foremanReact/redux/middlewares/IntervalMiddleware';
4
- import { TARGETING_HOSTS } from './TargetingHostsConsts';
5
-
6
- const url = getURI().addQuery('format', 'json');
7
- export const getData = () =>
8
- withInterval(get({ key: TARGETING_HOSTS, url }), 1000);