foreman_ansible 2.3.6 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/ui_ansible_roles_controller.rb +14 -0
  3. data/app/helpers/foreman_ansible/ansible_roles_helper.rb +4 -0
  4. data/app/models/ansible_role.rb +1 -0
  5. data/app/models/foreman_ansible/ansible_provider.rb +6 -1
  6. data/app/models/setting/ansible.rb +10 -10
  7. data/app/services/foreman_ansible/inventory_creator.rb +26 -23
  8. data/app/views/foreman_ansible/ansible_roles/_select_tab_content.html.erb +13 -13
  9. data/app/views/ui_ansible_roles/index.json.rabl +3 -0
  10. data/app/views/ui_ansible_roles/main.json.rabl +3 -0
  11. data/app/views/ui_ansible_roles/show.json.rabl +3 -0
  12. data/config/routes.rb +2 -0
  13. data/db/migrate/20190328114657_remove_top_level_ansible_variables_setting.rb +6 -0
  14. data/lib/foreman_ansible/register.rb +3 -2
  15. data/lib/foreman_ansible/version.rb +1 -1
  16. data/locale/de/foreman_ansible.edit.po +90 -191
  17. data/locale/en/foreman_ansible.edit.po +90 -191
  18. data/locale/es/foreman_ansible.edit.po +90 -191
  19. data/locale/fr/foreman_ansible.edit.po +90 -191
  20. data/locale/it/foreman_ansible.edit.po +90 -191
  21. data/locale/ja/foreman_ansible.edit.po +90 -191
  22. data/locale/ko/foreman_ansible.edit.po +90 -191
  23. data/locale/pt_BR/foreman_ansible.edit.po +90 -191
  24. data/locale/ru/foreman_ansible.edit.po +90 -191
  25. data/locale/zh_CN/foreman_ansible.edit.po +90 -191
  26. data/locale/zh_TW/foreman_ansible.edit.po +90 -191
  27. data/package.json +50 -9
  28. data/test/factories/ansible_variables.rb +1 -0
  29. data/test/functional/ui_ansible_roles_controller_test.rb +14 -0
  30. data/test/unit/lib/foreman_ansible_core/playbook_runner_test.rb +11 -11
  31. data/test/unit/services/inventory_creator_test.rb +75 -24
  32. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
  33. data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +5 -0
  34. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.js +140 -0
  35. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.scss +45 -0
  36. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherActions.js +69 -0
  37. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherConstants.js +7 -0
  38. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherHelpers.js +7 -0
  39. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherReducer.js +69 -0
  40. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherSelectors.js +68 -0
  41. data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesData.fixtures.js +20 -0
  42. data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesSwitcherReducer.fixtures.js +36 -0
  43. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcher.test.js +30 -0
  44. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherReducer.test.js +73 -0
  45. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherSelectors.test.js +43 -0
  46. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcher.test.js.snap +79 -0
  47. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherReducer.test.js.snap +399 -0
  48. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherSelectors.test.js.snap +60 -0
  49. data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.js +33 -0
  50. data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.test.js +9 -0
  51. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +56 -0
  52. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.test.js +26 -0
  53. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleActionButton.js +16 -0
  54. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRolesSwitcherError.js +32 -0
  55. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.js +67 -0
  56. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.test.js +19 -0
  57. data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.js +52 -0
  58. data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.test.js +22 -0
  59. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsiblePermissionDenied.test.js.snap +26 -0
  60. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRole.test.js.snap +108 -0
  61. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AssignedRolesList.test.js.snap +64 -0
  62. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +54 -0
  63. data/webpack/components/AnsibleRolesSwitcher/components/withProtectedView.js +14 -0
  64. data/webpack/components/AnsibleRolesSwitcher/index.js +44 -0
  65. data/webpack/components/ReportJsonViewer.js +11 -7
  66. data/webpack/index.js +14 -1
  67. data/webpack/reducer.js +7 -0
  68. data/webpack/test_setup.js +11 -0
  69. metadata +44 -2
@@ -7,34 +7,75 @@
7
7
  "test": "test"
8
8
  },
9
9
  "dependencies": {
10
- "react-json-tree": "^0.11.0"
10
+ "babel-polyfill": "^6.26.0",
11
+ "classnames": "^2.2.6",
12
+ "lodash": "4.17.10",
13
+ "patternfly": "^3.58.0",
14
+ "patternfly-react": "^2.25.4",
15
+ "prop-types": "^15.7.2",
16
+ "react": "^16.6.3",
17
+ "react-bootstrap": "^0.32.4",
18
+ "react-dom": "^16.6.3",
19
+ "react-json-tree": "^0.11.0",
20
+ "reselect": "^3.0.1",
21
+ "seamless-immutable": "7.1.2"
11
22
  },
