foreman_ansible 7.0.1 → 7.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/app/graphql/resolvers/ansible_role/path.rb +11 -0
  3. data/app/graphql/resolvers/ansible_variable/path.rb +11 -0
  4. data/app/graphql/types/ansible_role.rb +1 -0
  5. data/app/graphql/types/ansible_variable.rb +1 -0
  6. data/app/models/foreman_ansible/ansible_provider.rb +1 -1
  7. data/app/services/foreman_ansible/ansible_report_importer.rb +0 -4
  8. data/lib/foreman_ansible/engine.rb +1 -0
  9. data/lib/foreman_ansible/version.rb +1 -1
  10. data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.js +1 -0
  11. data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.scss +4 -0
  12. data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTable.js +5 -3
  13. data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverrides.fixtures.js +9 -0
  14. data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverridesDelete.test.js +2 -2
  15. data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/index.js +4 -1
  16. data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/index.js +8 -14
  17. data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/index.js +5 -2
  18. data/webpack/components/AnsibleHostDetail/components/RolesTab/RolesTable.js +4 -2
  19. data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/EditRoles.test.js +2 -2
  20. data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.fixtures.js +11 -0
  21. data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.test.js +7 -3
  22. data/webpack/components/AnsibleHostDetail/components/RolesTab/index.js +38 -14
  23. data/webpack/components/DualList/index.js +2 -2
  24. data/webpack/graphql/queries/hostAnsibleRoles.gql +1 -0
  25. data/webpack/graphql/queries/hostVariableOverrides.gql +1 -0
  26. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f339d8ddcc4cb0ae8402d9df48653f437cdfa509784a8fa5774a9ff8b9d6645
4
- data.tar.gz: ed2f5f5a56da334a955280c523cccf5488df9c37c61e267047b0653e5521031f
3
+ metadata.gz: 299049c29764a0920259664c06288f37ea56d4b920e049243baeab9ad7f2e608
4
+ data.tar.gz: 779264101df1f9fa6e0188c8673a435b98eb4dbd9fd814e754f991247b5bb250
5
5
  SHA512:
6
- metadata.gz: 19ac46f57b3606646821aafa291523a0b5973f4cb2012011b30a84ff4696ea57a0cdf81fb84d0db435d6e1c1c43ec77f1b9e5b17b40318a626ccf5f7c30e6add
7
- data.tar.gz: 43c1ebc458690ac43ba94ceb7cac037d41517e9d2236ea7e7e64d220a51dc166c44448492eca45174bb16371170e2d2b5093c40eb5200431cb381c7f9f8882af
6
+ metadata.gz: '08a1b935eb0c033ff08674e4922ee597d39ed602ef351b82d9ac763af9d850e5a32ff9ea482af7f74a641552ebaf62094b6fa59170cba317b5bba67949d31a8d'
7
+ data.tar.gz: 3f814381b2167e370757f761a0b5d3e1217e3c3ba4293d7f1ecf1e77599c232ef8c62beae293c8593d81ab4e305ae1cced983527bc6d29e248bbda3a3f4e731e
@@ -0,0 +1,11 @@
1
+ module Resolvers
2
+ module AnsibleRole
3
+ class Path < Resolvers::BaseResolver
4
+ type String, null: false
5
+
6
+ def resolve
7
+ Rails.application.routes.url_helpers.ansible_roles_path(search: "name = #{object.name}")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Resolvers
2
+ module AnsibleVariable
3
+ class Path < Resolvers::BaseResolver
4
+ type String, null: false
5
+
6
+ def resolve
7
+ Rails.application.routes.url_helpers.edit_ansible_variable_path(object.ansible_variable)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -5,5 +5,6 @@ module Types
5
5
  global_id_field :id
6
6
 
7
7
  field :name, String, :null => false
8
+ field :path, resolver: Resolvers::AnsibleRole::Path
8
9
  end
9
10
  end
