foreman_fog_proxmox 0.15.1 → 0.16.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/helpers/proxmox_compute_resources_helper.rb +1 -1
- data/app/helpers/proxmox_form_helper.rb +2 -2
- data/app/helpers/proxmox_vm_attrs_helper.rb +131 -0
- data/app/helpers/proxmox_vm_interfaces_helper.rb +3 -3
- data/app/helpers/proxmox_vm_volumes_helper.rb +3 -3
- data/app/models/concerns/fog_extensions/proxmox/node.rb +1 -1
- data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +3 -3
- data/app/models/foreman_fog_proxmox/proxmox_images.rb +5 -0
- data/app/models/foreman_fog_proxmox/proxmox_version.rb +1 -1
- data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +1 -1
- data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +1 -1
- data/app/overrides/compute_resources_vms/form/add_from_profile_to_compute_attributes_form.rb +8 -0
- data/app/overrides/compute_resources_vms/form/add_react_component_to_host.rb +25 -0
- data/app/overrides/compute_resources_vms/form/update_react_component_to_host_form.rb +25 -0
- data/app/views/compute_resources_vms/form/proxmox/_add_react_component_to_host_form.html.erb +5 -0
- data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +21 -21
- data/app/views/compute_resources_vms/form/proxmox/_update_react_component_to_host_form.html.erb +26 -0
- data/config/routes.rb +3 -3
- data/lib/foreman_fog_proxmox/version.rb +1 -1
- data/package.json +42 -0
- data/test/factories/proxmox_factory.rb +7 -7
- data/test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb +1 -1
- data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +6 -6
- data/webpack/components/GeneralTabContent.js +107 -0
- data/webpack/components/ProxmoxComputeSelectors.js +141 -0
- data/webpack/components/ProxmoxContainer/MountPoint.js +91 -0
- data/webpack/components/ProxmoxContainer/ProxmoxContainerHardware.js +85 -0
- data/webpack/components/ProxmoxContainer/ProxmoxContainerNetwork.js +179 -0
- data/webpack/components/ProxmoxContainer/ProxmoxContainerOptions.js +104 -0
- data/webpack/components/ProxmoxContainer/ProxmoxContainerStorage.js +194 -0
- data/webpack/components/ProxmoxContainer/components/NetworkInterface.js +193 -0
- data/webpack/components/ProxmoxServer/ProxmoxServerHardware.js +204 -0
- data/webpack/components/ProxmoxServer/ProxmoxServerNetwork.js +161 -0
- data/webpack/components/ProxmoxServer/ProxmoxServerOptions.js +105 -0
- data/webpack/components/ProxmoxServer/ProxmoxServerStorage.js +272 -0
- data/webpack/components/ProxmoxServer/components/CDRom.js +149 -0
- data/webpack/components/ProxmoxServer/components/CPUFlagsModal.js +88 -0
- data/webpack/components/ProxmoxServer/components/HardDisk.js +143 -0
- data/webpack/components/ProxmoxServer/components/NetworkInterface.js +150 -0
- data/webpack/components/ProxmoxStoragesUtils.js +50 -0
- data/webpack/components/ProxmoxVmType.js +256 -0
- data/webpack/components/ProxmoxVmUtils.js +62 -0
- data/webpack/components/common/FormInputs.js +143 -0
- data/webpack/global_index.js +15 -0
- data/webpack/index.js +7 -0
- metadata +49 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66a00f7786605946bb2388d497b7a2f512fb29fcf00a12f35bc7059e8b0825f4
|
4
|
+
data.tar.gz: 3e2bf00ae5430cad3c5927ba4636582cd78d83cefa7065088fa4458da638b173
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9534979808ea0e6ad262d696497189b3129e6594478601649d74d475ef1cee060898988e662d50db447f04257b6e6cdcfa6d2d144fea0ef498e66c3a899bd140
|
7
|
+
data.tar.gz: 981cfaa3815ce58182a465490541051b4a79612f0153e3419142bbf5e3c7e58c68b7758b2cac8eaa4bae31a428717d239315695b6847f2d1d207b04f26ff8a41
|
@@ -34,7 +34,7 @@ module ProxmoxComputeResourcesHelper
|
|
34
34
|
def cluster_nodes(compute_resource)
|
35
35
|
nodes = compute_resource.nodes ? compute_resource.nodes.collect(&:node) : []
|
36
36
|
rescue ::Foreman::Exception => e
|
37
|
-
|
37
|
+
[] if e.message == 'User token expired'
|
38
38
|
rescue StandardError => e
|
39
39
|
logger.warn("failed to get cluster nodes: #{e}")
|
40
40
|
raise e
|
@@ -30,7 +30,7 @@ module ProxmoxFormHelper
|
|
30
30
|
addClass options, 'form-control'
|
31
31
|
pass = f.password_field(attr, options) +
|
32
32
|
tag(:span, '', class: 'glyphicon glyphicon-warning-sign input-addon', title: 'Caps lock ON',
|
33
|
-
style: 'display:none')
|
33
|
+
style: 'display:none')
|
34
34
|
if unset_button
|
35
35
|
button = link_to_function(icon_text('edit', '', :kind => 'pficon'), 'toggle_input_group(this)',
|
36
36
|
:id => 'disable-pass-btn', :class => 'btn btn-default', :title => _('Change the password'))
|
@@ -56,7 +56,7 @@ style: 'display:none')
|
|
56
56
|
options[:form_builder_attrs] ||= {}
|
57
57
|
|
58
58
|
content_tag(:div, :class => "#{options[:type]}_#{association}_fields_template form_template",
|
59
|
-
:style => 'display: none;') do
|
59
|
+
:style => 'display: none;') do
|
60
60
|
form_builder.fields_for(association, options[:object],
|
61
61
|
:child_index => "new_#{options[:type]}_#{association}") do |f|
|
62
62
|
render(:partial => options[:partial], :layout => options[:layout],
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 Tristan Robert
|
4
|
+
|
5
|
+
# This file is part of ForemanFogProxmox.
|
6
|
+
|
7
|
+
# ForemanFogProxmox is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
|
12
|
+
# ForemanFogProxmox is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
require 'fog/proxmox/helpers/disk_helper'
|
21
|
+
require 'fog/proxmox/helpers/nic_helper'
|
22
|
+
require 'fog/proxmox/helpers/cpu_helper'
|
23
|
+
require 'foreman_fog_proxmox/value'
|
24
|
+
require 'foreman_fog_proxmox/hash_collection'
|
25
|
+
|
26
|
+
# Convert a foreman form server hash into a fog-proxmox server attributes hash
|
27
|
+
module ProxmoxVmAttrsHelper
|
28
|
+
def object_to_attributes_hash(vms, from_profile, start_checked)
|
29
|
+
param_scope = from_profile ? "compute_attribute[vm_attrs]" : "host[compute_attributes]"
|
30
|
+
vm_h = ActiveSupport::HashWithIndifferentAccess.new
|
31
|
+
keys = [:vmid, :node_id, :type, :pool]
|
32
|
+
main = vms.attributes.select { |key, _value| keys.include? key }
|
33
|
+
vms.config.all_attributes.each do |key, value|
|
34
|
+
camel_key = key.to_s.include?('_') ? snake_to_camel(key.to_s).to_sym : key
|
35
|
+
vm_h[camel_key] = { :name => "#{param_scope}[config_attributes][#{key}]", :value => value } unless keys.include? key
|
36
|
+
end
|
37
|
+
main.each do |key, value|
|
38
|
+
camel_key = key.to_s.include?('_') ? snake_to_camel(key.to_s).to_sym : key
|
39
|
+
vm_h[camel_key] = { :name => "#{param_scope}[#{key}]", :value => value } if keys.include? key
|
40
|
+
end
|
41
|
+
|
42
|
+
vm_h.merge!(additional_attrs(vms, param_scope, start_checked))
|
43
|
+
vm_h[:interfaces] = network_attrs(param_scope, vms.interfaces)
|
44
|
+
vm_h[:disks] = volumes_attrs(param_scope, vms.volumes)
|
45
|
+
vm_h.merge(cpu_flags_attrs(param_scope, vms.config))
|
46
|
+
end
|
47
|
+
|
48
|
+
def cpu_flags_attrs(param_scope, config)
|
49
|
+
flag_attrs = ActiveSupport::HashWithIndifferentAccess.new
|
50
|
+
Fog::Proxmox::CpuHelper.flags.each do |key, _val|
|
51
|
+
flag_attrs.merge!({ key => { :name => "#{param_scope}[config_attributes][#{key}]", :value => config.public_send(key) } })
|
52
|
+
end
|
53
|
+
flag_attrs
|
54
|
+
end
|
55
|
+
|
56
|
+
def volumes_attrs(param_scope, volumes)
|
57
|
+
vol_attrs = []
|
58
|
+
volumes.each_with_index do |vol, id|
|
59
|
+
keys = []
|
60
|
+
type = ""
|
61
|
+
if vol.rootfs?
|
62
|
+
keys = ['id', 'volid', 'storage', 'size', 'storage_type']
|
63
|
+
type = 'rootfs'
|
64
|
+
elsif vol.hard_disk?
|
65
|
+
keys = ['id', 'volid', 'storage_type', 'storage', 'controller', 'device', 'cache', 'size']
|
66
|
+
type = 'hard_disk'
|
67
|
+
elsif vol.cdrom?
|
68
|
+
keys = ['id', 'storage_type', 'cdrom', 'storage', 'volid']
|
69
|
+
type = 'cdrom'
|
70
|
+
elsif vol.cloud_init?
|
71
|
+
keys = ['id', 'volid', 'storage_type', 'storage', 'controller', 'device']
|
72
|
+
type = 'cloud_init'
|
73
|
+
elsif vol.mount_point?
|
74
|
+
keys = ['id', 'volid', 'storage_type', 'storage', 'device', 'mp', 'size']
|
75
|
+
type = 'mount_point'
|
76
|
+
end
|
77
|
+
vol_attrs << { :name => type, :value => vol_keys(param_scope, keys, vol, id) }
|
78
|
+
end
|
79
|
+
vol_attrs
|
80
|
+
end
|
81
|
+
|
82
|
+
def vol_keys(param_scope, keys, vol, id)
|
83
|
+
attrs = ActiveSupport::HashWithIndifferentAccess.new
|
84
|
+
keys.each do |key|
|
85
|
+
camel_key = key.to_s.include?('_') ? snake_to_camel(key.to_s).to_sym : key
|
86
|
+
attrs[camel_key] = { :name => "#{param_scope}[volumes_attributes][#{id}][#{key}]", :value => vol.public_send(key) }
|
87
|
+
end
|
88
|
+
attrs
|
89
|
+
end
|
90
|
+
|
91
|
+
def network_attrs(param_scope, interfaces)
|
92
|
+
networks_attrs = []
|
93
|
+
interfaces.each_with_index do |interface, id|
|
94
|
+
attrs = ActiveSupport::HashWithIndifferentAccess.new
|
95
|
+
interface.all_attributes.each do |key, value|
|
96
|
+
camel_key = key.to_s.include?('_') ? snake_to_camel(key.to_s).to_sym : key
|
97
|
+
attrs[camel_key] = { :name => "#{param_scope}[interfaces_attributes][#{id}][#{key}]", :value => value }
|
98
|
+
end
|
99
|
+
networks_attrs << { :name => 'interface', :value => attrs }
|
100
|
+
end
|
101
|
+
networks_attrs
|
102
|
+
end
|
103
|
+
|
104
|
+
def additional_attrs(vms, param_scope, start_checked)
|
105
|
+
attributes = {
|
106
|
+
pool: vms.pool,
|
107
|
+
image_id: vms.image_id,
|
108
|
+
cpu_type: vms.config.cpu_type,
|
109
|
+
nameserver: vms.config.nameserver,
|
110
|
+
searchdomain: vms.config.searchdomain,
|
111
|
+
hostname: vms.config.hostname,
|
112
|
+
ostemplate_storage: vms.ostemplate_storage,
|
113
|
+
ostemplate_file: vms.ostemplate_file,
|
114
|
+
start_after_create: vms.start_after_create,
|
115
|
+
templated: vms.templated,
|
116
|
+
}
|
117
|
+
vms_keys = [:pool, :start_after_create]
|
118
|
+
extra_attrs = ActiveSupport::HashWithIndifferentAccess.new
|
119
|
+
attributes.each do |key, value|
|
120
|
+
camel_key = key.to_s.include?('_') ? snake_to_camel(key.to_s).to_sym : key
|
121
|
+
nested_key = vms_keys.include?(key) ? key : "config_attributes[#{key}]"
|
122
|
+
value = start_checked if key == :start_after_create
|
123
|
+
extra_attrs[camel_key] = { name: "#{param_scope}[#{nested_key}]", value: value }
|
124
|
+
end
|
125
|
+
extra_attrs
|
126
|
+
end
|
127
|
+
|
128
|
+
def snake_to_camel(str)
|
129
|
+
str.split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
130
|
+
end
|
131
|
+
end
|
@@ -56,13 +56,13 @@ module ProxmoxVmInterfacesHelper
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def interface_common_typed_keys(type)
|
59
|
-
['id', type == 'qemu' ? 'macaddr' : 'hwaddr']
|
59
|
+
['id', (type == 'qemu') ? 'macaddr' : 'hwaddr']
|
60
60
|
end
|
61
61
|
|
62
62
|
def compute_dhcps(interface_attributes_h)
|
63
|
-
interface_attributes_h[:dhcp] = interface_attributes_h[:ip] == 'dhcp' ? '1' : '0'
|
63
|
+
interface_attributes_h[:dhcp] = (interface_attributes_h[:ip] == 'dhcp') ? '1' : '0'
|
64
64
|
interface_attributes_h[:ip] = '' if interface_attributes_h[:dhcp] == '1'
|
65
|
-
interface_attributes_h[:dhcp6] = interface_attributes_h[:ip6] == 'dhcp' ? '1' : '0'
|
65
|
+
interface_attributes_h[:dhcp6] = (interface_attributes_h[:ip6] == 'dhcp') ? '1' : '0'
|
66
66
|
interface_attributes_h[:ip6] = '' if interface_attributes_h[:dhcp6] == '1'
|
67
67
|
end
|
68
68
|
|
@@ -52,9 +52,9 @@ module ProxmoxVmVolumesHelper
|
|
52
52
|
logger.debug(format(_('parse_hard_disk_volume(): args=%<args>s'), args: args))
|
53
53
|
disk = {}
|
54
54
|
disk[:id] = args['id'] if args.key?('id')
|
55
|
-
disk[:volid] = args['volid'] if args.key?('volid')
|
56
|
-
disk[:storage] = args['storage'].to_s if args.key?('storage')
|
57
|
-
disk[:size] = args['size'].to_i if args.key?('size')
|
55
|
+
disk[:volid] = args['volid'] if args.key?('volid') && !args['volid'].empty?
|
56
|
+
disk[:storage] = args['storage'].to_s if args.key?('storage') && !args['storage'].empty?
|
57
|
+
disk[:size] = args['size'].to_i if args.key?('size') && !args['size'].empty?
|
58
58
|
add_disk_options(disk, args) unless args.key?('options')
|
59
59
|
disk[:options] = args['options'] if args.key?('options')
|
60
60
|
disk.key?(:storage) ? disk : {}
|
@@ -31,7 +31,7 @@ module FogExtensions
|
|
31
31
|
# We need to explicitly use the base 'each' method here on the page,
|
32
32
|
# otherwise we get infinite recursion
|
33
33
|
base_each = Fog::Collection.instance_method(:each)
|
34
|
-
base_each.
|
34
|
+
base_each.bind_call(page, &block)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
self
|
@@ -30,7 +30,7 @@ module ForemanFogProxmox
|
|
30
30
|
unless compute_os_types(host).include?(ostype)
|
31
31
|
raise ::Foreman::Exception,
|
32
32
|
format(_('Operating system family %<type>s is not consistent with %<ostype>s'), type: host.operatingsystem.type,
|
33
|
-
ostype: ostype)
|
33
|
+
ostype: ostype)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
super
|
@@ -42,8 +42,8 @@ ostype: ostype)
|
|
42
42
|
|
43
43
|
def interface_compute_attributes(interface_attributes)
|
44
44
|
vm_attrs = ForemanFogProxmox::HashCollection.new_hash_reject_keys(interface_attributes, [:identifier, :macaddr, :hwaddr])
|
45
|
-
vm_attrs[:dhcp] = interface_attributes[:ip] == 'dhcp' ? '1' : '0'
|
46
|
-
vm_attrs[:dhcp6] = interface_attributes[:ip6] == 'dhcp' ? '1' : '0'
|
45
|
+
vm_attrs[:dhcp] = (interface_attributes[:ip] == 'dhcp') ? '1' : '0'
|
46
|
+
vm_attrs[:dhcp6] = (interface_attributes[:ip6] == 'dhcp') ? '1' : '0'
|
47
47
|
vm_attrs
|
48
48
|
end
|
49
49
|
|
@@ -48,9 +48,14 @@ module ForemanFogProxmox
|
|
48
48
|
volumes = []
|
49
49
|
nodes.each do |node|
|
50
50
|
storages(node.node).each do |storage|
|
51
|
+
# fetches volumes of QEMU servers for images
|
51
52
|
volumes += storage.volumes.list_by_content_type('images')
|
53
|
+
|
54
|
+
# fetches volumes of KVM containers for images
|
55
|
+
volumes += storage.volumes.list_by_content_type('rootdir')
|
52
56
|
end
|
53
57
|
end
|
58
|
+
# for creating image, only list volumes which are templated
|
54
59
|
volumes.select(&:template?)
|
55
60
|
end
|
56
61
|
|
@@ -36,7 +36,7 @@ module ForemanFogProxmox
|
|
36
36
|
v = identity_client.read_version if identity_client
|
37
37
|
v ? v['version'] : 'Unknown'
|
38
38
|
rescue ::Foreman::Exception => e
|
39
|
-
|
39
|
+
'Unkown' if e.message == 'User token expired'
|
40
40
|
rescue StandardError => e
|
41
41
|
logger.warn("failed to get identity client version: #{e}")
|
42
42
|
raise e
|
@@ -191,7 +191,7 @@ module ForemanFogProxmox
|
|
191
191
|
new_attr_type ||= type
|
192
192
|
logger.debug("new_typed_vm(#{type}): new_attr_type=#{new_attr_type}")
|
193
193
|
logger.debug("new_typed_vm(#{type}): new_attr=#{new_attr}'")
|
194
|
-
options = !new_attr.key?('vmid') || ForemanFogProxmox::Value.empty?(new_attr['vmid']) ? vm_typed_instance_defaults(type).merge(new_attr).merge(type: type) : new_attr
|
194
|
+
options = (!new_attr.key?('vmid') || ForemanFogProxmox::Value.empty?(new_attr['vmid'])) ? vm_typed_instance_defaults(type).merge(new_attr).merge(type: type) : new_attr
|
195
195
|
logger.debug("new_typed_vm(#{type}): options=#{options}")
|
196
196
|
vm_h = parse_typed_vm(options, type).deep_symbolize_keys
|
197
197
|
logger.debug("new_typed_vm(#{type}): vm_h=#{vm_h}")
|
data/app/overrides/compute_resources_vms/form/add_from_profile_to_compute_attributes_form.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2018 Tristan Robert
|
2
4
|
|
3
5
|
# This file is part of ForemanFogProxmox.
|
@@ -15,6 +17,12 @@
|
|
15
17
|
# You should have received a copy of the GNU General Public License
|
16
18
|
# along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
|
17
19
|
|
20
|
+
Deface::Override.new(
|
21
|
+
virtual_path: 'compute_attributes/_compute_form',
|
22
|
+
name: 'remove_networks_and_volumes_partial',
|
23
|
+
remove: "erb[loud]:contains('compute_resources_vms/form/networks'), erb[loud]:contains('compute_resources_vms/form/volumes')"
|
24
|
+
)
|
25
|
+
|
18
26
|
Deface::Override.new(
|
19
27
|
:virtual_path => 'compute_attributes/_form',
|
20
28
|
:name => 'add_from_profile_to_compute_attributes_form',
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 Tristan Robert
|
4
|
+
|
5
|
+
# This file is part of ForemanFogProxmox.
|
6
|
+
|
7
|
+
# ForemanFogProxmox is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
|
12
|
+
# ForemanFogProxmox is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
Deface::Override.new(
|
21
|
+
virtual_path: 'hosts/_form',
|
22
|
+
name: 'add_react_component_to_virtual_machine_tab',
|
23
|
+
insert_after: "li.active",
|
24
|
+
partial: 'compute_resources_vms/form/proxmox/add_react_component_to_host_form'
|
25
|
+
)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2018 Tristan Robert
|
4
|
+
|
5
|
+
# This file is part of ForemanFogProxmox.
|
6
|
+
|
7
|
+
# ForemanFogProxmox is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
|
12
|
+
# ForemanFogProxmox is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
Deface::Override.new(
|
21
|
+
:virtual_path => 'hosts/_compute',
|
22
|
+
:name => 'update_react_component_to_virtual_machine_tab',
|
23
|
+
:replace => "erb[loud]:contains('hosts/compute_detail')",
|
24
|
+
:partial => 'compute_resources_vms/form/proxmox/update_react_component_to_host_form'
|
25
|
+
)
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<% content_for(:javascripts) do %>
|
2
|
+
<%= webpacked_plugins_js_for :foreman_fog_proxmox %>
|
3
|
+
<%= javascript_include_tag 'foreman_fog_proxmox/proxmox_vm', "data-turbolinks-track" => true %>
|
4
|
+
<% end %>
|
5
|
+
<%= react_component('ProxmoxVmType', { registerComp: true }) unless @host.managed %>
|
@@ -14,25 +14,25 @@ GNU General Public License for more details.
|
|
14
14
|
|
15
15
|
You should have received a copy of the GNU General Public License
|
16
16
|
along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
17
|
+
<% nodes = compute_resource.nodes %>
|
18
|
+
<% unless local_assigns[:hide_image] && !new_vm %>
|
19
|
+
<%
|
20
|
+
arch ||= nil ; os ||= nil
|
21
|
+
images = possible_images(compute_resource, arch, os)
|
22
|
+
-%>
|
23
|
+
<div id='image_selection'>
|
24
|
+
<%= select_f f, :image_id, images, :uuid, :name, { :include_blank => true },
|
25
|
+
:disabled => true,
|
26
|
+
:help_inline => :indicator,
|
27
|
+
:class => ('hide' if from_profile),
|
28
|
+
:label => _('Image'),
|
29
|
+
:no_label => from_profile,
|
30
|
+
:label_size => "col-md-2" %>
|
31
|
+
</div>
|
32
|
+
<% end %>
|
33
|
+
<% untemplatable = new_vm || f.object.templated? %>
|
34
|
+
<% checked = params[:host] && params[:host][:compute_attributes] && params[:host][:compute_attributes][:start_after_create] || '1' %>
|
35
|
+
<% content_for(:javascripts) do %>
|
36
|
+
<%= webpacked_plugins_js_for :foreman_fog_proxmox %>
|
35
37
|
<% end %>
|
36
|
-
<%= f.
|
37
|
-
<%= render :partial => "compute_resources_vms/form/proxmox/container/config", :locals => { :f => container_config, :compute_resource => compute_resource, :host => @host, :new_vm => new_vm, :item_layout => 'removable', :type => f.object.type, :node_id => f.object.node_id } %>
|
38
|
-
<% end %>
|
38
|
+
<%= react_component('ProxmoxVmType', { vmAttrs: object_to_attributes_hash(f.object, from_profile, checked), nodes: nodes.as_json, images: images.as_json, pools: compute_resource.pools.as_json, storages: compute_resource.storages.as_json, fromProfile: from_profile, newVm: new_vm, bridges: compute_resource.bridges.as_json, untemplatable: untemplatable }) %>
|
data/app/views/compute_resources_vms/form/proxmox/_update_react_component_to_host_form.html.erb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
<%# Copyright 2018 Tristan Robert
|
2
|
+
|
3
|
+
This file is part of ForemanFogProxmox.
|
4
|
+
|
5
|
+
ForemanFogProxmox is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
ForemanFogProxmox is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
|
17
|
+
|
18
|
+
<% if compute_resource.class == ForemanFogProxmox::Proxmox %>
|
19
|
+
<%= render :partial => provider_partial(compute_resource, 'base'),
|
20
|
+
locals: { f: compute, host: host, compute_resource: compute_resource, new_host: host.new_record?, new_vm: !compute.object.persisted?,
|
21
|
+
arch: host.architecture_id, os: host.operatingsystem_id, from_profile: false } %>
|
22
|
+
<% else %>
|
23
|
+
<%= render :partial => provider_partial(compute_resource, 'base'),
|
24
|
+
locals: { f: compute, host: host, compute_resource: compute_resource, new_host: host.new_record?, new_vm: !compute.object.persisted?,
|
25
|
+
arch: host.architecture_id, os: host.operatingsystem_id } %>
|
26
|
+
<% end %>
|
data/config/routes.rb
CHANGED
@@ -20,15 +20,15 @@
|
|
20
20
|
Rails.application.routes.draw do
|
21
21
|
namespace :foreman_fog_proxmox do
|
22
22
|
match 'isos/:compute_resource_id/:node_id/:storage', :to => 'compute_resources#isos_by_id_and_node_and_storage',
|
23
|
-
:via => 'get'
|
23
|
+
:via => 'get'
|
24
24
|
match 'ostemplates/:compute_resource_id/:node_id/:storage',
|
25
25
|
:to => 'compute_resources#ostemplates_by_id_and_node_and_storage', :via => 'get'
|
26
26
|
match 'isos/:compute_resource_id/:node_id', :to => 'compute_resources#isos_by_id_and_node', :via => 'get'
|
27
27
|
match 'ostemplates/:compute_resource_id/:node_id', :to => 'compute_resources#ostemplates_by_id_and_node',
|
28
|
-
:via => 'get'
|
28
|
+
:via => 'get'
|
29
29
|
match 'storages/:compute_resource_id/:node_id', :to => 'compute_resources#storages_by_id_and_node', :via => 'get'
|
30
30
|
match 'isostorages/:compute_resource_id/:node_id', :to => 'compute_resources#iso_storages_by_id_and_node',
|
31
|
-
:via => 'get'
|
31
|
+
:via => 'get'
|
32
32
|
match 'bridges/:compute_resource_id/:node_id', :to => 'compute_resources#bridges_by_id_and_node', :via => 'get'
|
33
33
|
end
|
34
34
|
end
|
data/package.json
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
{
|
2
|
+
"name": "foreman_fog_proxmox",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "DESCRIPTION",
|
5
|
+
"main": "index.js",
|
6
|
+
"scripts": {
|
7
|
+
"lint": "tfm-lint --plugin -d webpack",
|
8
|
+
"test": "tfm-test --config jest.config.js",
|
9
|
+
"test:watch": "tfm-test --plugin --watchAll",
|
10
|
+
"test:current": "tfm-test --plugin --watch",
|
11
|
+
"publish-coverage": "tfm-publish-coverage",
|
12
|
+
"stories": "tfm-stories --plugin",
|
13
|
+
"stories:build": "tfm-build-stories --plugin",
|
14
|
+
"create-react-component": "yo react-domain"
|
15
|
+
},
|
16
|
+
"repository": {
|
17
|
+
"type": "git",
|
18
|
+
"url": "git+https://github.com/theforeman/foreman_fog_proxmox.git"
|
19
|
+
},
|
20
|
+
"bugs": {
|
21
|
+
"url": "http://projects.theforeman.org/projects/foreman_fog_proxmox/issues"
|
22
|
+
},
|
23
|
+
"peerDependencies": {
|
24
|
+
"@theforeman/vendor": "^12.0.1"
|
25
|
+
},
|
26
|
+
"dependencies": {
|
27
|
+
"react-intl": "^2.8.0"
|
28
|
+
},
|
29
|
+
"devDependencies": {
|
30
|
+
"@babel/core": "^7.7.0",
|
31
|
+
"@testing-library/react": "^10.4.9",
|
32
|
+
"@theforeman/builder": ">=12.0.1",
|
33
|
+
"@theforeman/eslint-plugin-foreman": ">=12.0.1",
|
34
|
+
"@theforeman/find-foreman": ">=12.0.1",
|
35
|
+
"@theforeman/test": ">=12.0.1",
|
36
|
+
"@theforeman/vendor-dev": ">=12.0.1",
|
37
|
+
"babel-eslint": "^10.0.3",
|
38
|
+
"eslint": "^6.7.2",
|
39
|
+
"prettier": "^1.19.1",
|
40
|
+
"react-redux-test-utils": "^0.2.0"
|
41
|
+
}
|
42
|
+
}
|
@@ -20,7 +20,7 @@
|
|
20
20
|
require 'fog/proxmox/compute/models/node'
|
21
21
|
|
22
22
|
FactoryBot.define do
|
23
|
-
factory :proxmox_resource, :class => ComputeResource do
|
23
|
+
factory :proxmox_resource, :class => 'ComputeResource' do
|
24
24
|
sequence(:name) { |n| "compute_resource#{n}" }
|
25
25
|
organizations { [Organization.find_by(name: 'Organization 1')] }
|
26
26
|
locations { [Location.find_by(name: 'Location 1')] }
|
@@ -32,10 +32,10 @@ FactoryBot.define do
|
|
32
32
|
url { 'https://192.168.56.101:8006/api2/json' }
|
33
33
|
end
|
34
34
|
|
35
|
-
factory :proxmox_cr, :class => ForemanFogProxmox::Proxmox, :traits => [:proxmox]
|
35
|
+
factory :proxmox_cr, :class => 'ForemanFogProxmox::Proxmox', :traits => [:proxmox]
|
36
36
|
end
|
37
37
|
|
38
|
-
factory :node, :class => Fog::Proxmox::Compute::Node do
|
38
|
+
factory :node, :class => 'Fog::Proxmox::Compute::Node' do
|
39
39
|
sequence(:identity) { |n| "node#{n}" }
|
40
40
|
trait :proxmox do
|
41
41
|
identity { 'proxmox' }
|
@@ -43,7 +43,7 @@ FactoryBot.define do
|
|
43
43
|
trait :service do
|
44
44
|
service { :proxmox_cr }
|
45
45
|
end
|
46
|
-
factory :proxmox_node, :class => Fog::Proxmox::Compute::Node, :traits => [:proxmox, :service]
|
46
|
+
factory :proxmox_node, :class => 'Fog::Proxmox::Compute::Node', :traits => [:proxmox, :service]
|
47
47
|
end
|
48
48
|
|
49
49
|
def deferred_nic_attrs
|
@@ -59,16 +59,16 @@ FactoryBot.define do
|
|
59
59
|
host
|
60
60
|
end
|
61
61
|
|
62
|
-
factory :nic_base_empty, :class => Nic::Base do
|
62
|
+
factory :nic_base_empty, :class => 'Nic::Base' do
|
63
63
|
type { 'Nic::Base' }
|
64
64
|
end
|
65
65
|
|
66
|
-
factory :nic_managed_empty, :class => Nic::Managed, :parent => :nic_base_empty do
|
66
|
+
factory :nic_managed_empty, :class => 'Nic::Managed', :parent => :nic_base_empty do
|
67
67
|
type { 'Nic::Managed' }
|
68
68
|
identifier { 'net0' }
|
69
69
|
end
|
70
70
|
|
71
|
-
factory :host_empty, :class => Host do
|
71
|
+
factory :host_empty, :class => 'Host' do
|
72
72
|
sequence(:name) { |n| "host#{n}" }
|
73
73
|
sequence(:hostname) { |n| "host#{n}" }
|
74
74
|
trait :compute_attributes do
|
@@ -62,7 +62,7 @@ module ForemanFogProxmox
|
|
62
62
|
|
63
63
|
it 'sets container hostname with host name' do
|
64
64
|
physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :primary => true,
|
65
|
-
:compute_attributes => { 'dhcp' => '1', 'dhcp6' => '1' })
|
65
|
+
:compute_attributes => { 'dhcp' => '1', 'dhcp6' => '1' })
|
66
66
|
host = FactoryBot.build(
|
67
67
|
:host_empty,
|
68
68
|
:interfaces => [physical_nic],
|
@@ -40,7 +40,7 @@ module ForemanFogProxmox
|
|
40
40
|
it 'raises Foreman::Exception when server proxmox NIC id does not match net[k] with k integer' do
|
41
41
|
compute_attributes = ActiveSupport::HashWithIndifferentAccess.new({ 'id' => 'dsfqsfqzef' })
|
42
42
|
physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'eth0',
|
43
|
-
:compute_attributes => compute_attributes)
|
43
|
+
:compute_attributes => compute_attributes)
|
44
44
|
host = FactoryBot.build(
|
45
45
|
:host_empty,
|
46
46
|
:interfaces => [physical_nic],
|
@@ -58,7 +58,7 @@ module ForemanFogProxmox
|
|
58
58
|
ip6 = Array.new(4) { format('%<x>s', x: rand(16**4)) }.join(':') + '::1'
|
59
59
|
compute_attributes = ActiveSupport::HashWithIndifferentAccess.new({ 'id' => 'net0' })
|
60
60
|
physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6,
|
61
|
-
:mac => mac_address, :compute_attributes => compute_attributes)
|
61
|
+
:mac => mac_address, :compute_attributes => compute_attributes)
|
62
62
|
host = FactoryBot.build(
|
63
63
|
:host_empty,
|
64
64
|
:interfaces => [physical_nic],
|
@@ -75,7 +75,7 @@ module ForemanFogProxmox
|
|
75
75
|
it 'raises Foreman::Exception when container proxmox NIC id does not match net[k] with k integer' do
|
76
76
|
compute_attributes = ActiveSupport::HashWithIndifferentAccess.new({ 'id' => 'dsfqsfqzef' })
|
77
77
|
physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'eth0',
|
78
|
-
:compute_attributes => compute_attributes)
|
78
|
+
:compute_attributes => compute_attributes)
|
79
79
|
host = FactoryBot.build(
|
80
80
|
:host_empty,
|
81
81
|
:interfaces => [physical_nic],
|
@@ -94,7 +94,7 @@ module ForemanFogProxmox
|
|
94
94
|
compute_attributes = ActiveSupport::HashWithIndifferentAccess.new({ 'id' => 'net0', 'cidr' => cidr, 'gw' => ip,
|
95
95
|
'ip' => ip, 'dhcp6' => '1' })
|
96
96
|
physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6,
|
97
|
-
:compute_attributes => compute_attributes)
|
97
|
+
:compute_attributes => compute_attributes)
|
98
98
|
host = FactoryBot.build(
|
99
99
|
:host_empty,
|
100
100
|
:interfaces => [physical_nic],
|
@@ -115,7 +115,7 @@ module ForemanFogProxmox
|
|
115
115
|
compute_attributes = ActiveSupport::HashWithIndifferentAccess.new({ 'id' => 'net0', 'cidr6' => cidr6,
|
116
116
|
'dhcp' => '1', 'gw6' => ip6 })
|
117
117
|
physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6,
|
118
|
-
:compute_attributes => compute_attributes)
|
118
|
+
:compute_attributes => compute_attributes)
|
119
119
|
host = FactoryBot.build(
|
120
120
|
:host_empty,
|
121
121
|
:interfaces => [physical_nic],
|
@@ -137,7 +137,7 @@ module ForemanFogProxmox
|
|
137
137
|
compute_attributes = ActiveSupport::HashWithIndifferentAccess.new({ 'id' => 'net0', 'dhcp' => '1',
|
138
138
|
'ip6' => ip6, 'firewall' => firewall })
|
139
139
|
physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6,
|
140
|
-
:mac => mac_address, :compute_attributes => compute_attributes)
|
140
|
+
:mac => mac_address, :compute_attributes => compute_attributes)
|
141
141
|
host = FactoryBot.build(
|
142
142
|
:host_empty,
|
143
143
|
:interfaces => [physical_nic],
|