foreman_ansible 7.0.4 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/ansible_playbooks_controller.rb +66 -0
  3. data/app/jobs/sync_playbooks.rb +25 -0
  4. data/app/lib/proxy_api/ansible.rb +13 -0
  5. data/app/services/foreman_ansible/import_playbooks_error_notification.rb +38 -0
  6. data/app/services/foreman_ansible/import_playbooks_success_notification.rb +33 -0
  7. data/app/services/foreman_ansible/playbooks_importer.rb +73 -0
  8. data/app/services/foreman_ansible/proxy_api.rb +3 -4
  9. data/app/views/ansible_roles/index.html.erb +2 -0
  10. data/app/views/api/v2/ansible_playbooks/sync.json.rabl +5 -0
  11. data/app/views/foreman_ansible/job_templates/ansible_windows_updates.erb +160 -0
  12. data/app/views/foreman_ansible/job_templates/configure_cloud_connector_-_ansible_default.erb +37 -0
  13. data/config/routes.rb +7 -0
  14. data/db/seeds.d/90_notification_blueprints.rb +14 -0
  15. data/lib/foreman_ansible/register.rb +3 -1
  16. data/lib/foreman_ansible/remote_execution.rb +6 -0
  17. data/lib/foreman_ansible/version.rb +1 -1
  18. data/test/fixtures/playbooks_example_output.json +1 -0
  19. data/test/fixtures/sample_playbooks.json +10 -0
  20. data/test/functional/api/v2/ansible_playbooks_controller_test.rb +65 -0
  21. data/test/functional/hosts_controller_test.rb +2 -2
  22. data/test/unit/import_playbooks_test.rb +51 -0
  23. data/test/unit/lib/proxy_api/ansible_test.rb +6 -0
  24. data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTable.js +58 -75
  25. data/webpack/components/AnsibleHostDetail/components/JobsTab/PreviousJobsTable.js +44 -58
  26. data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/AllRolesTable.js +32 -55
  27. data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/index.js +1 -1
  28. data/webpack/components/AnsibleHostDetail/components/RolesTab/RolesTable.js +29 -42
  29. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.js +27 -38
  30. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesActions.js +2 -1
  31. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesConstants.js +1 -0
  32. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesSelectors.js +6 -0
  33. data/webpack/components/AnsibleRolesAndVariables/index.js +7 -1
  34. data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.js +2 -2
  35. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +9 -6
  36. data/webpack/helpers/pageParamsHelper.js +3 -3
  37. metadata +46 -31
  38. data/webpack/components/withPagination.js +0 -0
  39. data/webpack/helpers/paginationHelper.js +0 -9
@@ -20,7 +20,7 @@ class HostsControllerExtensionsTest < ActionController::TestCase
20
20
  0 => { :ansible_role_id => @role.id, :position => 0 }
21
21
  } }
22
22
  post :create, :params => { :host => host }, :session => set_session_user
23
- assert_redirected_to host_url(assigns('host'))
23
+ assert_redirected_to host_details_page_url(assigns('host'))
24
24
  assert assigns('host').ansible_roles, [@role]
25
25
  end
26
26
 
@@ -34,7 +34,7 @@ class HostsControllerExtensionsTest < ActionController::TestCase
34
34
  } }
35
35
  },
36
36
  :session => set_session_user
37
- assert_redirected_to host_url(assigns('host'))
37
+ assert_redirected_to host_details_page_url(assigns('host'))
38
38
  assert_equal assigns('host').ansible_roles, [@role]
39
39
  end
40
40
 
