foreman_fog_proxmox 0.12.4 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of foreman_fog_proxmox might be problematic. Click here for more details.

Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_compute_resource.js +24 -2
  4. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm.js +124 -52
  5. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +0 -48
  6. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume.js +39 -0
  7. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume_cdrom.js +63 -0
  8. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume_cloudinit.js +25 -0
  9. data/app/controllers/concerns/foreman_fog_proxmox/controller/parameters/compute_resource.rb +1 -1
  10. data/app/helpers/proxmox_compute_controllers_helper.rb +39 -0
  11. data/app/helpers/proxmox_compute_resources_helper.rb +49 -0
  12. data/app/helpers/proxmox_compute_selectors_helper.rb +6 -44
  13. data/app/helpers/proxmox_form_helper.rb +12 -4
  14. data/app/{models/concerns/fog_extensions/proxmox/volume.rb → helpers/proxmox_storages_helper.rb} +5 -8
  15. data/app/{models/foreman_fog_proxmox/proxmox_token_expiration.rb → helpers/proxmox_vm_cdrom_helper.rb} +15 -10
  16. data/app/helpers/proxmox_vm_cloudinit_helper.rb +43 -0
  17. data/app/helpers/proxmox_vm_config_helper.rb +159 -0
  18. data/app/helpers/proxmox_vm_helper.rb +24 -62
  19. data/app/helpers/proxmox_vm_interfaces_helper.rb +85 -0
  20. data/app/helpers/proxmox_vm_os_template_helper.rb +47 -0
  21. data/app/helpers/proxmox_vm_volumes_helper.rb +105 -0
  22. data/app/models/concerns/fog_extensions/proxmox/disk.rb +17 -2
  23. data/app/models/concerns/fog_extensions/proxmox/interface.rb +19 -4
  24. data/app/models/concerns/fog_extensions/proxmox/server.rb +8 -3
  25. data/app/models/concerns/fog_extensions/proxmox/server_config.rb +8 -30
  26. data/app/models/concerns/host_ext/proxmox/interfaces.rb +7 -2
  27. data/app/models/concerns/orchestration/proxmox/compute.rb +1 -0
  28. data/app/models/foreman_fog_proxmox/proxmox.rb +58 -15
  29. data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +13 -18
  30. data/app/models/foreman_fog_proxmox/proxmox_connection.rb +14 -9
  31. data/app/models/foreman_fog_proxmox/proxmox_images.rb +2 -1
  32. data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +53 -28
  33. data/app/models/foreman_fog_proxmox/proxmox_operating_systems.rb +1 -1
  34. data/app/models/foreman_fog_proxmox/proxmox_version.rb +7 -2
  35. data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +18 -30
  36. data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +108 -94
  37. data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +2 -1
  38. data/app/models/foreman_fog_proxmox/proxmox_volumes.rb +79 -22
  39. data/app/views/compute_resources/form/_proxmox.html.erb +23 -10
  40. data/app/views/compute_resources/show/_proxmox.html.erb +6 -6
  41. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_nic_provider_specific_form.html.erb +3 -1
  42. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_volumes_edit.html.erb +46 -29
  43. data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +3 -3
  44. data/app/views/compute_resources_vms/form/proxmox/_removable_layout.html.erb +2 -1
  45. data/app/views/compute_resources_vms/form/proxmox/container/_network.html.erb +8 -7
  46. data/app/views/compute_resources_vms/form/proxmox/server/_advanced.html.erb +0 -2
  47. data/app/views/compute_resources_vms/form/proxmox/server/_config.html.erb +15 -14
  48. data/app/views/compute_resources_vms/form/proxmox/server/_network.html.erb +2 -2
  49. data/app/views/compute_resources_vms/form/proxmox/server/_volume_cdrom.html.erb +34 -0
  50. data/app/views/compute_resources_vms/form/proxmox/server/_volume_cloud_init.html.erb +29 -0
  51. data/app/views/compute_resources_vms/form/proxmox/server/{_volume.html.erb → _volume_hard_disk.html.erb} +7 -3
  52. data/app/views/compute_resources_vms/show/_proxmox.html.erb +2 -0
  53. data/lib/foreman_fog_proxmox/engine.rb +7 -8
  54. data/lib/foreman_fog_proxmox/hash_collection.rb +69 -0
  55. data/lib/foreman_fog_proxmox/version.rb +1 -1
  56. data/lib/tasks/foreman_fog_proxmox_tasks.rake +0 -3
  57. data/test/factories/foreman_fog_proxmox/proxmox_container_mock_factory.rb +20 -8
  58. data/test/factories/foreman_fog_proxmox/proxmox_node_mock_factory.rb +5 -5
  59. data/test/factories/foreman_fog_proxmox/proxmox_server_mock_factory.rb +17 -7
  60. data/test/factories/proxmox_factory.rb +4 -4
  61. data/test/functional/compute_resources_controller_test.rb +4 -4
  62. data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +49 -29
  63. data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +53 -30
  64. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +22 -20
  65. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_volumes_helper_test.rb +50 -0
  66. data/test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb +10 -11
  67. data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +38 -10
  68. data/test/unit/foreman_fog_proxmox/proxmox_version_test.rb +10 -10
  69. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb +34 -24
  70. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_create_test.rb +8 -8
  71. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cdrom_test.rb +181 -0
  72. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cloudinit_test.rb +131 -0
  73. data/test/unit/foreman_fog_proxmox/{proxmox_vm_commands_server_update_volumes_test.rb → proxmox_vm_commands_server_update_hard_disk_test.rb} +45 -19
  74. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb +21 -21
  75. data/test/unit/foreman_fog_proxmox/proxmox_vm_new_test.rb +3 -3
  76. metadata +40 -23
  77. data/app/helpers/proxmox_container_helper.rb +0 -163
  78. data/app/helpers/proxmox_server_helper.rb +0 -155