12
23
  "devDependencies": {
13
24
  "babel-eslint": "^8.2.1",
14
- "babel-preset-env": "^1.6.0",
15
- "babel-preset-react": "^6.24.1",
16
25
  "babel-plugin-lodash": "^3.3.2",
17
- "babel-plugin-transform-object-assign": "^6.22.0",
18
26
  "babel-plugin-transform-class-properties": "^6.24.1",
27
+ "babel-plugin-transform-object-assign": "^6.22.0",
19
28
  "babel-plugin-transform-object-rest-spread": "^6.26.0",
29
+ "babel-preset-env": "^1.6.0",
30
+ "babel-preset-react": "^6.24.1",
31
+ "enzyme": "^3.7.0",
32
+ "enzyme-adapter-react-16": "^1.7.0",
33
+ "enzyme-to-json": "^3.3.5",
20
34
  "eslint": "^4.18.1",
21
35
  "eslint-config-airbnb": "^16.0.0",
22
36
  "eslint-plugin-import": "^2.8.0",
23
37
  "eslint-plugin-jest": "^21.2.0",
24
38
  "eslint-plugin-jsx-a11y": "^6.0.2",
25
- "eslint-plugin-react": "^7.4.0"
39
+ "eslint-plugin-patternfly-react": "^0.2.1",
40
+ "eslint-plugin-react": "^7.4.0",
41
+ "identity-obj-proxy": "^3.0.0",
42
+ "jest": "^23.6.0",
43
+ "prettier": "^1.16.4",
44
+ "react-redux": "^6.0.0",
45
+ "react-redux-test-utils": "^0.1.1",
46
+ "redux": "^4.0.1",
47
+ "redux-thunk": "^2.3.0"
26
48
  },
27
49
  "scripts": {
28
- "test": "echo \"Error: no test specified\" && exit 1"
50
+ "test": "node node_modules/.bin/jest webpack",
51
+ "lint": "./node_modules/.bin/eslint -c .eslintrc webpack/ || exit 0"
29
52
  },
30
53
  "repository": {
31
54
  "type": "git",
32
- "url": "git+https://github.com/bastilian/foreman_ansible.git"
55
+ "url": "git+https://github.com/theforeman/foreman_ansible.git"
33
56
  },
34
57
  "author": "",
35
58
  "license": "ISC",
36
59
  "bugs": {
37
- "url": "https://github.com/bastilian/foreman_ansible/issues"
60
+ "url": "https://projects.theforeman.org/projects/ansible"
38
61
  },
39
- "homepage": "https://github.com/bastilian/foreman_ansible#readme"
62
+ "homepage": "https://theforeman.org/plugins/foreman_ansible/",
63
+ "jest": {
64
+ "verbose": true,
65
+ "moduleDirectories": [
66
+ "node_modules",
67
+ "webpack"
68
+ ],
69
+ "setupFiles": [
70
+ "raf/polyfill",
71
+ "./webpack/test_setup.js"
72
+ ],
73
+ "testPathIgnorePatterns": [
74
+ "/node_modules/",
75
+ "<rootDir>/foreman/"
76
+ ],
77
+ "moduleNameMapper": {
78
+ "^.+\\.(css|scss)$": "identity-obj-proxy"
79
+ }
80
+ }
40
81
  }
@@ -3,6 +3,7 @@
3
3
  FactoryBot.define do
4
4
  factory :ansible_variable do
5
5
  sequence(:key) { |n| "ansible_variable_#{n}" }
6
+ sequence(:default_value) { |n| "default_value_#{n}" }
6
7
  ansible_role
7
8
  imported true
8
9
  end
@@ -0,0 +1,14 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class UiAnsibleRolesControllerTest < ActionController::TestCase
4
+ setup do
5
+ @role = FactoryBot.create(:ansible_role)
6
+ end
7
+
8
+ test 'should respond with roles' do
9
+ get :index, :params => {}, :session => set_session_user
10
+ assert_response :success
11
+ res = JSON.parse @response.body
12
+ assert_equal res['total'], res['results'].size
13
+ end
14
+ end
@@ -7,24 +7,24 @@ require 'test_helper'
7
7
  class PlaybookRunnerTest < ActiveSupport::TestCase