@@ -0,0 +1,51 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class ImportPlaybooksTest < ActiveSupport::TestCase
4
+ let(:ansible_proxy) { FactoryBot.create(:smart_proxy, :with_ansible) }
5
+ let(:proxy_api) { ::ProxyAPI::Ansible.new(url: ansible_proxy.url) }
6
+ subject { ::ForemanAnsible::PlaybooksImporter.new(ansible_proxy) }
7
+ let(:sample_playbooks) { JSON.parse(File.read(ansible_fixture_file('sample_playbooks.json'))) }
8
+ let(:playbook1_output) { sample_playbooks.first }
9
+ let(:playbook2_output) { sample_playbooks.last }
10
+ let(:first_playbook) { ['xprazak2.forklift_collection.foreman_provisioning.yml'] }
11
+ let(:second_playbook) { ['xprazak2.forklift_collection.collect_debug_draft.yml'] }
12
+ let(:playbook1_template) { JSON.parse(File.read(ansible_fixture_file('playbooks_example_output.json')))['template'] }
13
+
14
+ setup do
15
+ subject.stubs(:proxy_api).returns(proxy_api)
16
+ end
17
+
18
+ describe 'check the job templates that were created due to the import' do
19
+ test 'should just create job templates from playbooks' do
20
+ subject.expects(:playbooks).with(second_playbook).returns([playbook2_output])
21
+ actual = subject.import_playbooks(second_playbook)
22
+ assert_not_nil actual_created = actual[:created]
23
+ assert_equal 1, actual_created.count
24
+ job_template = JobTemplate.where(id: actual_created.keys.first).first
25
+ assert_equal job_template.name, actual_created.values.first
26
+ end
27
+ end
28
+
29
+ describe 'check the updated job templated due to import playbooks' do
30
+ test ' should not update an identical job template' do
31
+ FactoryBot.create(:job_template, id: 111, name: playbook1_output['name'],
32
+ template: playbook1_template)
33
+ subject.expects(:playbooks).with(first_playbook).returns([playbook1_output])
34
+ actual = subject.import_playbooks(first_playbook)
35
+ assert_not_nil actual_updated = actual[:updated]
36
+ assert_not_nil actual_created = actual[:created]
37
+ assert_equal 0, actual_updated.count
38
+ assert_equal 0, actual_created.count
39
+ end
40
+
41
+ test ' should just update a job template from playbooks' do
42
+ job_template = FactoryBot.create(:job_template, id: 112, name: playbook2_output['name'], template: 'check')
43
+ subject.expects(:playbooks).with(second_playbook).returns([playbook2_output])
44
+ actual = subject.import_playbooks(second_playbook)
45
+ assert_not_nil actual_updated = actual[:updated]
46
+ assert_equal 1, actual_updated.count
47
+ assert_equal actual_updated.keys.first, job_template.id
48
+ assert_not_nil job_template.template
49
+ end
50
+ end
51
+ end
@@ -14,6 +14,12 @@ class AnsibleTest < ActiveSupport::TestCase
14
14
  assert_equal roles, @proxy_api.roles
15
15
  end
16
16
 
17
+ test 'should get ansible playbooks from proxy' do
18
+ playbooks = ['some_playbook.some_author', 'test_playbook.test_author']
19
+ @proxy_api.expects(:get).returns(fake_rest_client_response(playbooks))
20
+ assert_equal playbooks, @proxy_api.playbooks
21
+ end
22
+
17
23
  test 'should raise error with appropriate message' do
18
24
  message = 'Connection refused'
19
25
  @proxy_api.expects(:get).raises(Errno::ECONNREFUSED, message)
@@ -4,7 +4,6 @@ import { useDispatch } from 'react-redux';
4
4
  import { useMutation } from '@apollo/client';
5
5
 
6
6
  import { sprintf, translate as __ } from 'foremanReact/common/I18n';
7
- import { usePaginationOptions } from 'foremanReact/components/Pagination/PaginationHooks';
8
7
  import { openConfirmModal } from 'foremanReact/components/ConfirmModal';