@@ -5,6 +5,7 @@ module Types
5
5
  global_id_field :id
6
6
 
7
7
  field :key, String
8
+ field :path, resolver: Resolvers::AnsibleVariable::Path
8
9
  field :override, Boolean
9
10
  field :description, String
10
11
  field :hidden_value, Boolean
@@ -88,7 +88,7 @@ if defined? ForemanRemoteExecution
88
88
  :children => [
89
89
  {
90
90
  :name => :tags,
91
- :type => Array,
91
+ :type => String,
92
92
  :opts => { :required => false, :desc => N_('A comma separated list of tags to use for Ansible run') }
93
93
  },
94
94
  {
@@ -18,10 +18,6 @@ module ForemanAnsible
18
18
  partial_hostname_match(hostname)
19
19
  end
20
20
 
21
- def self.authorized_smart_proxy_features
22
- super + ['Ansible']
23
- end
24
-
25
21
  def partial_hostname_match(hostname)
26
22
  return @host unless @host.new_record?
27
23
  hosts = Host.where(Host.arel_table[:name].matches("#{hostname}.%"))
@@ -75,6 +75,7 @@ module ForemanAnsible
75
75
  ::Api::V2::HostgroupsController.include ForemanAnsible::Api::V2::HostgroupsControllerExtensions
76
76
  ::Api::V2::HostgroupsController.include ForemanAnsible::Api::V2::HostgroupsParamGroupExtensions
77
77
  ::ConfigReportImporter.include ForemanAnsible::AnsibleReportImporter
78
+ ReportImporter.register_smart_proxy_feature('Ansible')
78
79
  rescue StandardError => e
79
80
  Rails.logger.warn "Foreman Ansible: skipping engine hook (#{e})"
80
81
  end
@@ -4,5 +4,5 @@
4
4
  # This way other parts of Foreman can just call ForemanAnsible::VERSION
5
5
  # and detect what version the plugin is running.
6
6
  module ForemanAnsible
7
- VERSION = '7.0.1'
7
+ VERSION = '7.0.2'
8
8
  end
@@ -21,6 +21,7 @@ const AnsibleHostDetail = ({
21
21
  {response?.id && (
22
22
  <>
23
23
  <Tabs
24
+ className="ansible-host-details-tabs"
24
25
  onSelect={(evt, subTab) => hashHistory.push(subTab)}
25
26
  activeKey={pathname?.split('/')[2]}
26
27
  isSecondary
@@ -4,3 +4,7 @@
4
4
  background-color: $pf-color-white;
5
5
  padding: 1.8rem;
6
6
  }
7
+
8
+ .ansible-host-details-tabs {
9
+ margin: 0 24px;
10
+ }
@@ -63,7 +63,7 @@ const AnsibleVariableOverridesTable = ({
63
63
  }) => {
64
64
  const columns = [
65
65
  __('Name'),
66
- __('Ansible Role'),
66
+ __('Ansible role'),
67
67
  __('Type'),
68
68
  __('Value'),
69
69
  __('Source attribute'),
@@ -131,7 +131,7 @@ const AnsibleVariableOverridesTable = ({
131
131
  onClick: () => {
132
132
  dispatch(
133
133
  openConfirmModal({
134
- title: __('Delete Ansible Variable Override'),
134
+ title: __('Delete Ansible variable override'),
135
135
  message:
136
136
  variable &&
137
137
  sprintf(
@@ -187,7 +187,9 @@ const AnsibleVariableOverridesTable = ({
187
187
  <Tbody>
188
188
  {variables.map((variable, idx) => (
189
189
  <Tr key={idx}>
190
- <Td>{variable.key}</Td>
190
+ <Td>
191
+ <a href={variable.path}>{variable.key}</a>
192
+ </Td>
191
193
  <Td>{variable.ansibleRoleName}</Td>
192
194
  <Td>{variable.parameterType}</Td>
193
195
  <Td>
@@ -29,6 +29,7 @@ const withFqdnOverride = canEdit => ({
29
29
  },
30
30
  id: ansibleVariableId,
31
31
  key: 'rectangle',
32
+ path: '/ansible/ansible_variables/1/edit',
32
33
  defaultValue: 17,
33
34
  parameterType: 'integer',
34
35
  ansibleRoleName: 'test.role',
@@ -62,6 +63,7 @@ const withDomainOverride = canEdit => ({
62
63
  },
63
64
  id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTc4',
64
65
  key: 'circle',
66
+ path: '/ansible/ansible_variables/2/edit',
65
67
  defaultValue: 'd',
66
68
  parameterType: 'string',
67
69
  ansibleRoleName: 'test.role',
@@ -133,6 +135,7 @@ export const mocks = [
133
135
  },
134
136
  id: barVariableGlobalId,
135
137
  key: 'bar',
138
+ path: '/ansible/ansible_variables/11/edit',
136
139
  defaultValue: 'a',
137
140
  parameterType: 'string',
138
141
  ansibleRoleName: 'test.role',
@@ -160,6 +163,7 @@ export const mocks = [
160
163
  },
161
164
  id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTY1',
162
165
  key: 'square',
166
+ path: '/ansible/ansible_variables/12/edit',
163
167
  defaultValue: true,
164
168
  parameterType: 'boolean',
165
169
  ansibleRoleName: 'test.role',
@@ -179,6 +183,7 @@ export const mocks = [
179
183
  },
180
184
  id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTc4',
181
185
  key: 'circle',
186
+ path: '/ansible/ansible_variables/13/edit',
182
187
  defaultValue: 'd',
183
188
  parameterType: 'string',
184
189
  ansibleRoleName: 'test.role',
@@ -203,6 +208,7 @@ export const mocks = [
203
208
  },
204
209
  id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTc5',
205
210
  key: 'ellipse',
211
+ path: '/ansible/ansible_variables/14/edit',
206
212
  defaultValue: ['seven', 'eight'],
207
213
  parameterType: 'array',
208
214
  ansibleRoleName: 'test.role',
@@ -227,6 +233,7 @@ export const mocks = [
227
233
  },
228
234
  id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTY2Ng==',
229
235
  key: 'spiral',
236
+ path: '/ansible/ansible_variables/15/edit',
230
237
  defaultValue: { one: 'one', two: 'two' },
231
238
  parameterType: 'hash',
232
239
  ansibleRoleName: 'test.role',
@@ -246,6 +253,7 @@ export const mocks = [
246
253
  },
247
254
  id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTY3Mg==',
248
255
  key: 'sun',
256
+ path: '/ansible/ansible_variables/16/edit',
249
257
  defaultValue: "{ one: 'one', two: 'two' }",
250
258
  parameterType: 'json',
251
259
  ansibleRoleName: 'test.role',
@@ -265,6 +273,7 @@ export const mocks = [
265
273
  },
266
274
  id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTY3Mw==',
267
275
  key: 'moon',
276
+ path: '/ansible/ansible_variables/17/edit',
268
277
  defaultValue: [
269
278
  { hosts: 'all', become: 'true', roles: ['foo'] },
270
279
  ],
@@ -37,12 +37,12 @@ describe('AnsibleVariableOverrides', () => {
37
37
  userEvent.click(screen.getByText('Delete'));
38
38
  await waitFor(tick);
39
39
  expect(
40
- screen.getByText('Delete Ansible Variable Override')
40
+ screen.getByText('Delete Ansible variable override')
41
41
  ).toBeInTheDocument();
42
42
  userEvent.click(screen.getByText('Cancel'));
43
43
  await waitFor(tick);
44
44
  expect(
45
- screen.queryByText('Delete Ansible Variable Override')
45
+ screen.queryByText('Delete Ansible variable override')
46
46
  ).not.toBeInTheDocument();
47
47
  });
48
48
  it('should delete override', async () => {
@@ -41,7 +41,10 @@ const AnsibleVariableOverrides = ({ hostId, hostAttrs, history }) => {
41
41
  renameData={renameData}
42
42
  fetchFn={useFetchFn}
43
43
  renamedDataPath="variables"
44
- emptyStateTitle={__('No Ansible Variables found for Host')}
44
+ emptyStateProps={{
45
+ header: __('No Ansible variables found for Host'),
46
+ description: __('Only variables marked to Override are shown here.'),
47
+ }}
45
48
  permissions={['view_ansible_variables']}
46
49
  pagination={pagination}
47
50
  history={history}
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import { useQuery } from '@apollo/client';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
5
 
6
- import { Modal, Button, ModalVariant } from '@patternfly/react-core';
6
+ import { Modal, ModalVariant } from '@patternfly/react-core';
7
7
 
8
8
  import allAnsibleRolesQuery from '../../../../../graphql/queries/allAnsibleRoles.gql';
9
9
  import AllRolesTable from './AllRolesTable';
@@ -17,25 +17,19 @@ const AllRolesModal = ({ hostGlobalId, onClose, history }) => {
17
17
  const baseModalProps = {
18
18
  variant: ModalVariant.large,
19
19
  isOpen: true,
20
+ onClose,
20
21
  className: 'foreman-modal',
21
- showClose: false,
22
- title: __('All Ansible Roles'),
22
+ showClose: true,
23
+ title: __('All assigned Ansible roles'),
23
24
  disableFocusTrap: true,
25
+ description: __(
26
+ 'This list consists of host assigned roles and group assigned roles. Group assigned roles will always be executed prior to host assigned roles'
27
+ ),
24
28
  };
25
29
 
26
30
  const paginationKeys = { page: 'allPage', perPage: 'allPerPage' };
27
31
 
28
- const actions = [
29
- <Button variant="link" onClick={onClose} key="close">
30
- {__('Close')}
31
- </Button>,
32
- ];
33
-
34
- const wrapper = child => (
35
- <Modal {...baseModalProps} actions={actions}>
36
- {child}
37
- </Modal>
38
- );
32
+ const wrapper = child => <Modal {...baseModalProps}>{child}</Modal>;
39
33
 
40
34
  const loadingWrapper = child => <Modal {...baseModalProps}>{child}</Modal>;
41
35
 
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { translate as __ } from 'foremanReact/common/I18n';
3
3
  import PropTypes from 'prop-types';
4
4
 
5
- import { Modal, Button, ModalVariant } from '@patternfly/react-core';
5
+ import { Modal, Button } from '@patternfly/react-core';
6
6
  import { useQuery } from '@apollo/client';
7
7
 
8
8
  import EditRolesForm from './EditRolesForm';
@@ -20,12 +20,15 @@ const EditRolesModal = ({
20
20
  canEditHost,
21
21
  }) => {
22
22
  const baseModalProps = {
23
- variant: ModalVariant.large,
23
+ width: '70%',
24
24
  isOpen,
25
25
  className: 'foreman-modal',
26
26
  showClose: false,
27
27
  title: __('Edit Ansible Roles'),
28
28
  disableFocusTrap: true,
29
+ description: __(
30
+ 'Add, remove or reorder host assigned Ansible roles. This host has also group assigned roles that are not displayed here and will always be executed prior to host assigned roles'
31
+ ),
29
32
  };
30
33
 
31
34
  const actions = [
@@ -48,7 +48,7 @@ const RolesTable = ({
48
48
  <FlexItem>
49
49
  <Link to="/Ansible/roles/edit">
50
50
  <Button aria-label="edit ansible roles">
51
- {__('Edit Ansible Roles')}
51
+ {__('Edit Ansible roles')}
52
52
  </Button>
53
53
  </Link>
54
54
  </FlexItem>
@@ -90,7 +90,9 @@ const RolesTable = ({
90
90
  <Tbody>
91
91
  {ansibleRoles.map(role => (
92
92
  <Tr key={role.id}>
93
- <Td>{role.name}</Td>
93
+ <Td>
94
+ <a href={role.path}>{role.name}</a>
95
+ </Td>
94
96
  </Tr>
95
97
  ))}
96
98
  </Tbody>
@@ -39,7 +39,7 @@ describe('assigning Ansible roles', () => {
39
39
  userEvent.click(screen.getByRole('button', { name: 'edit ansible roles' }));
40
40
  await waitFor(tick);
41
41
  await waitFor(tick);
42
- expect(screen.getByText('Available options')).toBeInTheDocument();
42
+ expect(screen.getByText('Available Ansible roles')).toBeInTheDocument();
43
43
  userEvent.click(screen.getAllByText('another.role')[1]);
44
44
  userEvent.click(screen.getByRole('button', { name: 'Remove selected' }));
45
45
  userEvent.click(screen.getByText('geerlingguy.ceylon'));
@@ -67,7 +67,7 @@ describe('assigning Ansible roles', () => {
67
67
  await waitFor(tick);
68
68
  userEvent.click(screen.getByRole('button', { name: 'edit ansible roles' }));
69
69
  await waitFor(tick);
70
- expect(screen.getByText('Available options')).toBeInTheDocument();
70
+ expect(screen.getByText('Available Ansible roles')).toBeInTheDocument();
71
71
  userEvent.click(screen.getAllByText('another.role')[1]);
72
72
  userEvent.click(screen.getByRole('button', { name: 'Remove selected' }));
73
73
  userEvent.click(screen.getByText('geerlingguy.ceylon'));
@@ -34,24 +34,28 @@ const role1 = {
34
34
  __typename: 'AnsibleRole',
35
35
  id: 'MDE6QW5zaWJsZVJvbGUtMw==',
36
36
  name: 'aardvaark.cube',
37
+ path: '/ansible/ansible_roles/search="name = aardvaark.cube"',
37
38
  };
38
39
 
39
40
  const role2 = {
40
41
  __typename: 'AnsibleRole',
41
42
  id: 'MDE6QW5zaWJsZVJvbGUtNQ==',
42
43
  name: 'aardvaark.sphere',
44
+ path: '/ansible/ansible_roles/search="name = aardvaark.sphere"',
43
45
  };
44
46
 
45
47
  const role3 = {
46
48
  __typename: 'AnsibleRole',
47
49
  id: 'MDE6QW5zaWJsZVJvbGUtMzA=',
48
50
  name: 'another.role',
51
+ path: '/ansible/ansible_roles/search="name = another.role"',
49
52
  };
50
53
 
51
54
  const role4 = {
52
55
  __typename: 'AnsibleRole',
53
56
  id: 'MDE6QW5zaWJsZVJvbGUtMzk=',
54
57
  name: 'geerlingguy.ceylon',
58
+ path: '/ansible/ansible_roles/search="name = geerlingguy.ceylon"',
55
59
  };
56
60
 
57
61
  const ansibleRolesMock = {
@@ -71,26 +75,32 @@ const availableRoles = {
71
75
  __typename: 'AnsibleRole',
72
76
  id: 'MDE6QW5zaWJsZVJvbGUtMQ==',
73
77
  name: 'theforeman.foreman_scap_client',
78
+ path:
79
+ '/ansible/ansible_roles/search="name = theforeman.foreman_scap_client"',
74
80
  },
75
81
  {
76
82
  __typename: 'AnsibleRole',
77
83
  id: 'MDE6QW5zaWJsZVJvbGUtMg==',
78
84
  name: 'adriagalin.motd',
85
+ path: '/ansible/ansible_roles/search="name = adriagalin.motd"',
79
86
  },
80
87
  {
81
88
  __typename: 'AnsibleRole',
82
89
  id: 'MDE6QW5zaWJsZVJvbGUtMjI=',
83
90
  name: 'geerlingguy.php',
91
+ path: '/ansible/ansible_roles/search="name = geerlingguy.php"',
84
92
  },
85
93
  {
86
94
  __typename: 'AnsibleRole',
87
95
  id: 'MDE6QW5zaWJsZVJvbGUtNTc=',
88
96
  name: 'robertdebock.epel',
97
+ path: '/ansible/ansible_roles/search="name = robertdebock.epel"',
89
98
  },
90
99
  {
91
100
  __typename: 'AnsibleRole',
92
101
  id: 'MDE6QW5zaWJsZVJvbGUtNTg=',
93
102
  name: 'geerlingguy.nfs',
103
+ path: '/ansible/ansible_roles/search="name = geerlingguy.nfs"',
94
104
  },
95
105
  ],
96
106
  };
@@ -106,6 +116,7 @@ export const allRolesMocks = allAnsibleRolesMockFactory(
106
116
  {
107
117
  id: 'MDE6QW5zaWJsZVJvbGUtMg==',
108
118
  name: 'adriagalin.motd',
119
+ path: '/ansible/ansible_roles/search="name = adriagalin.motd"',
109
120
  inherited: true,
110
121
  },
111
122
  { ...role1, inherited: false },
@@ -38,14 +38,18 @@ describe('RolesTab', () => {
38
38
  );
39
39
  await waitFor(tick);
40
40
  expect(screen.getByText('view all assigned roles')).toBeInTheDocument();
41
- expect(screen.queryByText('All Ansible Roles')).not.toBeInTheDocument();
41
+ expect(
42
+ screen.queryByText('All assigned Ansible roles')
43
+ ).not.toBeInTheDocument();
42
44
  userEvent.click(screen.getByText('view all assigned roles'));
43
45
  await waitFor(tick);
44
- expect(screen.getByText('All Ansible Roles')).toBeInTheDocument();
46
+ expect(screen.getByText('All assigned Ansible roles')).toBeInTheDocument();
45
47
  expect(screen.getByText('Inherited from Hostgroup')).toBeInTheDocument();
46
48
  userEvent.click(screen.getByRole('button', { name: 'Close' }));
47
49
  await waitFor(tick);
48
- expect(screen.queryByText('All Ansible Roles')).not.toBeInTheDocument();
50
+ expect(
51
+ screen.queryByText('All assigned Ansible roles')
52
+ ).not.toBeInTheDocument();
49
53
  });
50
54
  it('should load Ansible Roles as viewer', async () => {
51
55
  render(
@@ -1,6 +1,7 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useQuery } from '@apollo/client';
4
+ import { Button } from '@patternfly/react-core';
4
5
  import { translate as __ } from 'foremanReact/common/I18n';
5
6
 
6
7
  import ansibleRolesQuery from '../../../../graphql/queries/hostAnsibleRoles.gql';
@@ -10,11 +11,12 @@ import {
10
11
  useParamsToVars,
11
12
  useCurrentPagination,
12
13
  } from '../../../../helpers/pageParamsHelper';
14
+ import EditRolesModal from './EditRolesModal';
13
15
 
14
16
  const RolesTab = ({ hostId, history, canEditHost }) => {
15
17
  const hostGlobalId = encodeId('Host', hostId);
16
18
  const pagination = useCurrentPagination(history);
17
-
19
+ const [assignModal, setAssignModal] = useState(false);
18
20
  const renameData = data => ({
19
21
  ansibleRoles: data.host.ownAnsibleRoles.nodes,
20
22
  totalCount: data.host.ownAnsibleRoles.totalCount,
@@ -26,19 +28,41 @@ const RolesTab = ({ hostId, history, canEditHost }) => {
26
28
  fetchPolicy: 'network-only',
27
29
  });
28
30
 
31
+ const editBtn = canEditHost ? (
32
+ <Button
33
+ onClick={() => setAssignModal(true)}
34
+ aria-label="edit ansible roles"
35
+ >
36
+ {__('Assign Ansible roles')}
37
+ </Button>
38
+ ) : null;
29
39
  return (
30
- <RolesTable
31
- fetchFn={useFetchFn}
32
- renamedDataPath="ansibleRoles"
33
- renameData={renameData}
34
- permissions={['view_ansible_roles']}
35
- history={history}
36
- hostGlobalId={hostGlobalId}
37
- emptyStateProps={{ title: __('No Ansible roles assigned') }}
38
- pagination={pagination}
39
- canEditHost={canEditHost}
40
- hostId={hostId}
41
- />
40
+ <>
41
+ <RolesTable
42
+ fetchFn={useFetchFn}
43
+ renamedDataPath="ansibleRoles"
44
+ renameData={renameData}
45
+ permissions={['view_ansible_roles']}
46
+ history={history}
47
+ hostGlobalId={hostGlobalId}
48
+ emptyStateProps={{
49
+ header: __('No Ansible roles assigned'),
50
+ action: editBtn,
51
+ }}
52
+ pagination={pagination}
53
+ canEditHost={canEditHost}
54
+ hostId={hostId}
55
+ />
56
+ {assignModal && (
57
+ <EditRolesModal
58
+ closeModal={() => setAssignModal(false)}
59
+ isOpen={assignModal}
60
+ assignedRoles={[]}
61
+ hostId={hostId}
62
+ canEditHost={canEditHost}
63
+ />
64
+ )}
65
+ </>
42
66
  );
43
67
  };
44
68
 
@@ -63,7 +63,7 @@ const DualList = props => {
63
63
  return (
64
64
  <div className="pf-c-dual-list-selector">
65
65
  <ListPane
66
- title={__('Available options')}
66
+ title={__('Available Ansible roles')}
67
67
  items={props.availableOptions}
68
68
  paneClass="pf-m-available"
69
69
  onItemClick={onItemClick('availableSelected')}
@@ -81,7 +81,7 @@ const DualList = props => {
81
81
  removeSelectedDisabled={selectState.chosenSelected.length === 0}
82
82
  />
83
83
  <ListPane
84
- title={__('Chosen options')}
84
+ title={__('Host assigned Ansible roles')}
85
85
  items={props.chosenOptions}
86
86
  paneClass="pf-m-chosen"
87
87
  draggable
@@ -8,6 +8,7 @@ query($id: String!, $first: Int, $last: Int) {
8
8
  nodes {
9
9
  id
10
10
  name
11
+ path
11
12
  }
12
13
  }
13
14
  }
@@ -8,6 +8,7 @@ query($id: String!, $match: String, $first: Int, $last: Int) {
8
8
  nodes {
9
9
  id
10
10
  key
11
+ path
11
12
  meta {
12
13
  canEdit
13
14
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_ansible
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.1
4
+ version: 7.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Lobato Garcia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-07 00:00:00.000000000 Z
11
+ date: 2022-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acts_as_list
@@ -101,6 +101,8 @@ files:
101
101
  - app/graphql/mutations/hosts/assign_ansible_roles.rb
102
102
  - app/graphql/presenters/ansible_role_presenter.rb
103
103
  - app/graphql/presenters/overriden_ansible_variable_presenter.rb
104
+ - app/graphql/resolvers/ansible_role/path.rb
105
+ - app/graphql/resolvers/ansible_variable/path.rb
104
106
  - app/graphql/types/ansible_role.rb
105
107
  - app/graphql/types/ansible_variable.rb
106
108
  - app/graphql/types/ansible_variable_override.rb
@@ -445,7 +447,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
445
447
  - !ruby/object:Gem::Version
446
448
  version: '0'
447
449
  requirements: []
448
- rubygems_version: 3.1.6
450
+ rubygems_version: 3.3.4
449
451
  signing_key:
450
452
  specification_version: 4
451
453
  summary: Ansible integration with Foreman (theforeman.org)