8
8
  context 'roles dir' do
9
9
  test 'reads default when none provided' do
10
- ForemanAnsibleCore::PlaybookRunner.any_instance.stubs(:unknown_hosts).
10
+ ForemanAnsibleCore::Runner::Playbook.any_instance.stubs(:unknown_hosts).
11
11
  returns([])
12
12
  File.expects(:exist?).with(Dir.home).returns(true)
13
- runner = ForemanAnsibleCore::PlaybookRunner.new(nil, nil)
13
+ runner = ForemanAnsibleCore::Runner::Playbook.new(nil, nil, :suspended_action => nil)
14
14
  assert '/etc/ansible', runner.instance_variable_get('@ansible_dir')
15
15
  end
16
16
  end
17
17
 
18
18
  context 'working_dir' do
19
19
  setup do
20
- ForemanAnsibleCore::PlaybookRunner.any_instance.stubs(:unknown_hosts).
20
+ ForemanAnsibleCore::Runner::Playbook.any_instance.stubs(:unknown_hosts).
21
21
  returns([])
22
22
  end
23
23
 
24
24
  test 'creates temp one if not provided' do
25
25
  Dir.expects(:mktmpdir)
26
26
  File.expects(:exist?).with(Dir.home).returns(true)
27
- ForemanAnsibleCore::PlaybookRunner.new(nil, nil)
27
+ ForemanAnsibleCore::Runner::Playbook.new(nil, nil, :suspended_action => nil)
28
28
  end
29
29
 
30
30
  test 'reads it when provided' do
@@ -32,7 +32,7 @@ class PlaybookRunnerTest < ActiveSupport::TestCase
32
32
  ForemanAnsibleCore.expects(:settings).returns(settings)
33
33
  File.expects(:exist?).with(settings[:ansible_dir]).returns(true)
34
34
  Dir.expects(:mktmpdir).never
35
- runner = ForemanAnsibleCore::PlaybookRunner.new(nil, nil)
35
+ runner = ForemanAnsibleCore::Runner::Playbook.new(nil, nil, :suspended_action => nil)
36
36
  assert '/foo', runner.instance_variable_get('@working_dir')
37
37
  end
38
38
  end
@@ -42,24 +42,24 @@ class PlaybookRunnerTest < ActiveSupport::TestCase
42
42
  @inventory = { 'all' => { 'hosts' => ['foreman.example.com'] } }.to_json
43
43
  @output = StringIO.new
44
44
  logger = Logger.new(@output)
45
- ForemanAnsibleCore::PlaybookRunner.any_instance.stubs(:logger).
45
+ ForemanAnsibleCore::Runner::Playbook.any_instance.stubs(:logger).
46
46
  returns(logger)
47
47
  end
48
48
 
49
49
  test 'ignores known hosts' do
50
50
  Net::SSH::KnownHosts.expects(:search_for).
51
51
  with('foreman.example.com').returns(['somekey'])
52
- ForemanAnsibleCore::PlaybookRunner.any_instance.
52
+ ForemanAnsibleCore::Runner::Playbook.any_instance.
53
53
  expects(:add_to_known_hosts).never
54
- ForemanAnsibleCore::PlaybookRunner.new(@inventory, nil)
54
+ ForemanAnsibleCore::Runner::Playbook.new(@inventory, nil, :suspended_action => nil)
55
55
  end
56
56
 
57
57
  test 'adds unknown hosts to known_hosts' do
58
58
  Net::SSH::KnownHosts.expects(:search_for).
59
59
  with('foreman.example.com').returns([])
60
- ForemanAnsibleCore::PlaybookRunner.any_instance.
60
+ ForemanAnsibleCore::Runner::Playbook.any_instance.
61
61
  expects(:add_to_known_hosts).with('foreman.example.com')
62
- ForemanAnsibleCore::PlaybookRunner.new(@inventory, nil)
62
+ ForemanAnsibleCore::Runner::Playbook.new(@inventory, nil, :suspended_action => nil)
63
63
  end
64
64
 
65
65
  test 'logs error when it cannot add to known_hosts' do
@@ -67,7 +67,7 @@ class PlaybookRunnerTest < ActiveSupport::TestCase
67
67
  with('foreman.example.com').returns([])
68
68
  Net::SSH::Transport::Session.expects(:new).with('foreman.example.com').
69
69
  raises(Net::Error)