@@ -27,7 +27,7 @@ module ForemanFogProxmox
27
27
  def compute_resource_params_filter
28
28
  super.tap do |filter|
29
29
  filter.permit :ssl_verify_peer,
30
- :ssl_certs, :disable_proxy, :cr_id, :renew
30
+ :ssl_certs, :disable_proxy, :auth_method, :token_id, :token
31
31
  end
32
32
  end
33
33
 
@@ -0,0 +1,39 @@
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
+ module ProxmoxComputeControllersHelper
21
+ def proxmox_controllers_map
22
+ proxmox_controllers_cloudinit_map << ForemanFogProxmox::OptionsSelect.new(name: 'VirtIO Block', id: 'virtio', range: 15)
23
+ end
24
+
25
+ def proxmox_controllers_cloudinit_map
26
+ [ForemanFogProxmox::OptionsSelect.new(id: 'ide', name: 'IDE', range: 3),
27
+ ForemanFogProxmox::OptionsSelect.new(id: 'sata', name: 'SATA', range: 5),
28
+ ForemanFogProxmox::OptionsSelect.new(id: 'scsi', name: 'SCSI', range: 13)]
29
+ end
30
+
31
+ def proxmox_scsi_controllers_map
32
+ [OpenStruct.new(id: 'lsi', name: 'LSI 53C895A (Default)'),
33
+ OpenStruct.new(id: 'lsi53c810', name: 'LSI 53C810'),
34
+ OpenStruct.new(id: 'virtio-scsi-pci', name: 'VirtIO SCSI'),
35
+ OpenStruct.new(id: 'virtio-scsi-single', name: 'VirtIO SCSI Single'),
36
+ OpenStruct.new(id: 'megasas', name: 'MegaRAID SAS 8708EM2'),
37
+ OpenStruct.new(id: 'pvscsi', name: 'VMware PVSCSI')]
38
+ end
39
+ end
@@ -0,0 +1,49 @@
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
+ module ProxmoxComputeResourcesHelper
21
+ def user_token_expiration_date(compute_resource)
22
+ expire = compute_resource.current_user_token_expire
23
+ rescue ::Foreman::Exception => e
24
+ return 'Has already expired. Please edit the compute resource to set a new valid one.' if e.message == 'User token expired'
25
+ rescue StandardError => e
26
+ logger.warn(format(_('failed to get identity client version: %<e>s'), e: e))
27
+ raise e
28
+ else
29
+ return 'Never' if expire == 0
30
+
31
+ Time.at(expire).utc
32
+ end
33
+
34
+ def cluster_nodes(compute_resource)
35
+ nodes = compute_resource.nodes ? compute_resource.nodes.collect(&:node) : []
36
+ rescue ::Foreman::Exception => e
37
+ return [] if e.message == 'User token expired'
38
+ rescue StandardError => e
39
+ logger.warn(format(_('failed to get cluster nodes: %<e>s'), e: e))
40
+ raise e
41
+ else
42
+ nodes
43
+ end
44
+
45
+ def proxmox_auth_methods_map
46
+ [OpenStruct.new(id: 'access_ticket', name: '(Default) Access ticket'),
47
+ OpenStruct.new(id: 'user_token', name: 'User token')]
48
+ end
49
+ end
@@ -40,22 +40,6 @@ module ProxmoxComputeSelectorsHelper
40
40
  OpenStruct.new(id: 'unmanaged', name: 'Unmanaged')]
