foreman_puppet 10.0.0 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/foreman_puppet/api/v2/hosts_bulk_actions_controller.rb +102 -0
- data/app/services/concerns/foreman_puppet/extensions/bulk_hosts_manager.rb +24 -0
- data/config/api_routes.rb +11 -0
- data/lib/foreman_puppet/engine.rb +1 -0
- data/lib/foreman_puppet/register.rb +2 -0
- data/lib/foreman_puppet/version.rb +1 -1
- data/test/controllers/foreman_puppet/api/v2/hosts_bulk_actions_controller_test.rb +171 -0
- data/test/services/foreman_puppet/bulk_hosts_manager_test.rb +33 -0
- data/webpack/global_index.js +42 -0
- data/webpack/src/Extends/Hosts/ActionsBar/ActionsBar.scss +14 -0
- data/webpack/src/Extends/Hosts/ActionsBar/index.js +73 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkChangeProxyCommon/__tests__/actions.test.js +78 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkChangeProxyCommon/actions.js +36 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkChangeProxyCommon/index.js +252 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetCAProxy/__tests__/index.test.js +66 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetCAProxy/index.js +40 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetProxy/__tests__/index.test.js +66 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkChangePuppetProxy/index.js +40 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkRemoveProxyCommon/__tests__/actions.test.js +64 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkRemoveProxyCommon/actions.js +24 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkRemoveProxyCommon/index.js +164 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetCAProxy/__tests__/index.test.js +65 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetCAProxy/index.js +39 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetProxy/__tests__/index.test.js +61 -0
- data/webpack/src/Extends/Hosts/BulkActions/BulkRemovePuppetProxy/index.js +39 -0
- data/webpack/src/Extends/Hosts/BulkActions/__tests__/toastHelpers.test.js +55 -0
- data/webpack/src/Extends/Hosts/BulkActions/toastHelpers.js +17 -0
- data/webpack/src/foreman_puppet_host_form.test.js +4 -4
- metadata +26 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6897f1c5899747e2b70508bfa86bd240db54e8cef027b369941302e4de585814
|
|
4
|
+
data.tar.gz: 81360486bd6be95f0a73be4132766b4a8b561e0020e26589e4a08b90b6318ba7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2391cce05ed4cf77c2f84ffa205306d563add4ad6a361002583a791debae0b8166d6ef4f196fd57b9b1896dd983d8d35f4e7e6b79fac3362a1ceb0d11a65d82e
|
|
7
|
+
data.tar.gz: 852d1503ca1443e667ccf8f70f7271ba4baaadd067878ad62a28ff0426921d6597f9f245a1232948e9ac1e2b0573b4c74634b0012ab80991895899b11a7ccff1
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
module ForemanPuppet
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
class HostsBulkActionsController < ::ForemanPuppet::Api::V2::PuppetBaseController
|
|
5
|
+
include ::Api::V2::BulkHostsExtension
|
|
6
|
+
before_action :find_editable_hosts, only: %i[change_puppet_proxy remove_puppet_proxy]
|
|
7
|
+
before_action :find_smart_proxy, only: %i[change_puppet_proxy]
|
|
8
|
+
|
|
9
|
+
def_param_group :bulk_params do
|
|
10
|
+
param :organization_id, :number, required: true, desc: N_('ID of the organization')
|
|
11
|
+
param :included, Hash, required: true, action_aware: true do
|
|
12
|
+
param :search, String, required: false, desc: N_('Search string for hosts to perform an action on')
|
|
13
|
+
param :ids, Array, required: false, desc: N_('List of host ids to perform an action on')
|
|
14
|
+
end
|
|
15
|
+
param :excluded, Hash, required: true, action_aware: true do
|
|
16
|
+
param :ids, Array, required: false, desc: N_('List of host ids to exclude and not run an action on')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
api :PUT, '/hosts/bulk/change_puppet_proxy', N_('Change Puppet (CA) Proxy')
|
|
21
|
+
param_group :bulk_params
|
|
22
|
+
param :proxy_id, :number, required: true, desc: N_('ID of the Puppet proxy to reassign the hosts to')
|
|
23
|
+
param :ca_proxy, :bool, required: true, desc: N_('True, if Puppet CA proxy should be changed instead of the Puppet proxy')
|
|
24
|
+
def change_puppet_proxy
|
|
25
|
+
error_hosts = ::BulkHostsManager.new(hosts: @hosts).change_puppet_proxy(@proxy, ca_proxy?)
|
|
26
|
+
process_bulk_puppet_proxy_response(
|
|
27
|
+
error_hosts,
|
|
28
|
+
success_message: format(n_(
|
|
29
|
+
'Updated host: changed %{proxy_type}',
|
|
30
|
+
'Updated hosts: changed %{proxy_type}',
|
|
31
|
+
@hosts.count
|
|
32
|
+
), proxy_type: proxy_type),
|
|
33
|
+
error_message: format(n_(
|
|
34
|
+
'Failed to change %{proxy_type} for %{count} host',
|
|
35
|
+
'Failed to change %{proxy_type} for %{count} hosts',
|
|
36
|
+
error_hosts.count
|
|
37
|
+
), proxy_type: proxy_type, count: error_hosts.count)
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
api :PUT, '/hosts/bulk/remove_puppet_proxy', N_('Remove Puppet (CA) Proxy')
|
|
42
|
+
param_group :bulk_params
|
|
43
|
+
param :ca_proxy, :bool, required: true, desc: N_('True, if Puppet CA proxy should be removed instead of the Puppet proxy')
|
|
44
|
+
def remove_puppet_proxy
|
|
45
|
+
error_hosts = ::BulkHostsManager.new(hosts: @hosts).change_puppet_proxy(nil, ca_proxy?)
|
|
46
|
+
process_bulk_puppet_proxy_response(
|
|
47
|
+
error_hosts,
|
|
48
|
+
success_message: format(n_(
|
|
49
|
+
'Updated host: removed %{proxy_type}',
|
|
50
|
+
'Updated hosts: removed %{proxy_type}',
|
|
51
|
+
@hosts.count
|
|
52
|
+
), proxy_type: proxy_type),
|
|
53
|
+
error_message: format(n_(
|
|
54
|
+
'Failed to remove %{proxy_type} for %{count} host',
|
|
55
|
+
'Failed to remove %{proxy_type} for %{count} hosts',
|
|
56
|
+
error_hosts.count
|
|
57
|
+
), proxy_type: proxy_type, count: error_hosts.count)
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def find_editable_hosts
|
|
64
|
+
find_bulk_hosts(:edit_hosts, params)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def process_bulk_puppet_proxy_response(error_hosts, success_message:, error_message:)
|
|
68
|
+
if error_hosts.empty?
|
|
69
|
+
process_response(true, { message: success_message })
|
|
70
|
+
else
|
|
71
|
+
render_error(:bulk_hosts_error, status: :unprocessable_entity,
|
|
72
|
+
locals: { message: error_message, failed_host_ids: error_hosts })
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def find_smart_proxy
|
|
77
|
+
feature = ca_proxy? ? 'Puppet CA' : 'Puppet'
|
|
78
|
+
@proxy = SmartProxy.with_features(feature).find_by(id: params[:proxy_id])
|
|
79
|
+
|
|
80
|
+
if @proxy.nil?
|
|
81
|
+
render json: {
|
|
82
|
+
error: {
|
|
83
|
+
message: format(_('A Smart Proxy with id %{id} and the %{proxy_type} feature could not be found.'), id: params[:proxy_id], proxy_type: proxy_type),
|
|
84
|
+
},
|
|
85
|
+
}, status: :unprocessable_entity
|
|
86
|
+
false
|
|
87
|
+
else
|
|
88
|
+
true
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def ca_proxy?
|
|
93
|
+
Foreman::Cast.to_bool(params[:ca_proxy])
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def proxy_type
|
|
97
|
+
ca_proxy? ? _('Puppet CA proxy') : _('Puppet proxy')
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module ForemanPuppet
|
|
2
|
+
module Extensions
|
|
3
|
+
module BulkHostsManager
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
def change_puppet_proxy(proxy, is_ca_proxy)
|
|
7
|
+
error_hosts = []
|
|
8
|
+
@hosts.each do |host|
|
|
9
|
+
if is_ca_proxy
|
|
10
|
+
host.puppet_ca_proxy = proxy
|
|
11
|
+
else
|
|
12
|
+
host.puppet_proxy = proxy
|
|
13
|
+
end
|
|
14
|
+
host.save(validate: false)
|
|
15
|
+
rescue StandardError => e
|
|
16
|
+
message = format(_('Failed to set proxy for %{host}.'), host: host)
|
|
17
|
+
Foreman::Logging.exception(message, e)
|
|
18
|
+
error_hosts << host.id
|
|
19
|
+
end
|
|
20
|
+
error_hosts
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/config/api_routes.rb
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
Foreman::Application.routes.draw do
|
|
2
|
+
scope module: 'foreman_puppet' do
|
|
3
|
+
namespace :api, defaults: { format: 'json' } do
|
|
4
|
+
scope '(:apiv)', module: :v2, defaults: { apiv: 'v2' }, apiv: /v1|v2/, constraints: ApiConstraints.new(version: 2, default: true) do
|
|
5
|
+
match 'hosts/bulk/change_puppet_proxy', to: 'hosts_bulk_actions#change_puppet_proxy', via: [:put]
|
|
6
|
+
match 'hosts/bulk/remove_puppet_proxy', to: 'hosts_bulk_actions#remove_puppet_proxy', via: [:put]
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
1
12
|
ForemanPuppet::Engine.routes.draw do
|
|
2
13
|
namespace :api, defaults: { format: 'json' } do
|
|
3
14
|
scope '(:apiv)', module: :v2, defaults: { apiv: 'v2' }, apiv: /v1|v2/, constraints: ApiConstraints.new(version: 2, default: true) do
|
|
@@ -49,6 +49,7 @@ module ForemanPuppet
|
|
|
49
49
|
::ProvisioningTemplate.include ForemanPuppet::Extensions::ProvisioningTemplate
|
|
50
50
|
|
|
51
51
|
::HostCounter.prepend ForemanPuppet::Extensions::HostCounter
|
|
52
|
+
::BulkHostsManager.include ForemanPuppet::Extensions::BulkHostsManager
|
|
52
53
|
|
|
53
54
|
::Api::V2::BaseController.include ForemanPuppet::Extensions::ApiBaseController
|
|
54
55
|
::Api::V2::HostsController.include ForemanPuppet::Extensions::ApiV2HostsController
|
|
@@ -62,6 +62,8 @@ Foreman::Plugin.register :foreman_puppet do
|
|
|
62
62
|
p.actions << 'hosts/update_multiple_environment'
|
|
63
63
|
p.actions << 'hosts/select_multiple_puppet_proxy'
|
|
64
64
|
p.actions << 'hosts/update_multiple_puppet_proxy'
|
|
65
|
+
p.actions << 'foreman_puppet/api/v2/hosts_bulk_actions/change_puppet_proxy'
|
|
66
|
+
p.actions << 'foreman_puppet/api/v2/hosts_bulk_actions/remove_puppet_proxy'
|
|
65
67
|
end
|
|
66
68
|
p.actions << 'foreman_puppet/puppetclasses/parameters'
|
|
67
69
|
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
require 'test_puppet_helper'
|
|
2
|
+
|
|
3
|
+
module ForemanPuppet
|
|
4
|
+
module Api
|
|
5
|
+
module V2
|
|
6
|
+
class HostsBulkActionsControllerTest < ActionController::TestCase
|
|
7
|
+
tests ::ForemanPuppet::Api::V2::HostsBulkActionsController
|
|
8
|
+
|
|
9
|
+
setup do
|
|
10
|
+
@routes = ::Foreman::Application.routes
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
let(:host) { FactoryBot.create(:host, :with_puppet_enc) }
|
|
14
|
+
let(:host2) do
|
|
15
|
+
FactoryBot.create(:host, :with_puppet_enc,
|
|
16
|
+
organization: host.organization,
|
|
17
|
+
location: host.location)
|
|
18
|
+
end
|
|
19
|
+
let(:proxy) { FactoryBot.create(:puppet_and_ca_smart_proxy, organizations: [host.organization], locations: [host.location]) }
|
|
20
|
+
|
|
21
|
+
test 'changes puppet proxy for selected hosts' do
|
|
22
|
+
put :change_puppet_proxy,
|
|
23
|
+
params: bulk_params.merge(proxy_id: proxy.id, ca_proxy: false)
|
|
24
|
+
|
|
25
|
+
assert_response :success
|
|
26
|
+
assert_equal proxy.id, host2.reload.puppet_proxy_id
|
|
27
|
+
assert_equal proxy.id, host.reload.puppet_proxy_id
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
test 'changes puppet ca proxy for selected hosts' do
|
|
31
|
+
put :change_puppet_proxy,
|
|
32
|
+
params: bulk_params.merge(proxy_id: proxy.id, ca_proxy: true)
|
|
33
|
+
|
|
34
|
+
assert_response :success
|
|
35
|
+
assert_equal proxy.id, host2.reload.puppet_ca_proxy_id
|
|
36
|
+
assert_equal proxy.id, host.reload.puppet_ca_proxy_id
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test 'removes puppet proxy for selected hosts' do
|
|
40
|
+
host.update!(puppet_proxy: proxy)
|
|
41
|
+
host2.update!(puppet_proxy: proxy)
|
|
42
|
+
|
|
43
|
+
assert_equal proxy, host.reload.puppet_proxy
|
|
44
|
+
|
|
45
|
+
put :remove_puppet_proxy,
|
|
46
|
+
params: bulk_params.merge(ca_proxy: false),
|
|
47
|
+
session: set_session_user
|
|
48
|
+
|
|
49
|
+
assert_response :success
|
|
50
|
+
assert_nil host.reload.puppet_proxy
|
|
51
|
+
assert_nil host2.reload.puppet_proxy
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test 'returns error when puppet proxy is missing' do
|
|
55
|
+
missing_proxy_id = 999_999
|
|
56
|
+
|
|
57
|
+
put :change_puppet_proxy,
|
|
58
|
+
params: bulk_params.merge(proxy_id: missing_proxy_id, ca_proxy: false),
|
|
59
|
+
session: set_session_user
|
|
60
|
+
|
|
61
|
+
assert_response :unprocessable_entity
|
|
62
|
+
response = JSON.parse(@response.body)
|
|
63
|
+
assert_equal "A Smart Proxy with id #{missing_proxy_id} and the Puppet proxy feature could not be found.",
|
|
64
|
+
response.dig('error', 'message')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
test 'returns error when puppet ca proxy is missing' do
|
|
68
|
+
missing_proxy_id = 999_999
|
|
69
|
+
|
|
70
|
+
put :change_puppet_proxy,
|
|
71
|
+
params: bulk_params.merge(proxy_id: missing_proxy_id, ca_proxy: true),
|
|
72
|
+
session: set_session_user
|
|
73
|
+
|
|
74
|
+
assert_response :unprocessable_entity
|
|
75
|
+
response = JSON.parse(@response.body)
|
|
76
|
+
assert_equal "A Smart Proxy with id #{missing_proxy_id} and the Puppet CA proxy feature could not be found.",
|
|
77
|
+
response.dig('error', 'message')
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
test 'returns error when smart proxy is missing puppet feature' do
|
|
81
|
+
invalid_proxy = FactoryBot.create(:smart_proxy, organizations: [host.organization], locations: [host.location])
|
|
82
|
+
invalid_proxy.smart_proxy_feature_by_name('Puppet')&.destroy!
|
|
83
|
+
|
|
84
|
+
put :change_puppet_proxy,
|
|
85
|
+
params: bulk_params.merge(proxy_id: invalid_proxy.id, ca_proxy: false),
|
|
86
|
+
session: set_session_user
|
|
87
|
+
|
|
88
|
+
assert_response :unprocessable_entity
|
|
89
|
+
response = JSON.parse(@response.body)
|
|
90
|
+
assert_equal "A Smart Proxy with id #{invalid_proxy.id} and the Puppet proxy feature could not be found.",
|
|
91
|
+
response.dig('error', 'message')
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
test 'returns error when smart proxy is missing puppet ca feature' do
|
|
95
|
+
invalid_proxy = FactoryBot.create(:puppet_smart_proxy, organizations: [host.organization], locations: [host.location])
|
|
96
|
+
|
|
97
|
+
put :change_puppet_proxy,
|
|
98
|
+
params: bulk_params.merge(proxy_id: invalid_proxy.id, ca_proxy: true),
|
|
99
|
+
session: set_session_user
|
|
100
|
+
|
|
101
|
+
assert_response :unprocessable_entity
|
|
102
|
+
response = JSON.parse(@response.body)
|
|
103
|
+
assert_equal "A Smart Proxy with id #{invalid_proxy.id} and the Puppet CA proxy feature could not be found.",
|
|
104
|
+
response.dig('error', 'message')
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
test 'returns error when changing puppet proxy fails for some hosts' do
|
|
108
|
+
::BulkHostsManager.any_instance.expects(:change_puppet_proxy)
|
|
109
|
+
.with(proxy, false)
|
|
110
|
+
.returns([host2.id])
|
|
111
|
+
|
|
112
|
+
put :change_puppet_proxy,
|
|
113
|
+
params: bulk_params.merge(proxy_id: proxy.id, ca_proxy: false),
|
|
114
|
+
session: set_session_user
|
|
115
|
+
|
|
116
|
+
assert_response :unprocessable_entity
|
|
117
|
+
response = JSON.parse(@response.body)
|
|
118
|
+
assert_equal 'Failed to change Puppet proxy for 1 host',
|
|
119
|
+
response.dig('error', 'message')
|
|
120
|
+
assert_equal [host2.id], response.dig('error', 'failed_host_ids')
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
test 'returns error when removing puppet proxy fails for some hosts' do
|
|
124
|
+
host.update!(puppet_proxy: proxy)
|
|
125
|
+
host2.update!(puppet_proxy: proxy)
|
|
126
|
+
::BulkHostsManager.any_instance.expects(:change_puppet_proxy)
|
|
127
|
+
.with(nil, false)
|
|
128
|
+
.returns([host.id])
|
|
129
|
+
|
|
130
|
+
put :remove_puppet_proxy,
|
|
131
|
+
params: bulk_params.merge(ca_proxy: false),
|
|
132
|
+
session: set_session_user
|
|
133
|
+
|
|
134
|
+
assert_response :unprocessable_entity
|
|
135
|
+
response = JSON.parse(@response.body)
|
|
136
|
+
assert_equal 'Failed to remove Puppet proxy for 1 host',
|
|
137
|
+
response.dig('error', 'message')
|
|
138
|
+
assert_equal [host.id], response.dig('error', 'failed_host_ids')
|
|
139
|
+
assert_equal proxy.id, host.reload.puppet_proxy_id
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
test 'returns error when removing puppet ca proxy fails for some hosts' do
|
|
143
|
+
host.update!(puppet_ca_proxy: proxy)
|
|
144
|
+
host2.update!(puppet_ca_proxy: proxy)
|
|
145
|
+
::BulkHostsManager.any_instance.expects(:change_puppet_proxy)
|
|
146
|
+
.with(nil, true)
|
|
147
|
+
.returns([host.id])
|
|
148
|
+
|
|
149
|
+
put :remove_puppet_proxy,
|
|
150
|
+
params: bulk_params.merge(ca_proxy: true),
|
|
151
|
+
session: set_session_user
|
|
152
|
+
|
|
153
|
+
assert_response :unprocessable_entity
|
|
154
|
+
response = JSON.parse(@response.body)
|
|
155
|
+
assert_equal 'Failed to remove Puppet CA proxy for 1 host',
|
|
156
|
+
response.dig('error', 'message')
|
|
157
|
+
assert_equal [host.id], response.dig('error', 'failed_host_ids')
|
|
158
|
+
assert_equal proxy.id, host.reload.puppet_ca_proxy_id
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def bulk_params
|
|
162
|
+
{
|
|
163
|
+
organization_id: host.organization_id,
|
|
164
|
+
included: { ids: [host.id, host2.id] },
|
|
165
|
+
excluded: { ids: [] },
|
|
166
|
+
}
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'test_puppet_helper'
|
|
2
|
+
|
|
3
|
+
class BulkHostsManagerTest < ActiveSupport::TestCase
|
|
4
|
+
let(:hosts) { FactoryBot.create_list(:host, 2, :with_puppet_enc) }
|
|
5
|
+
let(:manager) { ::BulkHostsManager.new(hosts: hosts) }
|
|
6
|
+
let(:proxy) { FactoryBot.create(:puppet_smart_proxy) }
|
|
7
|
+
|
|
8
|
+
test 'changes puppet proxy for hosts' do
|
|
9
|
+
manager.change_puppet_proxy(proxy, false)
|
|
10
|
+
|
|
11
|
+
hosts.each do |host|
|
|
12
|
+
assert_equal proxy.id, host.reload.puppet_proxy_id
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test 'changes puppet ca proxy for hosts' do
|
|
17
|
+
manager.change_puppet_proxy(proxy, true)
|
|
18
|
+
|
|
19
|
+
hosts.each do |host|
|
|
20
|
+
assert_equal proxy.id, host.reload.puppet_ca_proxy_id
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test 'clears puppet proxy when proxy is nil' do
|
|
25
|
+
hosts.each { |host| host.update!(puppet_proxy: proxy) }
|
|
26
|
+
|
|
27
|
+
manager.change_puppet_proxy(nil, false)
|
|
28
|
+
|
|
29
|
+
hosts.each do |host|
|
|
30
|
+
assert_nil host.reload.puppet_proxy
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/webpack/global_index.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
|
|
1
3
|
import { registerReducer } from 'foremanReact/common/MountingService';
|
|
2
4
|
import { registerColumns } from 'foremanReact/components/HostsIndex/Columns/core';
|
|
3
5
|
import { translate as __ } from 'foremanReact/common/I18n';
|
|
4
6
|
import reducers from './src/reducers';
|
|
5
7
|
import { registerFills } from './src/Extends/Fills';
|
|
6
8
|
import { registerLegacy } from './legacy';
|
|
9
|
+
import HostsIndexActionsBar from './src/Extends/Hosts/ActionsBar';
|
|
10
|
+
import BulkChangePuppetProxy from './src/Extends/Hosts/BulkActions/BulkChangePuppetProxy';
|
|
11
|
+
import BulkChangePuppetCAProxy from './src/Extends/Hosts/BulkActions/BulkChangePuppetCAProxy';
|
|
12
|
+
import BulkRemovePuppetProxy from './src/Extends/Hosts/BulkActions/BulkRemovePuppetProxy';
|
|
13
|
+
import BulkRemovePuppetCAProxy from './src/Extends/Hosts/BulkActions/BulkRemovePuppetCAProxy';
|
|
7
14
|
|
|
8
15
|
// register reducers
|
|
9
16
|
registerReducer('puppet', reducers);
|
|
@@ -29,4 +36,39 @@ puppetHostsIndexColumns.forEach(column => {
|
|
|
29
36
|
column.categoryKey = 'puppet';
|
|
30
37
|
});
|
|
31
38
|
|
|
39
|
+
addGlobalFill(
|
|
40
|
+
'hosts-index-kebab',
|
|
41
|
+
'puppet-hosts-index-kebab',
|
|
42
|
+
<HostsIndexActionsBar key="puppet-hosts-index-kebab" />,
|
|
43
|
+
100
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
addGlobalFill(
|
|
47
|
+
'_all-hosts-modals',
|
|
48
|
+
'BulkChangePuppetProxy',
|
|
49
|
+
<BulkChangePuppetProxy key="bulk-change-puppet-proxy" />,
|
|
50
|
+
100
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
addGlobalFill(
|
|
54
|
+
'_all-hosts-modals',
|
|
55
|
+
'BulkChangePuppetCAProxy',
|
|
56
|
+
<BulkChangePuppetCAProxy key="bulk-change-puppet-ca-proxy" />,
|
|
57
|
+
100
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
addGlobalFill(
|
|
61
|
+
'_all-hosts-modals',
|
|
62
|
+
'BulkRemovePuppetCAProxy',
|
|
63
|
+
<BulkRemovePuppetCAProxy key="bulk-remove-puppet-ca-proxy" />,
|
|
64
|
+
100
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
addGlobalFill(
|
|
68
|
+
'_all-hosts-modals',
|
|
69
|
+
'BulkRemovePuppetProxy',
|
|
70
|
+
<BulkRemovePuppetProxy key="bulk-remove-puppet-proxy" />,
|
|
71
|
+
100
|
|
72
|
+
);
|
|
73
|
+
|
|
32
74
|
registerColumns(puppetHostsIndexColumns);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import { Menu, MenuItem, MenuContent, MenuList } from '@patternfly/react-core';
|
|
3
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
|
4
|
+
import { ForemanHostsIndexActionsBarContext } from 'foremanReact/components/HostsIndex';
|
|
5
|
+
import { openBulkModal } from 'foremanReact/common/BulkModalStateHelper';
|
|
6
|
+
import './ActionsBar.scss';
|
|
7
|
+
|
|
8
|
+
const HostActionsBar = () => {
|
|
9
|
+
const { selectedCount, setMenuOpen } = useContext(
|
|
10
|
+
ForemanHostsIndexActionsBarContext
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const handleOpenBulkModal = modalId => {
|
|
14
|
+
setMenuOpen(false);
|
|
15
|
+
setTimeout(() => openBulkModal(modalId, true), 0);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<MenuItem
|
|
20
|
+
itemId="content-flyout-item"
|
|
21
|
+
key="content-flyout"
|
|
22
|
+
isDisabled={selectedCount === 0}
|
|
23
|
+
flyoutMenu={
|
|
24
|
+
<Menu ouiaId="content-flyout-menu" onSelect={() => setMenuOpen(false)}>
|
|
25
|
+
<MenuContent>
|
|
26
|
+
<MenuList>
|
|
27
|
+
<MenuItem
|
|
28
|
+
itemId="bulk-change-puppet-proxy-menu-item"
|
|
29
|
+
key="bulk-change-puppet-proxy-menu-item"
|
|
30
|
+
onClick={() => handleOpenBulkModal('bulk-change-puppet-proxy')}
|
|
31
|
+
isDisabled={selectedCount === 0}
|
|
32
|
+
>
|
|
33
|
+
{__('Change Puppet proxy')}
|
|
34
|
+
</MenuItem>
|
|
35
|
+
<MenuItem
|
|
36
|
+
itemId="bulk-remove-puppet-proxy-menu-item"
|
|
37
|
+
key="bulk-remove-puppet-proxy-menu-item"
|
|
38
|
+
onClick={() => handleOpenBulkModal('bulk-remove-puppet-proxy')}
|
|
39
|
+
isDisabled={selectedCount === 0}
|
|
40
|
+
>
|
|
41
|
+
{__('Remove Puppet proxy')}
|
|
42
|
+
</MenuItem>
|
|
43
|
+
<MenuItem
|
|
44
|
+
itemId="bulk-change-puppet-ca-proxy-menu-item"
|
|
45
|
+
key="bulk-change-puppet-ca-proxy-menu-item"
|
|
46
|
+
onClick={() =>
|
|
47
|
+
handleOpenBulkModal('bulk-change-puppet-ca-proxy')
|
|
48
|
+
}
|
|
49
|
+
isDisabled={selectedCount === 0}
|
|
50
|
+
>
|
|
51
|
+
{__('Change Puppet CA proxy')}
|
|
52
|
+
</MenuItem>
|
|
53
|
+
<MenuItem
|
|
54
|
+
itemId="bulk-remove-puppet-ca-proxy-menu-item"
|
|
55
|
+
key="bulk-remove-puppet-ca-proxy-menu-item"
|
|
56
|
+
onClick={() =>
|
|
57
|
+
handleOpenBulkModal('bulk-remove-puppet-ca-proxy')
|
|
58
|
+
}
|
|
59
|
+
isDisabled={selectedCount === 0}
|
|
60
|
+
>
|
|
61
|
+
{__('Remove Puppet CA proxy')}
|
|
62
|
+
</MenuItem>
|
|
63
|
+
</MenuList>
|
|
64
|
+
</MenuContent>
|
|
65
|
+
</Menu>
|
|
66
|
+
}
|
|
67
|
+
>
|
|
68
|
+
{__('Puppet')}
|
|
69
|
+
</MenuItem>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default HostActionsBar;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { APIActions } from 'foremanReact/redux/API';
|
|
2
|
+
import { foremanUrl } from 'foremanReact/common/helpers';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
fetchSmartProxies,
|
|
6
|
+
SMART_PROXY_KEY,
|
|
7
|
+
bulkChangePuppetProxy,
|
|
8
|
+
BULK_CHANGE_PUPPET_CA_PROXY_KEY,
|
|
9
|
+
BULK_CHANGE_PUPPET_PROXY_KEY,
|
|
10
|
+
} from '../actions';
|
|
11
|
+
|
|
12
|
+
jest.mock('foremanReact/redux/API', () => ({
|
|
13
|
+
APIActions: {
|
|
14
|
+
get: jest.fn(),
|
|
15
|
+
put: jest.fn(),
|
|
16
|
+
},
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
describe('BulkChangeProxyCommon actions', () => {
|
|
20
|
+
const smartProxiesUrl = foremanUrl('/api/smart_proxies');
|
|
21
|
+
const bulkChangeUrl = foremanUrl('/api/v2/hosts/bulk/change_puppet_proxy');
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
jest.clearAllMocks();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('fetches smart proxies list filtered by feature search', () => {
|
|
28
|
+
fetchSmartProxies('Puppet');
|
|
29
|
+
|
|
30
|
+
expect(APIActions.get).toHaveBeenCalledWith({
|
|
31
|
+
key: SMART_PROXY_KEY,
|
|
32
|
+
url: smartProxiesUrl,
|
|
33
|
+
params: { per_page: 'all', search: 'feature = "Puppet"' },
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('calls bulk change puppet proxy endpoint for Puppet Proxy changes', () => {
|
|
38
|
+
const params = { included: { ids: [1] }, proxy_id: '1', ca_proxy: false };
|
|
39
|
+
const handleSuccess = jest.fn();
|
|
40
|
+
const handleError = jest.fn();
|
|
41
|
+
|
|
42
|
+
bulkChangePuppetProxy(
|
|
43
|
+
params,
|
|
44
|
+
handleSuccess,
|
|
45
|
+
handleError,
|
|
46
|
+
BULK_CHANGE_PUPPET_PROXY_KEY
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
expect(APIActions.put).toHaveBeenCalledWith({
|
|
50
|
+
key: BULK_CHANGE_PUPPET_PROXY_KEY,
|
|
51
|
+
url: bulkChangeUrl,
|
|
52
|
+
handleSuccess,
|
|
53
|
+
handleError,
|
|
54
|
+
params,
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('calls bulk change puppet proxy endpoint for Puppet CA Proxy changes', () => {
|
|
59
|
+
const params = { included: { ids: [1] }, proxy_id: '1', ca_proxy: true };
|
|
60
|
+
const handleSuccess = jest.fn();
|
|
61
|
+
const handleError = jest.fn();
|
|
62
|
+
|
|
63
|
+
bulkChangePuppetProxy(
|
|
64
|
+
params,
|
|
65
|
+
handleSuccess,
|
|
66
|
+
handleError,
|
|
67
|
+
BULK_CHANGE_PUPPET_CA_PROXY_KEY
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(APIActions.put).toHaveBeenCalledWith({
|
|
71
|
+
key: BULK_CHANGE_PUPPET_CA_PROXY_KEY,
|
|
72
|
+
url: bulkChangeUrl,
|
|
73
|
+
handleSuccess,
|
|
74
|
+
handleError,
|
|
75
|
+
params,
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { APIActions } from 'foremanReact/redux/API';
|
|
2
|
+
import { foremanUrl } from 'foremanReact/common/helpers';
|
|
3
|
+
|
|
4
|
+
export const SMART_PROXY_KEY = 'SMART_PROXY_KEY';
|
|
5
|
+
export const BULK_CHANGE_PUPPET_CA_PROXY_KEY = 'BULK_CHANGE_PUPPET_CA_PROXY';
|
|
6
|
+
export const BULK_CHANGE_PUPPET_PROXY_KEY = 'BULK_CHANGE_PUPPET_PROXY';
|
|
7
|
+
|
|
8
|
+
export const fetchSmartProxies = feature => {
|
|
9
|
+
const url = foremanUrl('/api/smart_proxies');
|
|
10
|
+
return APIActions.get({
|
|
11
|
+
key: SMART_PROXY_KEY,
|
|
12
|
+
url,
|
|
13
|
+
params: {
|
|
14
|
+
per_page: 'all',
|
|
15
|
+
...(feature ? { search: `feature = "${feature}"` } : {}),
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const bulkChangePuppetProxy = (
|
|
21
|
+
params,
|
|
22
|
+
handleSuccess,
|
|
23
|
+
handleError,
|
|
24
|
+
key
|
|
25
|
+
) => {
|
|
26
|
+
const url = foremanUrl(`/api/v2/hosts/bulk/change_puppet_proxy`);
|
|
27
|
+
return APIActions.put({
|
|
28
|
+
key,
|
|
29
|
+
url,
|
|
30
|
+
handleSuccess,
|
|
31
|
+
handleError,
|
|
32
|
+
params,
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default fetchSmartProxies;
|