70
- ForemanAnsibleCore::PlaybookRunner.new(@inventory, nil)
70
+ ForemanAnsibleCore::Runner::Playbook.new(@inventory, nil, :suspended_action => nil)
71
71
  assert_match(
72
72
  /ERROR.*Failed to save host key for foreman.example.com: Net::Error/,
73
73
  @output.string
@@ -137,35 +137,86 @@ module ForemanAnsible
137
137
  inventory.to_hash['all']['vars'])
138
138
  end
139
139
 
140
- context 'top-level parameters sent as variables' do
141
- setup do
142
- # Fetching the Host parameters requires this Setting, since
143
- # this plugin does not provide fixtures
144
- Setting.create(:name => 'top_level_ansible_vars',
145
- :description => 'sample description',
146
- :default => true)
147
- @template_invocation = OpenStruct.new(
148
- :job_invocation => OpenStruct.new(:password => 'foobar'),
149
- :input_values => []
150
- )
140
+ test 'parameters are passed as top-level "hostvars"' do
141
+ @host.expects(:host_params).returns('hello' => 'foreman').at_least_once
142
+ inventory = ForemanAnsible::InventoryCreator.new([@host],
143
+ @template_invocation)
144
+ hostvar = inventory.to_hash['_meta']['hostvars'][@host.name]['hello']
145
+ assert_equal 'foreman', hostvar
146
+ end
147
+
148
+ test 'ansible_roles are passed as top-level "hostvars"' do
149
+ roles = [].tap do |array|
150
+ 2.times { array << FactoryBot.create(:ansible_role) }
151
151
  end
152
152
 
153
- test 'parameters are passed as top-level "hostvars" by default' do
154
- @host.expects(:host_params).returns('hello' => 'foreman').at_least_once
155
- inventory = ForemanAnsible::InventoryCreator.new([@host],
156
- @template_invocation)
157
- hostvar = inventory.to_hash['_meta']['hostvars'][@host.name]['hello']
158
- assert_equal 'foreman', hostvar
153
+ host = FactoryBot.create(:host, :ansible_roles => roles)
154
+ inventory = ForemanAnsible::InventoryCreator.new([host]).to_hash
155
+ inventory_roles = inventory['_meta']['hostvars'][host.name]['foreman_ansible_roles']
156
+ assert_equal 2, inventory_roles.count
157
+ assert_includes inventory_roles, roles.first.name
158
+ end
159
+
160
+ test 'inventory can be generated without template invocation' do
161
+ inventory = ForemanAnsible::InventoryCreator.new([@host]).to_hash
162
+ assert_equal({}, inventory['all']['vars'])
163
+ assert_equal(@host.name, inventory['all']['hosts'].first)
164
+ end
165
+
166
+ test 'ansible variables are passed as top-level "hostvars"' do
167
+ role = FactoryBot.create :ansible_role
168
+ variables = [].tap do |array|
169
+ 2.times do |num|
170
+ array << FactoryBot.create(:ansible_variable,
171
+ :ansible_role_id => role.id,
172
+ :default_value => "value_#{num}",
173
+ :override => true)
174
+ end
159
175
  end
160
176
 
161
- test 'parameters NOT passed as top-level "hostvars" if false' do
162
- Setting['top_level_ansible_vars'] = false
163
- @host.expects(:host_params).returns('hello' => 'foreman').at_least_once
164
- inventory = ForemanAnsible::InventoryCreator.new([@host],
165
- @template_invocation)
166
- hostvar = inventory.to_hash['_meta']['hostvars'][@host.name]['hello']
167
- refute_equal 'foreman', hostvar
177
+ host = FactoryBot.create(:host, :ansible_roles => [role])
178
+ inventory = ForemanAnsible::InventoryCreator.new([host]).to_hash
179
+ host_inventory = inventory['_meta']['hostvars'][host.name]
180
+ assert host_inventory[variables.first.key]
181
+ assert host_inventory[variables.last.key]
182
+ end
183
+
184
+ test 'ansible variables are not passed in "foreman"' do
185
+ role = FactoryBot.create :ansible_role
186
+ variables = [].tap do |array|
187
+ 2.times do |num|
188
+ array << FactoryBot.create(:ansible_variable,
189
+ :ansible_role_id => role.id,
190
+ :default_value => "value_#{num}",
191
+ :override => true)
192
+ end
168
193
  end