41
41
  end
42
42
 
43
- def proxmox_controllers_map
44
- [ForemanFogProxmox::OptionsSelect.new(id: 'ide', name: 'IDE', range: 3),
45
- ForemanFogProxmox::OptionsSelect.new(id: 'sata', name: 'SATA', range: 5),
46
- ForemanFogProxmox::OptionsSelect.new(id: 'scsi', name: 'SCSI', range: 13),
47
- ForemanFogProxmox::OptionsSelect.new(name: 'VirtIO Block', id: 'virtio', range: 15)]
48
- end
49
-
50
- def proxmox_scsi_controllers_map
51
- [OpenStruct.new(id: 'lsi', name: 'LSI 53C895A (Default)'),
52
- OpenStruct.new(id: 'lsi53c810', name: 'LSI 53C810'),
53
- OpenStruct.new(id: 'virtio-scsi-pci', name: 'VirtIO SCSI'),
54
- OpenStruct.new(id: 'virtio-scsi-single', name: 'VirtIO SCSI Single'),
55
- OpenStruct.new(id: 'megasas', name: 'MegaRAID SAS 8708EM2'),
56
- OpenStruct.new(id: 'pvscsi', name: 'VMware PVSCSI')]
57
- end
58
-
59
43
  def proxmox_operating_systems_map
60
44
  [OpenStruct.new(id: 'other', name: 'Unspecified OS'),
61
45
  OpenStruct.new(id: 'wxp', name: 'Microsoft Windows XP'),
@@ -84,34 +68,6 @@ module ProxmoxComputeSelectorsHelper
84
68
  OpenStruct.new(id: 'serial3', name: 'Serial terminal 3')]
85
69
  end
86
70
 
