foreman_ovirt 2.0.3 → 2.0.4
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/Rakefile +2 -17
- data/app/assets/javascripts/foreman_ovirt/ovirt.js +37 -8
- data/app/controllers/concerns/foreman_ovirt/api_compute_resources_controller_extension.rb +42 -0
- data/app/controllers/concerns/foreman_ovirt/compute_resources_vms_controller.rb +3 -1
- data/app/controllers/concerns/foreman_ovirt/parameters_extension.rb +5 -5
- data/app/controllers/foreman_ovirt/concerns/compute_resources_controller_extensions.rb +12 -3
- data/app/helpers/ovirt_compute_resource_helper.rb +18 -4
- data/app/models/concerns/fog_extensions/ovirt/server.rb +13 -4
- data/app/models/concerns/fog_extensions/ovirt/template.rb +3 -1
- data/app/models/concerns/fog_extensions/ovirt/volume.rb +3 -1
- data/app/models/foreman_ovirt/ovirt.rb +166 -141
- data/app/views/api/v2/compute_resources/ovirt.json.rabl +2 -0
- data/config/routes.rb +8 -5
- data/db/migrate/20250810212811_update_legacy_ovirt_compute_resource_type.rb +5 -3
- data/lib/foreman_ovirt/engine.rb +8 -5
- data/lib/foreman_ovirt/version.rb +3 -1
- data/lib/foreman_ovirt.rb +2 -0
- data/lib/tasks/foreman_ovirt_tasks.rake +37 -22
- data/locale/gemspec.rb +3 -1
- data/package.json +1 -0
- data/test/controllers/api/v2/compute_resources_controller_test.rb +186 -0
- data/test/controllers/hosts_controller_test.rb +46 -0
- data/test/factories/foreman_ovirt_factories.rb +27 -2
- data/test/fixtures/ovirt_operating_systems.xml +243 -0
- data/test/graphql/types/provider_enum_test.rb +12 -0
- data/test/integration/compute_profile_js_test.rb +49 -0
- data/test/models/compute_resources/compute_resource_test_helpers.rb +143 -0
- data/test/models/compute_resources/ovirt_test.rb +687 -0
- data/test/models/ovirt_volume_test.rb +104 -0
- data/test/test_plugin_helper.rb +2 -0
- data/test/unit/compute_resource_host_importer_test.rb +48 -0
- data/test/unit/ovirt_connection_test.rb +123 -0
- data/webpack/components/__tests__/ovirt.test.js +17 -0
- data/webpack/components/extensions/HostDetails/DetailsTabCards/OvirtCard.js +40 -38
- data/webpack/global_index.js +0 -2
- data/webpack/global_test_setup.js +3 -3
- data/webpack/index.js +0 -1
- metadata +26 -8
- data/test/unit/foreman_ovirt_test.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 265b540a1760c3b80a0ada6c75748d6d70b01d58cfa769e45ddb320fac93f5c5
|
|
4
|
+
data.tar.gz: c7faf208698abeac35635409c83d14d87e7f0c40cdf8854c1456ec0750bcff04
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad89324d644b50989e6f8817b4368b4daee16a2caae9cfdc8012fdca7668dd27a9eeac95d015d712837c2f49544efa22e6fbd3ca2a47d0b52593705ab775b82f
|
|
7
|
+
data.tar.gz: 8aa6f8fb851acb66cd4163b02422cd3317e0d77e3ec6c0441fb39c785e1b3ebb208d90dc174676bbffaa33d2ba572818f5b7d0f67ec661b3bfdd6ef76fc95450
|
data/Rakefile
CHANGED
|
@@ -1,26 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
2
4
|
begin
|
|
3
5
|
require 'bundler/setup'
|
|
4
6
|
rescue LoadError
|
|
5
7
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
8
|
end
|
|
7
|
-
begin
|
|
8
|
-
require 'rdoc/task'
|
|
9
|
-
rescue LoadError
|
|
10
|
-
require 'rdoc/rdoc'
|
|
11
|
-
require 'rake/rdoctask'
|
|
12
|
-
RDoc::Task = Rake::RDocTask
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
|
-
rdoc.rdoc_dir = 'rdoc'
|
|
17
|
-
rdoc.title = 'ForemanOvirt'
|
|
18
|
-
rdoc.options << '--line-numbers'
|
|
19
|
-
rdoc.rdoc_files.include('README.rdoc')
|
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
|
|
24
9
|
|
|
25
10
|
Bundler::GemHelper.install_tasks
|
|
26
11
|
|
|
@@ -25,8 +25,8 @@ function templateSelected(item) {
|
|
|
25
25
|
url,
|
|
26
26
|
data: `template_id=${template}`,
|
|
27
27
|
success(result) {
|
|
28
|
-
// As Instance Type values will take
|
|
29
|
-
// we don't update memory/cores values if
|
|
28
|
+
// As Instance Type values will take precedence over template values,
|
|
29
|
+
// we don't update memory/cores values if an instance type is already selected.
|
|
30
30
|
if (!$('#host_compute_attributes_instance_type').val()) {
|
|
31
31
|
updateCoresAndSockets(result);
|
|
32
32
|
setMemoryInputProps({ value: result.memory });
|
|
@@ -61,6 +61,11 @@ function templateSelected(item) {
|
|
|
61
61
|
function instanceTypeSelected(item) {
|
|
62
62
|
const instanceType = $(item).val();
|
|
63
63
|
|
|
64
|
+
// Ignore empty instance type values. Select2 can fire change on init.
|
|
65
|
+
if (!instanceType) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
64
69
|
if (!item.disabled) {
|
|
65
70
|
const url = $(item).attr('data-url');
|
|
66
71
|
|
|
@@ -138,6 +143,10 @@ function addVolume({
|
|
|
138
143
|
.hide();
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
// Update the memory FormField props and the hidden input value.
|
|
147
|
+
// Memory input component keeps its own internal state on mount, so changing
|
|
148
|
+
// reactProps alone may not update the hidden input used for form submission.
|
|
149
|
+
// To be safe we set reactProps and also update the hidden input directly.
|
|
141
150
|
function setMemoryInputProps(props) {
|
|
142
151
|
const newProps = { ...props };
|
|
143
152
|
|
|
@@ -145,13 +154,32 @@ function setMemoryInputProps(props) {
|
|
|
145
154
|
newProps.value = parseInt(newProps.value, 10);
|
|
146
155
|
}
|
|
147
156
|
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
157
|
+
const wrapper = document.getElementById('memory-input');
|
|
158
|
+
if (!wrapper) return;
|
|
159
|
+
|
|
160
|
+
const element = wrapper.getElementsByTagName('foreman-react-component')[0];
|
|
161
|
+
if (element) {
|
|
162
|
+
element.reactProps = {
|
|
163
|
+
...element.reactProps,
|
|
164
|
+
...newProps,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Also set the hidden input directly because the memory component keeps
|
|
169
|
+
// its own state and may not apply prop updates immediately.
|
|
170
|
+
if (newProps.value !== undefined) {
|
|
171
|
+
const hiddenInput = wrapper.querySelector('input[type="hidden"]');
|
|
172
|
+
if (hiddenInput) hiddenInput.value = newProps.value;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (newProps.disabled !== undefined) {
|
|
176
|
+
const hiddenInput = wrapper.querySelector('input[type="hidden"]');
|
|
177
|
+
if (hiddenInput) hiddenInput.disabled = newProps.disabled;
|
|
178
|
+
}
|
|
153
179
|
}
|
|
154
180
|
|
|
181
|
+
// Update cores and sockets FormField props from AJAX result.
|
|
182
|
+
// These are simple numeric fields so updating reactProps is sufficient.
|
|
155
183
|
function updateCoresAndSockets(result) {
|
|
156
184
|
const coresInputElement = getComponentByWrapperId('cores-input');
|
|
157
185
|
coresInputElement.reactProps = {
|
|
@@ -202,6 +230,7 @@ function bootableRadio(item) {
|
|
|
202
230
|
$(item).prop('checked', true);
|
|
203
231
|
}
|
|
204
232
|
}
|
|
233
|
+
|
|
205
234
|
function clusterSelected(item) {
|
|
206
235
|
const cluster = $(item).val();
|
|
207
236
|
const url = $(item).data('url');
|
|
@@ -258,4 +287,4 @@ function vnicSelected(item) {
|
|
|
258
287
|
);
|
|
259
288
|
networkSelect.val(networkObj.id).trigger('change');
|
|
260
289
|
}
|
|
261
|
-
}
|
|
290
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ForemanOvirt
|
|
4
|
+
module ApiComputeResourcesControllerExtension
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
# rubocop:disable Rails/LexicallyScopedActionFilter
|
|
9
|
+
before_action :convert_datacenter_to_uuid, only: %i[create update]
|
|
10
|
+
# rubocop:enable Rails/LexicallyScopedActionFilter
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def convert_datacenter_to_uuid
|
|
16
|
+
datacenter = params[:compute_resource][:datacenter]
|
|
17
|
+
return if datacenter.blank? || Foreman.is_uuid?(datacenter)
|
|
18
|
+
|
|
19
|
+
case params[:action]
|
|
20
|
+
when 'create'
|
|
21
|
+
return unless compute_resource_params[:provider]&.downcase == 'ovirt'
|
|
22
|
+
@compute_resource = ComputeResource.new_provider(compute_resource_params.except(:datacenter))
|
|
23
|
+
when 'update'
|
|
24
|
+
return unless @compute_resource.is_a?(ForemanOvirt::Ovirt)
|
|
25
|
+
else
|
|
26
|
+
Rails.logger.error("Convert datacenter to UUID should not be called for action #{params[:action]}")
|
|
27
|
+
return
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
uuid = change_datacenter_to_uuid(datacenter)
|
|
31
|
+
params[:compute_resource][:datacenter] = uuid if uuid.present?
|
|
32
|
+
rescue Foreman::Exception => e
|
|
33
|
+
render_exception(e, status: :unprocessable_entity)
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def change_datacenter_to_uuid(datacenter)
|
|
38
|
+
@compute_resource.test_connection
|
|
39
|
+
@compute_resource.get_datacenter_uuid(datacenter)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ForemanOvirt
|
|
2
4
|
module ComputeResourcesVmsController
|
|
3
5
|
extend ActiveSupport::Concern
|
|
@@ -19,7 +21,7 @@ module ForemanOvirt
|
|
|
19
21
|
render partial: "compute_resources_vms/index/#{@compute_resource.provider.downcase}_json"
|
|
20
22
|
else
|
|
21
23
|
render json: _('JSON VM listing is not supported for this compute resource.'),
|
|
22
|
-
|
|
24
|
+
status: :not_implemented
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
end
|
|
@@ -23,11 +23,11 @@ module ForemanOvirt
|
|
|
23
23
|
compute_resource_params_filter_without_ovirt.tap do |filter|
|
|
24
24
|
# Now, add the oVirt specific parameters to the existing filter.
|
|
25
25
|
filter.permit :datacenter,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
:ovirt_quota,
|
|
27
|
+
:keyboard_layout,
|
|
28
|
+
:use_v4,
|
|
29
|
+
:public_key,
|
|
30
|
+
:uuid
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ForemanOvirt
|
|
2
4
|
module Concerns
|
|
3
5
|
module ComputeResourcesControllerExtensions
|
|
4
6
|
extend ActiveSupport::Concern
|
|
5
7
|
|
|
6
8
|
prepended do
|
|
7
|
-
|
|
9
|
+
# rubocop:disable Rails/LexicallyScopedActionFilter
|
|
10
|
+
before_action :change_datacenter_to_uuid, only: %i[create update]
|
|
11
|
+
# rubocop:enable Rails/LexicallyScopedActionFilter
|
|
8
12
|
rescue_from ::ProxyAPI::Ovirt::Unauthorized, with: :render_ovirt_unauthorized_error
|
|
9
13
|
end
|
|
10
14
|
|
|
@@ -38,7 +42,11 @@ module ForemanOvirt
|
|
|
38
42
|
private
|
|
39
43
|
|
|
40
44
|
def change_datacenter_to_uuid
|
|
41
|
-
|
|
45
|
+
unless params[:compute_resource] &&
|
|
46
|
+
params[:compute_resource][:provider] == 'Ovirt' &&
|
|
47
|
+
params[:compute_resource][:datacenter]
|
|
48
|
+
return
|
|
49
|
+
end
|
|
42
50
|
proxy = find_resource(params[:id]) if params[:id].present?
|
|
43
51
|
proxy ||= ::ProxyAPI::Ovirt.new(
|
|
44
52
|
url: params[:compute_resource][:url],
|
|
@@ -48,12 +56,13 @@ module ForemanOvirt
|
|
|
48
56
|
uuid = proxy.datacenter_uuid_by_name(params[:compute_resource][:datacenter])
|
|
49
57
|
params[:compute_resource][:datacenter] = uuid
|
|
50
58
|
rescue ::ProxyAPI::Ovirt::Unauthorized
|
|
59
|
+
# Do nothing, allow the process to continue or fail elsewhere
|
|
51
60
|
rescue Foreman::Exception => e
|
|
52
61
|
render_error e.message, status: :not_found
|
|
53
62
|
end
|
|
54
63
|
|
|
55
64
|
def render_ovirt_unauthorized_error
|
|
56
|
-
render_error
|
|
65
|
+
render_error '401 Unauthorized', status: :unauthorized
|
|
57
66
|
end
|
|
58
67
|
end
|
|
59
68
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module OvirtComputeResourceHelper
|
|
2
4
|
# Really counting vms is as expensive as loading them all, especially when
|
|
3
5
|
# a filter is in place. So we create a fake count to get table pagination to work.
|
|
@@ -6,21 +8,33 @@ module OvirtComputeResourceHelper
|
|
|
6
8
|
end
|
|
7
9
|
|
|
8
10
|
def ovirt_storage_domains_for_select(compute_resource)
|
|
9
|
-
compute_resource.storage_domains.map
|
|
11
|
+
compute_resource.storage_domains.map do |sd|
|
|
12
|
+
avail = sd.available.to_i / 1.gigabyte
|
|
13
|
+
used = sd.used.to_i / 1.gigabyte
|
|
14
|
+
OpenStruct.new({ id: sd.id,
|
|
15
|
+
label: "#{sd.name} (" + _('Available') + ": #{avail} GiB, " + _('Used') + ": #{used} GiB)" })
|
|
16
|
+
end
|
|
10
17
|
end
|
|
11
18
|
|
|
12
19
|
def ovirt_vms_data
|
|
13
20
|
data = @vms.map do |vm|
|
|
14
21
|
[
|
|
15
|
-
link_to_if_authorized(html_escape(vm.name),
|
|
22
|
+
link_to_if_authorized(html_escape(vm.name),
|
|
23
|
+
hash_for_compute_resource_vm_path(compute_resource_id: @compute_resource, id: vm.id).merge(
|
|
24
|
+
auth_object: @compute_resource, auth_action: 'view', authorizer: authorizer
|
|
25
|
+
)),
|
|
16
26
|
vm.cores,
|
|
17
27
|
number_to_human_size(vm.memory),
|
|
18
28
|
"<span #{vm_power_class(vm.ready?)}>#{vm_state(vm)}</span>",
|
|
19
29
|
action_buttons(vm_power_action(vm, authorizer),
|
|
20
30
|
vm_import_action(vm), vm_associate_link(vm),
|
|
21
|
-
display_delete_if_authorized(
|
|
31
|
+
display_delete_if_authorized(
|
|
32
|
+
hash_for_compute_resource_vm_path(compute_resource_id: @compute_resource, id: vm.id).merge(
|
|
33
|
+
auth_object: @compute_resource, authorizer: authorizer
|
|
34
|
+
)
|
|
35
|
+
)),
|
|
22
36
|
]
|
|
23
37
|
end
|
|
24
|
-
JSON.fast_generate(data).html_safe
|
|
38
|
+
JSON.fast_generate(data).html_safe # rubocop:disable Rails/OutputSafety
|
|
25
39
|
end
|
|
26
40
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FogExtensions
|
|
2
4
|
module Ovirt
|
|
3
5
|
module Server
|
|
@@ -22,7 +24,7 @@ module FogExtensions
|
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def poweroff
|
|
25
|
-
service.vm_action(:
|
|
27
|
+
service.vm_action(id: id, action: :shutdown)
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def reset
|
|
@@ -30,12 +32,19 @@ module FogExtensions
|
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def vm_description
|
|
33
|
-
|
|
35
|
+
format(
|
|
36
|
+
_('%<cores>s Cores and %<memory>s memory'), cores: cores, memory: number_to_human_size(memory.to_i)
|
|
37
|
+
)
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
def select_nic(fog_nics, nic)
|
|
37
|
-
nic_network = @service.list_networks(@attributes[:cluster]).detect
|
|
38
|
-
|
|
41
|
+
nic_network = @service.list_networks(@attributes[:cluster]).detect do |n|
|
|
42
|
+
n.name == nic.compute_attributes['network']
|
|
43
|
+
end.try(:id) || nic.compute_attributes['network']
|
|
44
|
+
# grab any nic on the same network
|
|
45
|
+
fog_nics.detect do |fn|
|
|
46
|
+
fn.network == nic_network
|
|
47
|
+
end
|
|
39
48
|
end
|
|
40
49
|
end
|
|
41
50
|
end
|