194
+
195
+ host = FactoryBot.create(:host, :ansible_roles => [role])
196
+ inventory = ForemanAnsible::InventoryCreator.new([host]).to_hash
197
+ inventory_roles = inventory['_meta']['hostvars'][host.name]['foreman']
198
+ refute inventory_roles[variables.first.key]
199
+ refute inventory_roles[variables.last.key]
200
+ end
201
+
202
+ test 'ansible variables can override host params' do
203
+ role = FactoryBot.create :ansible_role
204
+ FactoryBot.create(:ansible_variable,
205
+ :key => 'test_var',
206
+ :ansible_role_id => role.id,
207
+ :default_value => "variable value",
208
+ :override => true)
209
+ host = FactoryBot.create(:host, :ansible_roles => [role])
210
+ host.expects(:host_params).returns('test_var' => 'param value').at_least_once
211
+ inventory = ForemanAnsible::InventoryCreator.new([host]).to_hash
212
+ assert_equal 'variable value', inventory['_meta']['hostvars'][host.name]['test_var']
213
+ end
214
+
215
+ test 'params from host info have correct nesting' do
216
+ org = FactoryBot.create(:organization)
217
+ host = FactoryBot.create(:host, :organization => org)
218
+ inventory = ForemanAnsible::InventoryCreator.new([host]).to_hash
219
+ assert_equal org.name, inventory['_meta']['hostvars'][host.name]['foreman']['organization']
169
220
  end
170
221
  end
171
222
  # rubocop:enable ClassLength