87
- def proxmox_keyboards_map
88
- [OpenStruct.new(id: 'de', name: 'Deutsch'),
89
- OpenStruct.new(id: 'de-ch', name: 'Deutsch (Swiss)'),
90
- OpenStruct.new(id: 'da', name: 'Danish'),
91
- OpenStruct.new(id: 'en-gb', name: 'English (UK)'),
92
- OpenStruct.new(id: 'en-us', name: 'English (US)'),
93
- OpenStruct.new(id: 'es', name: 'Spanish'),
94
- OpenStruct.new(id: 'fi', name: 'Finnish'),
95
- OpenStruct.new(id: 'fr', name: 'French'),
96
- OpenStruct.new(id: 'fr-be', name: 'French (Belgium)'),
97
- OpenStruct.new(id: 'fr-ca', name: 'French (Canadian)'),
98
- OpenStruct.new(id: 'fr-ch', name: 'French (Swiss)'),
99
- OpenStruct.new(id: 'hu', name: 'Hungarian'),
100
- OpenStruct.new(id: 'is', name: 'Israelian'),
101
- OpenStruct.new(id: 'it', name: 'Italian'),
102
- OpenStruct.new(id: 'ja', name: 'Japanese'),
103
- OpenStruct.new(id: 'lt', name: 'Lituanian'),
104
- OpenStruct.new(id: 'mk', name: ''),
105
- OpenStruct.new(id: 'nl', name: 'Nederland'),
106
- OpenStruct.new(id: 'no', name: 'Norway'),
107
- OpenStruct.new(id: 'pl', name: 'Polish'),
108
- OpenStruct.new(id: 'pt', name: 'Portugese'),
109
- OpenStruct.new(id: 'pt-br', name: 'Portugese (Brasilian)'),
110
- OpenStruct.new(id: 'sv', name: 'Sv'),
111
- OpenStruct.new(id: 'sl', name: 'Slovakian'),
112
- OpenStruct.new(id: 'tr', name: 'Tr')]
113
- end
114
-
115
71
  def get_controller(id)
116
72
  proxmox_controllers_map.find { |controller| controller.id == id }
117
73
  end
@@ -161,6 +117,12 @@ module ProxmoxComputeSelectorsHelper
161
117
  OpenStruct.new(id: 'host', name: 'host')]
162
118
  end
163
119
 
120
+ def proxmox_cpu_flags_map
121
+ [OpenStruct.new(id: '-1', name: 'Off'),
122
+ OpenStruct.new(id: '0', name: 'Default'),
123
+ OpenStruct.new(id: '+1', name: 'On')]
124
+ end
125
+
164
126
  def proxmox_scsihw_map