9
8
  import {
10
9
  TableComposable,
@@ -14,8 +13,9 @@ import {
14
13
  Th,
15
14
  Td,
16
15
  } from '@patternfly/react-table';
17
- import { Flex, FlexItem, Pagination } from '@patternfly/react-core';
16
+ import { Flex, FlexItem } from '@patternfly/react-core';
18
17
 
18
+ import Pagination from 'foremanReact/components/Pagination';
19
19
  import deleteAnsibleVariableOverride from '../../../../graphql/mutations/deleteAnsibleVariableOverride.gql';
20
20
  import EditableAction from './EditableAction';
21
21
  import EditableValue from './EditableValue';
@@ -29,10 +29,6 @@ import {
29
29
  } from './AnsibleVariableOverridesTableHelper';
30
30
 
31
31
  import withLoading from '../../../withLoading';
32
- import {
33
- preparePerPageOptions,
34
- refreshPage,
35
- } from '../../../../helpers/paginationHelper';
36
32
 
37
33
  const reducer = (state, action) =>
38
34
  state.map((item, index) => {
@@ -58,8 +54,6 @@ const AnsibleVariableOverridesTable = ({
58
54
  hostId,
59
55
  hostGlobalId,
60
56
  totalCount,
61
- pagination,
62
- history,
63
57
  }) => {
64
58
  const columns = [
65
59
  __('Name'),
@@ -69,16 +63,6 @@ const AnsibleVariableOverridesTable = ({
69
63
  __('Source attribute'),
70
64
  ];
71
65
 
72
- const handlePerPageSelected = (event, perPage) => {
73
- refreshPage(history, { page: 1, perPage });
74
- };
75
-
76
- const handlePageSelected = (event, page) => {
77
- refreshPage(history, { ...pagination, page });
78
- };
79
-
80
- const perPageOptions = preparePerPageOptions(usePaginationOptions());
81
-
82
66
  const [editableState, innerDispatch] = useReducer(
83
67
  reducer,
84
68
  variables,
@@ -162,67 +146,68 @@ const AnsibleVariableOverridesTable = ({
162
146
 
163
147
  return (
164
148
  <React.Fragment>
165
- <Flex>
149
+ <Flex direction={{ default: 'column' }}>
150
+ <FlexItem align={{ default: 'alignRight' }}>
151
+ <Pagination updateParamsByUrl itemCount={totalCount} variant="top" />
152
+ </FlexItem>
153
+ <FlexItem>
154
+ <TableComposable variant="compact">
155
+ <Thead>
156
+ <Tr>
157
+ {columns.map(col => (
158
+ <Th key={col}>{col}</Th>
159
+ ))}
160
+ <Th />
161
+ </Tr>
162
+ </Thead>
163
+ <Tbody>
164
+ {variables.map((variable, idx) => (
165
+ <Tr key={idx}>
166
+ <Td>
167
+ <a href={variable.path}>{variable.key}</a>
168
+ </Td>
169
+ <Td>{variable.ansibleRoleName}</Td>
170
+ <Td>{variable.parameterType}</Td>
171
+ <Td>
172
+ <EditableValue
173
+ variable={variable}
174
+ editing={editableState[idx].open}
175
+ onChange={onValueChange(idx, variable)}
176
+ value={editableState[idx].value}
177
+ validation={editableState[idx].validation}
178
+ working={editableState[idx].working}
179
+ />
180
+ </Td>
181
+ <Td>{formatSourceAttr(variable)}</Td>
182
+ <Td>
183
+ <EditableAction
184
+ open={editableState[idx].open}
185
+ onClose={setEditable(idx, false)}
186
+ onOpen={setEditable(idx, true)}
187
+ toggleWorking={toggleWorking(idx)}
188
+ variable={variable}
189
+ state={editableState[idx]}
190
+ hostId={hostId}
191
+ hostName={hostAttrs.name}
192
+ hostGlobalId={hostGlobalId}
193
+ onSubmitSuccess={onSubmitSuccess(idx, variable)}
194
+ onValidationError={onValidationError(idx)}
195
+ />
196
+ </Td>
197
+ <Td actions={{ items: actionsResolver(variable, idx) }} />
198
+ </Tr>
199
+ ))}
200
+ </Tbody>
201
+ </TableComposable>
202
+ </FlexItem>
166
203
  <FlexItem align={{ default: 'alignRight' }}>
167
204
  <Pagination
205
+ updateParamsByUrl
168
206
  itemCount={totalCount}
169
- page={pagination.page}
170
- perPage={pagination.perPage}
171
- onSetPage={handlePageSelected}
172
- onPerPageSelect={handlePerPageSelected}
173
- perPageOptions={perPageOptions}
174
- variant="top"
207
+ variant="bottom"
175
208
  />
176
209
  </FlexItem>
177
210
  </Flex>
178
- <TableComposable variant="compact">
179
- <Thead>
180
- <Tr>
181
- {columns.map(col => (
182
- <Th key={col}>{col}</Th>
183
- ))}
184
- <Th />
185
- </Tr>
186
- </Thead>
187
- <Tbody>
188
- {variables.map((variable, idx) => (
189
- <Tr key={idx}>
190
- <Td>
191
- <a href={variable.path}>{variable.key}</a>
192
- </Td>
193
- <Td>{variable.ansibleRoleName}</Td>
194
- <Td>{variable.parameterType}</Td>
195
- <Td>
196
- <EditableValue
197
- variable={variable}
198
- editing={editableState[idx].open}
199
- onChange={onValueChange(idx, variable)}
200
- value={editableState[idx].value}
201
- validation={editableState[idx].validation}
202
- working={editableState[idx].working}
203
- />
204
- </Td>
205
- <Td>{formatSourceAttr(variable)}</Td>
206
- <Td>
207
- <EditableAction
208
- open={editableState[idx].open}
209
- onClose={setEditable(idx, false)}
210
- onOpen={setEditable(idx, true)}
211
- toggleWorking={toggleWorking(idx)}
212
- variable={variable}
213
- state={editableState[idx]}
214
- hostId={hostId}
215
- hostName={hostAttrs.name}
216
- hostGlobalId={hostGlobalId}
217
- onSubmitSuccess={onSubmitSuccess(idx, variable)}
218
- onValidationError={onValidationError(idx)}
219
- />
220
- </Td>
221
- <Td actions={{ items: actionsResolver(variable, idx) }} />
222
- </Tr>
223
- ))}
224
- </Tbody>
225
- </TableComposable>
226
211
  </React.Fragment>
227
212
  );
228
213
  };
@@ -233,8 +218,6 @@ AnsibleVariableOverridesTable.propTypes = {
233
218
  hostId: PropTypes.number.isRequired,
234
219
  hostGlobalId: PropTypes.string.isRequired,
235
220
  totalCount: PropTypes.number.isRequired,
236
- pagination: PropTypes.object.isRequired,
237
- history: PropTypes.object.isRequired,
238
221
  };
239
222
 
240
223
  export default withLoading(AnsibleVariableOverridesTable);
@@ -1,8 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { translate as __ } from 'foremanReact/common/I18n';
4
- import { usePaginationOptions } from 'foremanReact/components/Pagination/PaginationHooks';
5
-
6
4
  import RelativeDateTime from 'foremanReact/components/common/dates/RelativeDateTime';
7
5
 
8
6
  import {
@@ -13,15 +11,12 @@ import {
13
11
  Th,
14
12
  Td,
15
13
  } from '@patternfly/react-table';
16
- import { Flex, FlexItem, Pagination } from '@patternfly/react-core';
14
+ import { Flex, FlexItem } from '@patternfly/react-core';
15
+ import Pagination from 'foremanReact/components/Pagination';
17
16
 
18
17
  import { decodeId } from '../../../../globalIdHelper';
19
18
  import withLoading from '../../../withLoading';
20
19
  import { readableCron, readablePurpose } from './JobsTabHelper';
21
- import {
22
- preparePerPageOptions,
23
- refreshPage,
24
- } from '../../../../helpers/paginationHelper';
25
20
 
26
21
  const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
27
22
  const columns = [
@@ -32,66 +27,57 @@ const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
32
27
  __('Schedule'),
33
28
  ];
34
29
 
35
- const handlePerPageSelected = (event, perPage) => {
36
- refreshPage(history, { page: 1, perPage });
37
- };
38
-
39
- const handlePageSelected = (event, page) => {
40
- refreshPage(history, { ...pagination, page });
41
- };
42
-
43
- const perPageOptions = preparePerPageOptions(usePaginationOptions());
44
-
45
30
  return (
46
31
  <React.Fragment>
47
32
  <h3>{__('Previously executed jobs')}</h3>
48
- <Flex className="pf-u-pt-md">
33
+ <Flex direction={{ default: 'column' }} className="pf-u-pt-md">
34
+ <FlexItem align={{ default: 'alignRight' }}>
35
+ <Pagination updateParamsByUrl itemCount={totalCount} variant="top" />
36
+ </FlexItem>
37
+ <FlexItem>
38
+ <TableComposable variant="compact">
39
+ <Thead>
40
+ <Tr>
41
+ {columns.map(col => (
42
+ <Th key={col}>{col}</Th>
43
+ ))}
44
+ </Tr>
45
+ </Thead>
46
+ <Tbody>
47
+ {jobs.map(job => (
48
+ <Tr key={job.id}>
49
+ <Td>
50
+ <a
51
+ onClick={() =>
52
+ window.tfm.nav.pushUrl(
53
+ `/job_invocations/${decodeId(job.id)}`
54
+ )
55
+ }
56
+ >
57
+ {job.description}
58
+ </a>
59
+ &nbsp;
60
+ {readablePurpose(job.recurringLogic.purpose)}
61
+ </Td>
62
+ <Td>{job.task.result}</Td>
63
+ <Td>{job.task.state}</Td>
64
+ <Td>
65
+ <RelativeDateTime date={job.startAt} />
66
+ </Td>
67
+ <Td>{readableCron(job.recurringLogic.cronLine)}</Td>
68
+ </Tr>
69
+ ))}
70
+ </Tbody>
71
+ </TableComposable>
72
+ </FlexItem>
49
73
  <FlexItem align={{ default: 'alignRight' }}>
50
74
  <Pagination
75
+ updateParamsByUrl
51
76
  itemCount={totalCount}
52
- page={pagination.page}
53
- perPage={pagination.perPage}
54
- onSetPage={handlePageSelected}
55
- onPerPageSelect={handlePerPageSelected}
56
- perPageOptions={perPageOptions}
57
- variant="top"
77
+ variant="bottom"
58
78
  />
59
79
  </FlexItem>
60
80
  </Flex>
61
- <TableComposable variant="compact">
62
- <Thead>
63
- <Tr>
64
- {columns.map(col => (
65
- <Th key={col}>{col}</Th>
66
- ))}
67
- </Tr>
68
- </Thead>
69
- <Tbody>
70
- {jobs.map(job => (
71
- <Tr key={job.id}>
72
- <Td>
73
- <a
74
- onClick={() =>
75
- window.tfm.nav.pushUrl(
76
- `/job_invocations/${decodeId(job.id)}`
77
- )
78
- }
79
- >
80
- {job.description}
81
- </a>
82
- &nbsp;
83
- {readablePurpose(job.recurringLogic.purpose)}
84
- </Td>
85
- <Td>{job.task.result}</Td>
86
- <Td>{job.task.state}</Td>
87
- <Td>
88
- <RelativeDateTime date={job.startAt} />
89
- </Td>
90
- <Td>{readableCron(job.recurringLogic.cronLine)}</Td>
91
- </Tr>
92
- ))}
93
- </Tbody>
94
- </TableComposable>
95
81
  </React.Fragment>
96
82
  );
97
83
  };
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { translate as __ } from 'foremanReact/common/I18n';
4
- import { usePaginationOptions } from 'foremanReact/components/Pagination/PaginationHooks';
5
4
 
6
5
  import {
7
6
  TableComposable,
@@ -11,70 +10,50 @@ import {
11
10
  Th,
12
11
  Td,
13
12
  } from '@patternfly/react-table';
14
-
15
- import { Flex, FlexItem, Pagination } from '@patternfly/react-core';
13
+ import { Flex, FlexItem } from '@patternfly/react-core';
14
+ import Pagination from 'foremanReact/components/Pagination';
16
15
  import withLoading from '../../../../withLoading';
17
- import {
18
- preparePerPageOptions,
19
- refreshPage,
20
- } from '../../../../../helpers/paginationHelper';
21
16
 
22
- const AllRolesTable = ({
23
- allAnsibleRoles,
24
- totalCount,
25
- pagination,
26
- history,
27
- }) => {
17
+ const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
28
18
  const columns = [__('Name'), __('Source')];
29
19
 
30
- const handlePerPageSelected = (event, allPerPage) => {
31
- refreshPage(history, { allPage: 1, allPerPage });
32
- };
33
-
34
- const handlePageSelected = (event, allPage) => {
35
- refreshPage(history, { ...pagination, allPage });
36
- };
37
-
38
- const perPageOptions = preparePerPageOptions(usePaginationOptions());
39
-
40
20
  return (
41
21
  <React.Fragment>
42
- <Flex className="pf-u-pt-md">
22
+ <Flex direction={{ default: 'column' }} className="pf-u-pt-md">
23
+ <FlexItem align={{ default: 'alignRight' }}>
24
+ <Pagination updateParamsByUrl itemCount={totalCount} variant="top" />
25
+ </FlexItem>
26
+ <TableComposable variant="compact">
27
+ <Thead>
28
+ <Tr>
29
+ <Th />
30
+ {columns.map(col => (
31
+ <Th key={`${col}-all`}>{col}</Th>
32
+ ))}
33
+ </Tr>
34
+ </Thead>
35
+ <Tbody>
36
+ {allAnsibleRoles.map(role => (
37
+ <Tr key={`${role.id}-all`} id={role.id}>
38
+ <Td />
39
+ <Td>{role.name}</Td>
40
+ <Td>
41
+ {role.inherited
42
+ ? __('Inherited from Hostgroup')
43
+ : __('Directly assigned to Host')}
44
+ </Td>
45
+ </Tr>
46
+ ))}
47
+ </Tbody>
48
+ </TableComposable>
43
49
  <FlexItem align={{ default: 'alignRight' }}>
44
50
  <Pagination
51
+ updateParamsByUrl
45
52
  itemCount={totalCount}
46
- page={pagination.allPage}
47
- perPage={pagination.allPerPage}
48
- onSetPage={handlePageSelected}
49
- onPerPageSelect={handlePerPageSelected}
50
- perPageOptions={perPageOptions}
51
- variant="top"
53
+ variant="bottom"
52
54
  />
53
55
  </FlexItem>
54
56
  </Flex>
55
- <TableComposable variant="compact">
56
- <Thead>
57
- <Tr>
58
- <Th />
59
- {columns.map(col => (
60
- <Th key={`${col}-all`}>{col}</Th>
61
- ))}
62
- </Tr>
63
- </Thead>
64
- <Tbody>
65
- {allAnsibleRoles.map(role => (
66
- <Tr key={`${role.id}-all`} id={role.id}>
67
- <Td />
68
- <Td>{role.name}</Td>
69
- <Td>
70
- {role.inherited
71
- ? __('Inherited from Hostgroup')
72
- : __('Directly assigned to Host')}
73
- </Td>
74
- </Tr>
75
- ))}
76
- </Tbody>
77
- </TableComposable>
78
57
  </React.Fragment>
79
58
  );
80
59
  };
@@ -82,8 +61,6 @@ const AllRolesTable = ({
82
61
  AllRolesTable.propTypes = {
83
62
  allAnsibleRoles: PropTypes.array.isRequired,
84
63
  totalCount: PropTypes.number.isRequired,
85
- pagination: PropTypes.object.isRequired,
86
- history: PropTypes.object.isRequired,
87
64
  };
88
65
 
89
66
  export default withLoading(AllRolesTable);
@@ -27,7 +27,7 @@ const AllRolesModal = ({ hostGlobalId, onClose, history }) => {
27
27
  ),
28
28
  };
29
29
 
30
- const paginationKeys = { page: 'allPage', perPage: 'allPerPage' };
30
+ const paginationKeys = { page: 'page', perPage: 'per_page' };
31
31
 
32
32
  const wrapper = child => <Modal {...baseModalProps}>{child}</Modal>;
33
33
 
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { translate as __ } from 'foremanReact/common/I18n';
4
4
  import { Route, Link } from 'react-router-dom';
5
- import { usePaginationOptions } from 'foremanReact/components/Pagination/PaginationHooks';
5
+ import Pagination from 'foremanReact/components/Pagination';
6
6
 
7
7
  import {
8
8
  TableComposable,
@@ -12,20 +12,15 @@ import {
12
12
  Th,
13
13
  Td,
14
14
  } from '@patternfly/react-table';
15
- import { Flex, FlexItem, Button, Pagination } from '@patternfly/react-core';
15
+ import { Flex, FlexItem, Button } from '@patternfly/react-core';
16
16
 
17
17
  import EditRolesModal from './EditRolesModal';
18
18
 
19
19
  import withLoading from '../../../withLoading';
20
20
  import AllRolesModal from './AllRolesModal';
21
- import {
22
- preparePerPageOptions,
23
- refreshPage,
24
- } from '../../../../helpers/paginationHelper';
25
21
 
26
22
  const RolesTable = ({
27
23
  totalCount,
28
- pagination,
29
24
  history,
30
25
  ansibleRoles,
31
26
  hostId,
@@ -34,16 +29,6 @@ const RolesTable = ({
34
29
  }) => {
35
30
  const columns = [__('Name')];
36
31
 
37
- const handlePerPageSelected = (event, perPage) => {
38
- refreshPage(history, { page: 1, perPage });
39
- };
40
-
41
- const handlePageSelected = (event, page) => {
42
- refreshPage(history, { ...pagination, page });
43
- };
44
-
45
- const perPageOptions = preparePerPageOptions(usePaginationOptions());
46
-
47
32
  const editBtn = canEditHost ? (
48
33
  <FlexItem>
49
34
  <Link to="/Ansible/roles/edit">
@@ -67,36 +52,39 @@ const RolesTable = ({
67
52
  </Flex>
68
53
  <Flex>
69
54
  <FlexItem>{editBtn}</FlexItem>
55
+ <FlexItem align={{ default: 'alignRight' }}>
56
+ <Pagination updateParamsByUrl itemCount={totalCount} variant="top" />
57
+ </FlexItem>
58
+ </Flex>
59
+ <Flex direction={{ default: 'column' }}>
60
+ <FlexItem>
61
+ <TableComposable variant="compact">
62
+ <Thead>
63
+ <Tr>
64
+ {columns.map(col => (
65
+ <Th key={col}>{col}</Th>
66
+ ))}
67
+ </Tr>
68
+ </Thead>
69
+ <Tbody>
70
+ {ansibleRoles.map(role => (
71
+ <Tr key={role.id}>
72
+ <Td>
73
+ <a href={role.path}>{role.name}</a>
74
+ </Td>
75
+ </Tr>
76
+ ))}
77
+ </Tbody>
78
+ </TableComposable>
79
+ </FlexItem>
70
80
  <FlexItem align={{ default: 'alignRight' }}>
71
81
  <Pagination
82
+ updateParamsByUrl
72
83
  itemCount={totalCount}
73
- page={pagination.page}
74
- perPage={pagination.perPage}
75
- onSetPage={handlePageSelected}
76
- onPerPageSelect={handlePerPageSelected}
77
- perPageOptions={perPageOptions}
78
- variant="top"
84
+ variant="bottom"
79
85
  />
80
86
  </FlexItem>
81
87
  </Flex>
82
- <TableComposable variant="compact">
83
- <Thead>
84
- <Tr>
85
- {columns.map(col => (
86
- <Th key={col}>{col}</Th>
87
- ))}
88
- </Tr>
89
- </Thead>
90
- <Tbody>
91
- {ansibleRoles.map(role => (
92
- <Tr key={role.id}>
93
- <Td>
94
- <a href={role.path}>{role.name}</a>
95
- </Td>
96
- </Tr>
97
- ))}
98
- </Tbody>
99
- </TableComposable>
100
88
  <Route path="/Ansible/roles/edit">
101
89
  <EditRolesModal
102
90
  closeModal={() => history.goBack()}
@@ -123,7 +111,6 @@ RolesTable.propTypes = {
123
111
  hostId: PropTypes.number.isRequired,
124
112
  hostGlobalId: PropTypes.string.isRequired,
125
113
  history: PropTypes.object.isRequired,
126
- pagination: PropTypes.object.isRequired,
127
114
  totalCount: PropTypes.number.isRequired,
128
115
  canEditHost: PropTypes.bool.isRequired,
129
116
  };