@@ -0,0 +1,2 @@
1
+ const PaginationWrapper = () => jest.fn();
2
+ export default PaginationWrapper;
@@ -0,0 +1,5 @@
1
+ const EmptyState = () => jest.fn();
2
+
3
+ export const EmptyStatePattern = () => jest.fn();
4
+
5
+ export default EmptyState;
@@ -0,0 +1,140 @@
1
+ import React from 'react';
2
+ import { Grid, Row, Col } from 'patternfly-react';
3
+ import { lowerCase } from 'lodash';
4
+ import PropTypes from 'prop-types';
5
+
6
+ import AvailableRolesList from './components/AvailableRolesList';
7
+ import AssignedRolesList from './components/AssignedRolesList';
8
+ import AnsibleRolesSwitcherError from './components/AnsibleRolesSwitcherError';
9
+ import { excludeAssignedRolesSearch } from './AnsibleRolesSwitcherHelpers';
10
+
11
+ class AnsibleRolesSwitcher extends React.Component {
12
+ componentDidMount() {
13
+ const {
14
+ initialAssignedRoles,
15
+ availableRolesUrl,
16
+ inheritedRoleIds,
17
+ resourceId,
18
+ resourceName,
19
+ } = this.props.data;
20
+
21
+ this.props.getAnsibleRoles(
22
+ availableRolesUrl,
23
+ initialAssignedRoles,
24
+ inheritedRoleIds,
25
+ resourceId,
26
+ resourceName,
27
+ { page: 1, perPage: 10 },
28
+ excludeAssignedRolesSearch(initialAssignedRoles)
29
+ );
30
+ }
31
+
32
+ render() {
33
+ const {
34
+ loading,
35
+ pagination,
36
+ itemCount,
37
+ addAnsibleRole,
38
+ removeAnsibleRole,
39
+ getAnsibleRoles,
40
+ changeAssignedPage,
41
+ assignedPagination,
42
+ assignedRolesCount,
43
+ assignedRoles,
44
+ allAssignedRoles,
45
+ unassignedRoles,
46
+ error,
47
+ } = this.props;
48
+
49
+ const {
50
+ availableRolesUrl,
51
+ inheritedRoleIds,
52
+ resourceId,
53
+ resourceName,
54
+ } = this.props.data;
55
+
56
+ const onListingChange = paginationArgs =>
57
+ getAnsibleRoles(
58
+ availableRolesUrl,
59
+ allAssignedRoles,
60
+ inheritedRoleIds,
61
+ resourceId,
62
+ resourceName,
63
+ paginationArgs,
64
+ excludeAssignedRolesSearch(allAssignedRoles)
65
+ );
66
+
67
+ return (
68
+ <Grid bsClass="container-fluid" id="ansibleRolesSwitcher">
69
+ <Row className="row-eq-height">
70
+ <AnsibleRolesSwitcherError error={error} />
71
+ <Col sm={6} className="available-roles-container">
72
+ <div className="available-roles-header">
73
+ <h2>{__('Available Ansible Roles')}</h2>
74
+ </div>
75
+ <AvailableRolesList
76
+ unassignedRoles={unassignedRoles}
77
+ pagination={pagination}
78
+ itemCount={itemCount}
79
+ onListingChange={onListingChange}
80
+ onAddRole={addAnsibleRole}
81
+ loading={loading}
82
+ />
83
+ </Col>
84
+
85
+ <Col sm={6} className="assigned-roles-container">
86
+ <div className="assigned-roles-header">
87
+ <h2>{__('Assigned Ansible Roles')}</h2>
88
+ </div>
89
+ <AssignedRolesList
90
+ assignedRoles={assignedRoles}
91
+ pagination={assignedPagination}
92
+ itemCount={assignedRolesCount}
93
+ onPaginationChange={changeAssignedPage}
94
+ onRemoveRole={removeAnsibleRole}
95
+ resourceName={lowerCase(resourceName || '')}
96
+ />
97
+ </Col>
98
+ </Row>
99
+ </Grid>
100
+ );
101
+ }
102
+ }
103
+
104
+ AnsibleRolesSwitcher.propTypes = {
105
+ data: PropTypes.shape({
106
+ initialAssignedRoles: PropTypes.arrayOf(PropTypes.object),
107
+ availableRolesUrl: PropTypes.string,
108
+ inheritedRoleIds: PropTypes.arrayOf(PropTypes.number),
109
+ resourceId: PropTypes.number,
110
+ resourceName: PropTypes.string,
111
+ }).isRequired,
112
+ getAnsibleRoles: PropTypes.func.isRequired,
113
+ loading: PropTypes.bool.isRequired,
114
+ pagination: PropTypes.shape({
115
+ page: PropTypes.number,
116
+ perPage: PropTypes.number,
117
+ }).isRequired,
118
+ itemCount: PropTypes.number.isRequired,
119
+ addAnsibleRole: PropTypes.func.isRequired,
120
+ removeAnsibleRole: PropTypes.func.isRequired,
121
+ changeAssignedPage: PropTypes.func.isRequired,
122
+ assignedPagination: PropTypes.shape({
123
+ page: PropTypes.number,
124
+ perPage: PropTypes.number,
125
+ }).isRequired,
126
+ assignedRolesCount: PropTypes.number.isRequired,
127
+ assignedRoles: PropTypes.arrayOf(PropTypes.object).isRequired,
128
+ allAssignedRoles: PropTypes.arrayOf(PropTypes.object).isRequired,
129
+ unassignedRoles: PropTypes.arrayOf(PropTypes.object).isRequired,
130
+ error: PropTypes.shape({
131
+ errorMsg: PropTypes.string,
132
+ statusText: PropTypes.string,
133
+ }),
134
+ };
135
+
136
+ AnsibleRolesSwitcher.defaultProps = {
137
+ error: {},
138
+ };
139
+
140
+ export default AnsibleRolesSwitcher;
@@ -0,0 +1,45 @@
1
+ @import '~patternfly/dist/sass/patternfly/_color-variables';
2
+ @import '~patternfly/dist/sass/patternfly/_variables';
3
+ @import '~patternfly/dist/sass/patternfly/_loading-state';
4
+
5
+ #ansibleRolesSwitcher {
6
+ .list-view-pf {
7
+ .list-group-item.ansible-role-disabled {
8
+ background-color: $color-pf-black-200;
9
+ color: $color-pf-black-500;
10
+ border-left-color: $color-pf-black-200;
11
+ border-right-color: $color-pf-black-200;
12
+ }
13
+
14
+ .list-group-item.ansible-role-movable:hover {
15
+ cursor: pointer;
16
+ }
17
+ }
18
+
19
+ .loading-state-pf {
20
+ padding-top: 5%;
21
+ background-color: $color-pf-white;
22
+ }
23
+
24
+ .role-add-remove-btn {
25
+ background-color: initial;
26
+ border: none;
27
+ color: #0388ce;
28
+ }
29
+
30
+ .list-view-pf-main-info {
31
+ padding-top: 10px;
32
+ padding-bottom: 10px;
33
+ }
34
+
35
+ .list-view-pf-actions {
36
+ margin-top: 0;
37
+ margin-bottom: 0;
38
+ }
39
+
40
+ .list-group-item-heading {
41
+ margin-bottom: 0;
42
+ font-size: 12px;
43
+ font-weight: normal;
44
+ }
45
+ }