165
127
  [OpenStruct.new(id: 'lsi', name: 'lsi'),
166
128
  OpenStruct.new(id: 'lsi53c810', name: 'lsi53c810'),
@@ -29,8 +29,7 @@ module ProxmoxFormHelper
29
29
  options[:value] = value if value.present?
30
30
  addClass options, 'form-control'
31
31
  pass = f.password_field(attr, options) +
32
- content_tag(:span, '', class: 'glyphicon glyphicon-warning-sign input-addon',
33
- title: 'Caps lock ON', style: 'display:none')
32
+ tag(:span, '', class: 'glyphicon glyphicon-warning-sign input-addon', title: 'Caps lock ON', style: 'display:none')
34
33
  if unset_button
35
34
  button = link_to_function(icon_text('edit', '', :kind => 'pficon'), 'toggle_input_group(this)', :id => 'disable-pass-btn', :class => 'btn btn-default', :title => _('Change the password'))
36
35
  input_group(pass, input_group_btn(button))
@@ -54,7 +53,7 @@ module ProxmoxFormHelper
54
53
  options[:form_builder_local] ||= :f
55
54
  options[:form_builder_attrs] ||= {}
56
55
 
57
- content_tag(:div, :class => "#{options[:type]}_#{association}_fields_template form_template ", :style => 'display: none;') do
56
+ content_tag(:div, :class => "#{options[:type]}_#{association}_fields_template form_template", :style => 'display: none;') do
58
57
  form_builder.fields_for(association, options[:object], :child_index => "new_#{options[:type]}_#{association}") do |f|
59
58
  render(:partial => options[:partial], :layout => options[:layout],
60
59
  :locals => { options[:form_builder_local] => f }.merge(options[:form_builder_attrs]))
@@ -65,6 +64,15 @@ module ProxmoxFormHelper
65
64
  def add_child_link_typed(name, association, type, opts = {})
66
65
  opts[:class] = [opts[:class], 'add_nested_fields btn btn-primary'].compact.join(' ')
67
66
  opts[:"data-association"] = (type + '_' + association.to_s).to_sym
68
- link_to_function(name.to_s, 'add_child_node(this);tfm.numFields.initAll();', opts)
67
+ hide = ''
68
+ hide += '$("[data-association=' + type + '_volumes]").hide();' unless ['hard_disk', 'mp'].include?(type)
69
+ link_to_function(name.to_s, 'add_child_node(this);tfm.numFields.initAll();' + hide, opts)
70
+ end
71
+
72
+ def remove_child_link_typed(name, f, type, opts = {})
73
+ opts[:class] = [opts[:class], 'remove_nested_fields'].compact.join(' ')
74
+ hide = ''
75
+ hide += '$("[data-association=' + type + '_volumes]").show();' unless ['hard_disk', 'mp'].include?(type)
76
+ f.hidden_field(opts[:method] || :_destroy) + link_to_function(name, 'remove_child_node(this);' + hide, opts)
69
77
  end
70
78
  end
@@ -17,13 +17,10 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
- module FogExtensions
21
- module Proxmox
22
- module Volume
23
- extend ActiveSupport::Concern
24
- def templated?
25
- volid ? volid.match(/^([\w-]+)[:]base-(\d+)-disk-(\d+)/) : false
26
- end
27
- end
20
+ module ProxmoxStoragesHelper
21
+ def proxmox_storages_types_map
22
+ [OpenStruct.new(id: 'hard_disk', name: 'Hard disk'),
23
+ OpenStruct.new(id: 'cdrom', name: 'CD-ROM'),
24
+ OpenStruct.new(id: 'cloud_init', name: 'Cloud-init')]
28
25
  end
29
26
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2019 Tristan Robert
3
+ # Copyright 2018 Tristan Robert
4
4
 
5
5
  # This file is part of ForemanFogProxmox.
6
6
 
@@ -11,20 +11,25 @@
11
11
 
12
12
  # ForemanFogProxmox is distributed in the hope that it will be useful,
13
13
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
15
  # GNU General Public License for more details.
16
16
 
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
- module ForemanFogProxmox
21
- module ProxmoxTokenExpiration
22
- def token_expired?
23
- Fog::Proxmox.credentials_has_expired?
24
- end
20
+ require 'fog/proxmox/helpers/disk_helper'
21
+ require 'fog/proxmox/helpers/nic_helper'
22
+ require 'foreman_fog_proxmox/value'
23
+ require 'foreman_fog_proxmox/hash_collection'
25
24
 
26
- def token_deadline
27
- Fog::Proxmox.credentials[:deadline]
28
- end
25
+ # Convert a foreman form server hash into a fog-proxmox server attributes hash
26
+ module ProxmoxVmCdromHelper
27
+ def parse_server_cdrom(args)
28
+ cdrom_media = args['cdrom'] if args.key?('cdrom')
29
+ cdrom_image = args['volid'] if args.key?('volid')
30
+ volid = cdrom_image.empty? ? cdrom_media : cdrom_image
31
+ return {} unless volid
32
+
33
+ { id: 'ide2', volid: volid, media: 'cdrom' }
29
34
  end
30
35
  end
@@ -0,0 +1,43 @@
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 'foreman_fog_proxmox/value'
23
+ require 'foreman_fog_proxmox/hash_collection'
24
+
25
+ # Convert a foreman form server hash into a fog-proxmox server attributes hash
26
+ module ProxmoxVmCloudinitHelper
27
+ def parse_server_cloudinit(args)
28
+ cloudinit_h = {}
29
+ cloudinit = args['cloudinit']
30
+ unless ['none'].include? cloudinit
31
+ volid = args['volid']
32
+ storage = args['storage']
33
+ cloudinit_volid = volid if volid
34
+ cloudinit_volid ||= "#{storage}:cloudinit" if storage
35
+ controller = args['controller']
36
+ device = args['device']
37
+ id = "#{controller}#{device}" if controller && device
38
+ cloudinit_h.store(:id, id.to_sym) if id
39
+ cloudinit_h.store(:volid, cloudinit_volid) if cloudinit_volid
40
+ end
41
+ cloudinit_h
42
+ end
43
+ end
@@ -0,0 +1,159 @@
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 ProxmoxVmConfigHelper
28
+ KILO = 1024
29
+ MEGA = KILO * KILO
30
+ GIGA = KILO * MEGA
31
+
32
+ def object_to_config_hash(vm, type)
33
+ vm_h = ActiveSupport::HashWithIndifferentAccess.new
34
+ main_a = ['hostname', 'name', 'vmid']
35
+ main = vm.attributes.select { |key, _value| main_a.include? key }
36
+ main_a += ['templated']
37
+ config = vm.config.attributes.reject { |key, _value| main_a.include?(key) || Fog::Proxmox::DiskHelper.disk?(key) || Fog::Proxmox::NicHelper.nic?(key) }
38
+ vm_h = vm_h.merge(main)
39
+ vm_h = vm_h.merge('config_attributes': config)
40
+ logger.debug(format(_('object_to_config_hash(%<type>s): vm_h=%<vm_h>s'), type: type, vm_h: vm_h))
41
+ vm_h
42
+ end
43
+
44
+ def convert_memory_size(config_hash, key)
45
+ # default unit memory size is Mb
46
+ memory = (config_hash[key].to_i / MEGA).to_s == '0' ? config_hash[key] : (config_hash[key].to_i / MEGA).to_s
47
+ config_hash.store(key, memory)
48
+ end
49
+
50
+ def general_a
51
+ general_a = ['name', 'node_id', 'type', 'config_attributes', 'volumes_attributes', 'interfaces_attributes']
52
+ general_a += ['firmware_type', 'provision_method', 'container_volumes', 'server_volumes', 'start_after_create']
53
+ general_a
54
+ end
55
+
56
+ def config_typed_keys(type)
57
+ keys = { general: general_a }
58
+ main_a = ['name', 'type', 'node_id', 'vmid', 'interfaces', 'mount_points', 'disks']
59
+ case type
60
+ when 'lxc'
61
+ cpu_a = ['arch', 'cpulimit', 'cpuunits', 'cores', 'sockets']
62
+ memory_a = ['memory', 'swap']
63
+ ostemplate_a = ['ostemplate', 'ostemplate_storage', 'ostemplate_file']
64
+ keys.store(:ostemplate, ostemplate_a)
65
+ when 'qemu'
66
+ cpu_a = ['cpu_type', 'cpu']
67
+ cpu_a += ForemanFogProxmox::HashCollection.stringify_keys(Fog::Proxmox::CpuHelper.flags).keys
68
+ memory_a = ['memory', 'balloon', 'shares']
69
+ cloud_init_a = ['ciuser', 'cipassword', 'searchdomain', 'nameserver']
70
+ keys.store(:cloud_init, cloud_init_a)
71
+ end
72
+ keys.store(:main, main_a)
73
+ keys.store(:cpu, cpu_a)
74
+ keys.store(:memory, memory_a)
75
+ keys
76
+ end
77
+
78
+ def convert_memory_sizes(args)
79
+ ['memory', 'balloon', 'shares', 'swap'].each { |key| convert_memory_size(args['config_attributes'], key) }
80
+ end
81
+
82
+ def config_general_or_ostemplate_key?(key)
83
+ config_typed_keys('lxc')[:general].include?(key) || config_typed_keys(type)[:ostemplate].include?(key)
84
+ end
85
+
86
+ def config_a(type)
87
+ config_a = []
88
+ case type
89
+ when 'qemu'
90
+ [:cpu, :memory, :general, :cloud_init].each { |key| config_a += config_typed_keys(type)[key] }
91
+ when 'lxc'
92
+ [:main].each { |key| config_a += config_typed_keys(type)[key] }
93
+ end
94
+ config_a
95
+ end
96
+
97
+ def args_a(type)
98
+ args_a = []
99
+ case type
100
+ when 'qemu'
101
+ [:general].each { |key| args_a += config_typed_keys(type)[key] }
102
+ when 'lxc'
103
+ [:general, :ostemplate].each { |key| args_a += config_typed_keys(type)[key] }
104
+ end
105
+ args_a
106
+ end
107
+
108
+ def config_options(config, args, type)
109
+ options = {}
110
+ case type
111
+ when 'qemu'
112
+ options = config.select { |key, _value| config_typed_keys(type)[:cloud_init].include? key }
113
+ when 'lxc'
114
+ options = parse_ostemplate(args, config)
115
+ end
116
+ options
117
+ end
118
+
119
+ def parsed_typed_config(args, type)
120
+ config = args['config_attributes']
121
+ config ||= ForemanFogProxmox::HashCollection.new_hash_reject_keys(args, config_typed_keys(type)[:main])
122
+ logger.debug("parsed_typed_config(#{type}): config=#{config}")
123
+ config_cpu = config.select { |key, _value| config_typed_keys(type)[:cpu].include? key }
124
+ logger.debug("parsed_typed_config(#{type}): config_cpu=#{config_cpu}")
125
+ cpu = parse_typed_cpu(config_cpu, type)
126
+ memory = parse_typed_memory(config.select { |key, _value| config_typed_keys(type)[:memory].include? key }, type)
127
+ parsed_config = config.reject { |key, value| config_a(type).include?(key) || ForemanFogProxmox::Value.empty?(value) }
128
+ parsed_vm = args.reject { |key, value| args_a(type).include?(key) || ForemanFogProxmox::Value.empty?(value) }
129
+ parsed_vm = parsed_vm.merge(config_options(config, args, type))
130
+ parsed_vm = parsed_vm.merge(parsed_config).merge(cpu).merge(memory)
131
+ logger.debug("parsed_typed_config(#{type}): parsed_vm=#{parsed_vm}")
132
+ parsed_vm
133
+ end
134
+
135
+ def parse_typed_memory(args, type)
136
+ memory = {}
137
+ ForemanFogProxmox::HashCollection.remove_empty_values(args)
138
+ config_typed_keys(type)[:memory].each { |key| ForemanFogProxmox::HashCollection.add_and_format_element(memory, key.to_sym, args, key, :to_i) }
139
+ memory
140
+ end
141
+
142
+ def parse_typed_cpu(args, type)
143
+ cpu = {}
144
+ ForemanFogProxmox::HashCollection.remove_empty_values(args)
145
+ if type == 'qemu'
146
+ logger.debug("parse_typed_cpu(#{type}): args=#{args}")
147
+ cpu_flattened = Fog::Proxmox::CpuHelper.flatten(args)
148
+ cpu_flattened = args[:cpu] if cpu_flattened.empty?
149
+ logger.debug("parse_typed_cpu(#{type}): cpu_flattened=#{cpu_flattened}")
150
+ ForemanFogProxmox::HashCollection.remove_empty_values(args)
151
+ ForemanFogProxmox::HashCollection.remove_keys(args, config_typed_keys('qemu')[:cpu])
152
+ args.each_value(&:to_i)
153
+ cpu = { cpu: cpu_flattened }
154
+ end
155
+ config_typed_keys('lxc')[:cpu].each { |key| ForemanFogProxmox::HashCollection.add_and_format_element(cpu, key.to_sym, args, key) } if type == 'lxc'
156
+ logger.debug("parse_typed_cpu(#{type}): cpu=#{cpu}")
157
+ cpu
158
+ end
159
+ end