foreman_fog_proxmox 0.8.0 → 0.8.2

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -1
  3. data/Rakefile +3 -1
  4. data/app/controllers/concerns/foreman_fog_proxmox/controller/parameters/compute_resource.rb +2 -2
  5. data/app/controllers/foreman_fog_proxmox/compute_resources_controller.rb +2 -2
  6. data/app/helpers/node_dashboard_helper.rb +13 -14
  7. data/app/helpers/proxmox_compute_selectors_helper.rb +49 -50
  8. data/app/helpers/proxmox_container_helper.rb +42 -36
  9. data/app/helpers/proxmox_form_helper.rb +38 -40
  10. data/app/helpers/proxmox_server_helper.rb +39 -41
  11. data/app/helpers/proxmox_vm_helper.rb +21 -25
  12. data/app/models/concerns/fog_extensions/proxmox/disk.rb +8 -8
  13. data/app/models/concerns/fog_extensions/proxmox/interface.rb +8 -8
  14. data/app/models/concerns/fog_extensions/proxmox/node.rb +24 -22
  15. data/app/models/concerns/fog_extensions/proxmox/server.rb +71 -59
  16. data/app/models/concerns/fog_extensions/proxmox/server_config.rb +47 -39
  17. data/app/models/concerns/fog_extensions/proxmox/volume.rb +8 -8
  18. data/app/models/concerns/host_ext/proxmox/interfaces.rb +21 -13
  19. data/app/models/concerns/orchestration/proxmox/compute.rb +14 -10
  20. data/app/models/foreman_fog_proxmox/options_select.rb +14 -14
  21. data/app/models/foreman_fog_proxmox/proxmox.rb +30 -466
  22. data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +54 -0
  23. data/app/models/foreman_fog_proxmox/proxmox_connection.rb +67 -0
  24. data/app/models/foreman_fog_proxmox/proxmox_console.rb +41 -0
  25. data/app/models/foreman_fog_proxmox/proxmox_images.rb +53 -0
  26. data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +60 -0
  27. data/app/models/foreman_fog_proxmox/proxmox_operating_systems.rb +49 -0
  28. data/app/models/foreman_fog_proxmox/proxmox_token_expiration.rb +30 -0
  29. data/app/models/foreman_fog_proxmox/proxmox_version.rb +36 -0
  30. data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +108 -0
  31. data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +162 -0
  32. data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +74 -0
  33. data/app/models/foreman_fog_proxmox/proxmox_volumes.rb +85 -0
  34. data/app/overrides/compute_resources_vms/form/add_clone_to_new_vm_compute_detail.rb +7 -6
  35. data/app/overrides/compute_resources_vms/form/add_from_profile_to_compute_attributes_form.rb +13 -11
  36. data/app/overrides/compute_resources_vms/form/add_vm_type_to_networks_form.rb +13 -11
  37. data/app/overrides/compute_resources_vms/form/add_vm_type_to_nic_provider_specific_form.rb +8 -7
  38. data/app/overrides/compute_resources_vms/form/add_vm_type_to_volumes_edit.rb +7 -6
  39. data/app/overrides/compute_resources_vms/form/add_vm_type_to_volumes_new_volume.rb +7 -6
  40. data/app/overrides/compute_resources_vms/form/remove_new_vm_from_removable_layout.rb +7 -6
  41. data/app/services/foreman_fog_proxmox/node_dashboard/data.rb +16 -16
  42. data/app/views/api/v2/compute_resources/proxmox.json.rabl +3 -1
  43. data/app/views/compute_resources/form/_proxmox.html.erb +3 -0
  44. data/app/views/compute_resources/show/_proxmox.html.erb +8 -0
  45. data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_compute_attributes_form.html.erb +5 -0
  46. data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_compute_form.html.erb +6 -1
  47. data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_hosts_compute_detail_form.html.erb +6 -0
  48. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_form.html.erb +6 -2
  49. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_new_childs_form.html.erb +8 -2
  50. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_nic_provider_specific_form.html.erb +6 -0
  51. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_volumes_edit.html.erb +15 -1
  52. data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +2 -2
  53. data/app/views/compute_resources_vms/form/proxmox/_general.html.erb +1 -1
  54. data/app/views/compute_resources_vms/form/proxmox/_removable_layout.html.erb +6 -1
  55. data/app/views/compute_resources_vms/form/proxmox/container/_extended.html.erb +1 -1
  56. data/app/views/compute_resources_vms/form/proxmox/container/_volume_mp.html.erb +1 -1
  57. data/app/views/compute_resources_vms/form/proxmox/server/_config.html.erb +1 -1
  58. data/app/views/compute_resources_vms/form/proxmox/server/_volume.html.erb +2 -2
  59. data/config/routes.rb +4 -4
  60. data/lib/foreman_fog_proxmox/engine.rb +14 -14
  61. data/lib/foreman_fog_proxmox/semver.rb +78 -78
  62. data/lib/foreman_fog_proxmox/value.rb +5 -3
  63. data/lib/foreman_fog_proxmox/version.rb +1 -1
  64. data/lib/tasks/foreman_fog_proxmox_tasks.rake +3 -13
  65. data/locale/en/foreman_fog_proxmox.edit.po +472 -0
  66. data/locale/en/foreman_fog_proxmox.po +48 -24
  67. data/locale/en/foreman_fog_proxmox.po.time_stamp +0 -0
  68. data/locale/foreman_fog_proxmox.pot +140 -102
  69. data/locale/fr/foreman_fog_proxmox.edit.po +472 -0
  70. data/locale/fr/foreman_fog_proxmox.po +52 -28
  71. data/locale/fr/foreman_fog_proxmox.po.time_stamp +0 -0
  72. data/locale/gemspec.rb +2 -0
  73. data/test/{unit/foreman_fog_proxmox/proxmox_test_helpers.rb → factories/foreman_fog_proxmox/proxmox_container_mock_factory.rb} +4 -140
  74. data/test/factories/foreman_fog_proxmox/proxmox_node_mock_factory.rb +61 -0
  75. data/test/factories/foreman_fog_proxmox/proxmox_server_mock_factory.rb +134 -0
  76. data/test/factories/proxmox_factory.rb +15 -15
  77. data/test/functional/compute_resources_controller_test.rb +12 -10
  78. data/test/test_plugin_helper.rb +2 -0
  79. data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +178 -182
  80. data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +122 -126
  81. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +180 -187
  82. data/test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb +116 -0
  83. data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +71 -0
  84. data/test/unit/foreman_fog_proxmox/proxmox_test.rb +9 -479
  85. data/test/unit/foreman_fog_proxmox/proxmox_version_test.rb +82 -0
  86. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb +207 -0
  87. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_create_test.rb +92 -0
  88. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb +324 -0
  89. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_test.rb +43 -0
  90. data/test/unit/foreman_fog_proxmox/proxmox_vm_new_test.rb +71 -0
  91. data/test/unit/foreman_fog_proxmox/proxmox_vm_queries_test.rb +63 -0
  92. data/test/unit/foreman_fog_proxmox/semver_test.rb +67 -53
  93. metadata +52 -14
@@ -0,0 +1,82 @@
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 'test_plugin_helper'
21
+ require 'models/compute_resources/compute_resource_test_helpers'
22
+ require 'active_support/core_ext/hash/indifferent_access'
23
+
24
+ module ForemanFogProxmox
25
+ class ProxmoxVersionTest < ActiveSupport::TestCase
26
+ include ComputeResourceTestHelpers
27
+ include ProxmoxVmHelper
28
+
29
+ wrong_version = { version: '5.a', release: '1' }.with_indifferent_access
30
+ supported_version = { version: '5.4', release: '3' }.with_indifferent_access
31
+ unsupported_version = { version: '6.0', release: '1' }.with_indifferent_access
32
+
33
+ describe 'version' do
34
+ before do
35
+ @cr = FactoryBot.build_stubbed(:proxmox_cr)
36
+ @identity_client = mock('identity_client')
37
+ @cr.stubs(:identity_client).returns(@identity_client)
38
+ end
39
+
40
+ it 'returns 5.a.1 with 5.a-1' do
41
+ @identity_client.stubs(:read_version).returns(wrong_version)
42
+ assert_equal '5.a.1', @cr.version
43
+ end
44
+
45
+ it 'returns 5.4.3 with 5.4-3' do
46
+ @identity_client.stubs(:read_version).returns(supported_version)
47
+ assert_equal '5.4.3', @cr.version
48
+ end
49
+
50
+ it 'returns 6.0.1 with 6.0-1' do
51
+ @identity_client.stubs(:read_version).returns(unsupported_version)
52
+ assert_equal '6.0.1', @cr.version
53
+ end
54
+ end
55
+
56
+ describe 'version_suitable?' do
57
+ before do
58
+ @cr = FactoryBot.build_stubbed(:proxmox_cr)
59
+ @identity_client = mock('identity_client')
60
+ @cr.stubs(:identity_client).returns(@identity_client)
61
+ end
62
+
63
+ it 'raises error with 5.a.1' do
64
+ @identity_client.stubs(:read_version).returns(wrong_version)
65
+ err = assert_raises Foreman::Exception do
66
+ @cr.version_suitable?
67
+ end
68
+ assert err.message.end_with?('Proxmox version 5.a.1 is not semver suitable')
69
+ end
70
+
71
+ it 'is true with 5.4-3' do
72
+ @identity_client.stubs(:read_version).returns(supported_version)
73
+ assert_equal true, @cr.version_suitable?
74
+ end
75
+
76
+ it 'is false with 6.0-1' do
77
+ @identity_client.stubs(:read_version).returns(unsupported_version)
78
+ assert_equal false, @cr.version_suitable?
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,207 @@
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 'test_plugin_helper'
21
+ require 'models/compute_resources/compute_resource_test_helpers'
22
+ require 'factories/foreman_fog_proxmox/proxmox_node_mock_factory'
23
+ require 'factories/foreman_fog_proxmox/proxmox_container_mock_factory'
24
+ require 'active_support/core_ext/hash/indifferent_access'
25
+
26
+ module ForemanFogProxmox
27
+ class ProxmoxVmCommandsContainerTest < ActiveSupport::TestCase
28
+ include ComputeResourceTestHelpers
29
+ include ProxmoxNodeMockFactory
30
+ include ProxmoxContainerMockFactory
31
+ include ProxmoxVmHelper
32
+
33
+ describe 'save_vm' do
34
+ before do
35
+ @cr = FactoryBot.build_stubbed(:proxmox_cr)
36
+ end
37
+
38
+ it 'saves modified container config' do
39
+ uuid = '100'
40
+ config = mock('config')
41
+ config.stubs(:attributes).returns(:cores => '')
42
+ vm = mock('vm')
43
+ vm.stubs(:config).returns(config)
44
+ vm.stubs(:container?).returns(true)
45
+ vm.stubs(:type).returns('lxc')
46
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
47
+ attr = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1', 'onboot' => '0' } }.with_indifferent_access
48
+ @cr.stubs(:parse_container_vm).returns('vmid' => '100', 'type' => 'lxc', 'cores' => '1', 'cpulimit' => '1')
49
+ expected_attr = { :cores => '1', :cpulimit => '1' }
50
+ vm.expects(:update, expected_attr)
51
+ @cr.save_vm(uuid, attr)
52
+ end
53
+
54
+ it 'saves modified container config with added volumes' do
55
+ uuid = '100'
56
+ config = mock('config')
57
+ disks = mock('disks')
58
+ disk = mock('disk')
59
+ disk.stubs(:size).returns(1_073_741_824)
60
+ disk.stubs(:storage).returns('local-lvm')
61
+ disk.stubs(:id).returns('mp0')
62
+ disks.stubs(:get).returns
63
+ config.stubs(:disks).returns(disks)
64
+ config.stubs(:attributes).returns(:cores => '')
65
+ vm = mock('vm')
66
+ vm.stubs(:config).returns(config)
67
+ vm.stubs(:container?).returns(true)
68
+ vm.stubs(:type).returns('lxc')
69
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
70
+ new_attributes = {
71
+ 'templated' => '0',
72
+ 'config_attributes' => {
73
+ 'cores' => '1',
74
+ 'cpulimit' => '1'
75
+ },
76
+ 'volumes_attributes' => {
77
+ '0' => {
78
+ 'id' => 'mp0',
79
+ '_delete' => '',
80
+ 'device' => '0',
81
+ 'storage' => 'local-lvm',
82
+ 'size' => '2147483648',
83
+ 'cache' => 'none',
84
+ 'mp' => '/opt/path'
85
+ }
86
+ }
87
+ }.with_indifferent_access
88
+ @cr.stubs(:parse_container_vm).returns('vmid' => '100', 'type' => 'lxc', 'cores' => '1', 'cpulimit' => '1')
89
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
90
+ expected_volume_attr =
91
+ [
92
+ {
93
+ id: 'mp0',
94
+ storage: 'local:lvm',
95
+ size: (2_147_483_648 / GIGA).to_s
96
+ },
97
+ {
98
+ mp: '/opt/path'
99
+ }
100
+ ]
101
+ vm.expects(:attach, expected_volume_attr)
102
+ vm.expects(:update, expected_config_attr)
103
+ @cr.save_vm(uuid, new_attributes)
104
+ end
105
+
106
+ it 'saves modified container config with resized volumes' do
107
+ uuid = '100'
108
+ config = mock('config')
109
+ disks = mock('disks')
110
+ disk = mock('disk')
111
+ disk.stubs(:size).returns(1_073_741_824)
112
+ disk.stubs(:storage).returns('local-lvm')
113
+ disk.stubs(:id).returns('rootfs')
114
+ disks.stubs(:get).returns(disk)
115
+ config.stubs(:disks).returns(disks)
116
+ config.stubs(:attributes).returns(:cores => '')
117
+ vm = mock('vm')
118
+ vm.stubs(:config).returns(config)
119
+ vm.stubs(:container?).returns(true)
120
+ vm.stubs(:type).returns('lxc')
121
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
122
+ new_attributes =
123
+ {
124
+ 'templated' => '0',
125
+ 'config_attributes' => {
126
+ 'cores' => '1',
127
+ 'cpulimit' => '1',
128
+ 'onboot' => '0'
129
+ },
130
+ 'volumes_attributes' => {
131
+ '0' => {
132
+ 'id' => 'rootfs',
133
+ '_delete' => '',
134
+ 'volid' => 'local-lvm:1073741824',
135
+ 'device' => '0',
136
+ 'storage' => 'local-lvm',
137
+ 'size' => '2147483648',
138
+ 'cache' => 'none'
139
+ }
140
+ }
141
+ }.with_indifferent_access
142
+ @cr.stubs(:parse_container_vm).returns(
143
+ 'vmid' => '100',
144
+ 'type' => 'lxc',
145
+ 'cores' => '1',
146
+ 'cpulimit' => '1'
147
+ )
148
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
149
+ expected_volume_attr = ['rootfs', '+1G']
150
+ vm.expects(:extend, expected_volume_attr)
151
+ vm.expects(:update, expected_config_attr)
152
+ @cr.save_vm(uuid, new_attributes)
153
+ end
154
+ end
155
+
156
+ describe 'create_vm' do
157
+ it 'creates container without bootstart' do
158
+ args = { vmid: '100', type: 'lxc', config_attributes: { onboot: '0' } }
159
+ servers = mock('servers')
160
+ servers.stubs(:id_valid?).returns(true)
161
+ containers = mock('containers')
162
+ containers.stubs(:create).with(vmid: 100, type: 'lxc', config_attributes: { onboot: '0' })
163
+ cr = mock_node_servers_containers(ForemanFogProxmox::Proxmox.new, servers, containers)
164
+ cr.stubs(:convert_sizes).with(args)
165
+ cr.stubs(:parse_container_vm).with(args).returns(args)
166
+ vm = mock('vm')
167
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
168
+ cr.create_vm(args)
169
+ end
170
+
171
+ it 'creates container with bootstart' do
172
+ args = { vmid: '100', type: 'lxc', config_attributes: { onboot: '0' } }
173
+ servers = mock('servers')
174
+ servers.stubs(:id_valid?).returns(true)
175
+ containers = mock('containers')
176
+ vm = mock('vm')
177
+ containers.stubs(:create).with(vmid: 100, type: 'lxc', config_attributes: { onboot: '0' }).returns(vm)
178
+ cr = mock_node_servers_containers(ForemanFogProxmox::Proxmox.new, servers, containers)
179
+ cr.stubs(:convert_sizes).with(args)
180
+ cr.stubs(:parse_container_vm).with(args).returns(args)
181
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
182
+ cr.stubs(:start_on_boot).with(vm, args).returns(vm)
183
+ cr.create_vm(args)
184
+ end
185
+
186
+ it 'clones container' do
187
+ args = { vmid: '100', type: 'lxc', image_id: '999', name: 'name' }
188
+ servers = mock('servers')
189
+ servers.stubs(:id_valid?).returns(true)
190
+ containers = mock('containers')
191
+ containers.stubs(:create).with(vmid: 100, type: 'lxc')
192
+ image = mock('image')
193
+ clone = mock('clone')
194
+ image.stubs(:clone).with(100)
195
+ servers.stubs(:get).with(100).returns(clone)
196
+ servers.stubs(:get).with('999').returns(image)
197
+ clone.stubs(:update).with(name: 'name')
198
+ cr = mock_node_servers_containers(ForemanFogProxmox::Proxmox.new, servers, containers)
199
+ cr.stubs(:convert_sizes).with(args)
200
+ cr.stubs(:parse_container_vm).with(args).returns(args)
201
+ vm = mock('vm')
202
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
203
+ cr.create_vm(args)
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,92 @@
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 'test_plugin_helper'
21
+ require 'models/compute_resources/compute_resource_test_helpers'
22
+ require 'factories/foreman_fog_proxmox/proxmox_node_mock_factory'
23
+ require 'factories/foreman_fog_proxmox/proxmox_server_mock_factory'
24
+ require 'active_support/core_ext/hash/indifferent_access'
25
+
26
+ module ForemanFogProxmox
27
+ class ProxmoxVmCommandsServerCreateTest < ActiveSupport::TestCase
28
+ include ComputeResourceTestHelpers
29
+ include ProxmoxNodeMockFactory
30
+ include ProxmoxServerMockFactory
31
+ include ProxmoxVmHelper
32
+
33
+ describe 'create_vm' do
34
+ it 'raises Foreman::Exception when vmid is invalid' do
35
+ args = { vmid: '100' }
36
+ servers = mock('servers')
37
+ servers.stubs(:id_valid?).returns(false)
38
+ cr = mock_node_servers(ForemanFogProxmox::Proxmox.new, servers)
39
+ err = assert_raises Foreman::Exception do
40
+ cr.create_vm(args)
41
+ end
42
+ assert err.message.end_with?('invalid vmid=100')
43
+ end
44
+
45
+ it 'creates server without bootstart' do
46
+ args = { vmid: '100', type: 'qemu', config_attributes: { onboot: '0' } }
47
+ servers = mock('servers')
48
+ servers.stubs(:id_valid?).returns(true)
49
+ cr = mock_node_servers(ForemanFogProxmox::Proxmox.new, servers)
50
+ cr.stubs(:convert_sizes).with(args)
51
+ cr.stubs(:parse_server_vm).with(args).returns(args)
52
+ servers.stubs(:create).with(args)
53
+ vm = mock('vm')
54
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
55
+ cr.create_vm(args)
56
+ end
57
+
58
+ it 'creates server with bootstart' do
59
+ args = { vmid: '100', type: 'qemu', config_attributes: { onboot: '1' } }
60
+ servers = mock('servers')
61
+ servers.stubs(:id_valid?).returns(true)
62
+ cr = mock_node_servers(ForemanFogProxmox::Proxmox.new, servers)
63
+ cr.stubs(:convert_sizes).with(args)
64
+ cr.stubs(:parse_server_vm).with(args).returns(args)
65
+ vm = mock('vm')
66
+ servers.stubs(:create).with(args).returns(vm)
67
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
68
+ cr.stubs(:start_on_boot).with(vm, args).returns(vm)
69
+ cr.create_vm(args)
70
+ end
71
+
72
+ it 'clones server' do
73
+ args = { vmid: '100', type: 'qemu', image_id: '999', name: 'name' }
74
+ servers = mock('servers')
75
+ servers.stubs(:id_valid?).returns(true)
76
+ cr = mock_node_servers(ForemanFogProxmox::Proxmox.new, servers)
77
+ cr.stubs(:convert_sizes).with(args)
78
+ cr.stubs(:parse_server_vm).with(args).returns(args)
79
+ servers.stubs(:create).with(args)
80
+ image = mock('image')
81
+ clone = mock('clone')
82
+ image.stubs(:clone).with(100)
83
+ servers.stubs(:get).with(100).returns(clone)
84
+ servers.stubs(:get).with('999').returns(image)
85
+ clone.stubs(:update).with(name: 'name')
86
+ vm = mock('vm')
87
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
88
+ cr.create_vm(args)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,324 @@
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 'test_plugin_helper'
21
+ require 'models/compute_resources/compute_resource_test_helpers'
22
+ require 'factories/foreman_fog_proxmox/proxmox_node_mock_factory'
23
+ require 'factories/foreman_fog_proxmox/proxmox_server_mock_factory'
24
+ require 'active_support/core_ext/hash/indifferent_access'
25
+
26
+ module ForemanFogProxmox
27
+ class ProxmoxVmCommandsServerUpdateTest < ActiveSupport::TestCase
28
+ include ComputeResourceTestHelpers
29
+ include ProxmoxNodeMockFactory
30
+ include ProxmoxServerMockFactory
31
+ include ProxmoxVmHelper
32
+
33
+ describe 'save_vm' do
34
+ before do
35
+ @cr = FactoryBot.build_stubbed(:proxmox_cr)
36
+ end
37
+
38
+ it 'saves modified server config with same volumes' do
39
+ uuid = '100'
40
+ config = mock('config')
41
+ config.stubs(:attributes).returns(:cores => '')
42
+ vm = mock('vm')
43
+ vm.stubs(:config).returns(config)
44
+ vm.stubs(:container?).returns(false)
45
+ vm.stubs(:templated?).returns(false)
46
+ vm.stubs(:type).returns('qemu')
47
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
48
+ attr = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1', 'onboot' => '0' } }.with_indifferent_access
49
+ @cr.stubs(:parse_server_vm).returns('vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1', 'onboot' => '0')
50
+ expected_attr = { :cores => '1', :cpulimit => '1' }.with_indifferent_access
51
+ vm.expects(:update, expected_attr)
52
+ @cr.save_vm(uuid, attr)
53
+ end
54
+
55
+ it 'saves server as template' do
56
+ uuid = '100'
57
+ config = mock('config')
58
+ config.stubs(:attributes).returns(:cores => '')
59
+ vm = mock('vm')
60
+ vm.stubs(:config).returns(config)
61
+ vm.stubs(:container?).returns(false)
62
+ vm.stubs(:templated?).returns(false)
63
+ vm.stubs(:type).returns('qemu')
64
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
65
+ attr = { 'templated' => '1' }
66
+ vm.expects(:create_template)
67
+ @cr.save_vm(uuid, attr)
68
+ end
69
+
70
+ it 'saves modified server config with added volumes' do
71
+ uuid = '100'
72
+ config = mock('config')
73
+ disks = mock('disks')
74
+ disk = mock('disk')
75
+ disk.stubs(:size).returns(1_073_741_824)
76
+ disk.stubs(:storage).returns('local-lvm')
77
+ disk.stubs(:id).returns('scsi0')
78
+ disks.stubs(:get).returns
79
+ config.stubs(:disks).returns(disks)
80
+ config.stubs(:attributes).returns(:cores => '')
81
+ vm = mock('vm')
82
+ vm.stubs(:config).returns(config)
83
+ vm.stubs(:container?).returns(false)
84
+ vm.stubs(:type).returns('qemu')
85
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
86
+ new_attributes = {
87
+ 'templated' => '0',
88
+ 'config_attributes' => {
89
+ 'cores' => '1',
90
+ 'cpulimit' => '1'
91
+ },
92
+ 'volumes_attributes' => {
93
+ '0' => {
94
+ 'id' => 'scsi0',
95
+ '_delete' => '',
96
+ 'device' => '0',
97
+ 'controller' => 'scsi',
98
+ 'storage' => 'local-lvm',
99
+ 'size' => '2147483648',
100
+ 'cache' => 'none'
101
+ }
102
+ }
103
+ }.with_indifferent_access
104
+ @cr.stubs(:parse_server_vm).returns('vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1', 'onboot' => '0')
105
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
106
+ expected_volume_attr = { id: 'scsi0', storage: 'local:lvm', size: (2_147_483_648 / GIGA).to_s }
107
+ vm.expects(:attach, expected_volume_attr)
108
+ vm.expects(:update, expected_config_attr)
109
+ @cr.save_vm(uuid, new_attributes)
110
+ end
111
+
112
+ it 'saves modified server config with removed volumes' do
113
+ uuid = '100'
114
+ config = mock('config')
115
+ disks = mock('disks')
116
+ disk = mock('disk')
117
+ disk.stubs(:size).returns(1_073_741_824)
118
+ disk.stubs(:storage).returns('local-lvm')
119
+ disk.stubs(:id).returns('virtio0')
120
+ disks.stubs(:get).returns(disk)
121
+ config.stubs(:disks).returns(disks)
122
+ config.stubs(:attributes).returns(:cores => '')
123
+ vm = mock('vm')
124
+ vm.stubs(:config).returns(config)
125
+ vm.stubs(:container?).returns(false)
126
+ vm.stubs(:templated?).returns(false)
127
+ vm.stubs(:type).returns('qemu')
128
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
129
+ new_attributes = {
130
+ 'templated' => '0',
131
+ 'config_attributes' => {
132
+ 'cores' => '1',
133
+ 'cpulimit' => '1'
134
+ },
135
+ 'volumes_attributes' => {
136
+ '0' => {
137
+ '_delete' => '1',
138
+ 'id' => 'scsi0',
139
+ 'volid' => 'local-lvm:vm-100-disk-0',
140
+ 'device' => '0',
141
+ 'controller' => 'scsi',
142
+ 'storage' => 'local-lvm',
143
+ 'size' => '2147483648',
144
+ 'cache' => 'none'
145
+ }
146
+ }
147
+ }.with_indifferent_access
148
+ @cr.stubs(:parse_server_vm).returns('vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1', 'config_attributes' => { 'onboot' => '0' })
149
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
150
+ expected_volume_attr = 'scsi0'
151
+ vm.expects(:detach, expected_volume_attr)
152
+ vm.expects(:detach, 'unused0')
153
+ vm.expects(:update, expected_config_attr)
154
+ @cr.save_vm(uuid, new_attributes)
155
+ end
156
+
157
+ it 'saves modified server config with removed interfaces' do
158
+ uuid = '100'
159
+ config = mock('config')
160
+ interfaces = mock('interfaces')
161
+ interface = mock('interface')
162
+ interface.stubs(:id).returns('net0')
163
+ interfaces.stubs(:get).returns(interface)
164
+ config.stubs(:interfaces).returns(interfaces)
165
+ config.stubs(:attributes).returns(:cores => '')
166
+ vm = mock('vm')
167
+ vm.stubs(:config).returns(config)
168
+ vm.stubs(:container?).returns(false)
169
+ vm.stubs(:type).returns('qemu')
170
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
171
+ new_attributes = {
172
+ 'templated' => '0',
173
+ 'config_attributes' => {
174
+ 'cores' => '1',
175
+ 'cpulimit' => '1'
176
+ },
177
+ 'interfaces_attributes' => {
178
+ '0' => {
179
+ '_delete' => '1',
180
+ 'id' => 'net0'
181
+ }
182
+ }
183
+ }.with_indifferent_access
184
+ @cr.stubs(:parse_server_vm).returns(
185
+ 'vmid' => '100',
186
+ 'type' => 'qemu',
187
+ 'cores' => '1',
188
+ 'cpulimit' => '1',
189
+ 'delete' => 'net0',
190
+ 'onboot' => '0'
191
+ )
192
+ expected_config_attr = { :cores => '1', :cpulimit => '1', :delete => 'net0' }
193
+ vm.expects(:update, expected_config_attr)
194
+ @cr.save_vm(uuid, new_attributes)
195
+ end
196
+
197
+ it 'saves modified server config with resized volumes' do
198
+ uuid = '100'
199
+ config = mock('config')
200
+ disks = mock('disks')
201
+ disk = mock('disk')
202
+ disk.stubs(:size).returns(1_073_741_824)
203
+ disk.stubs(:storage).returns('local-lvm')
204
+ disks.stubs(:get).returns(disk)
205
+ config.stubs(:disks).returns(disks)
206
+ config.stubs(:attributes).returns(:cores => '')
207
+ vm = mock('vm')
208
+ vm.stubs(:config).returns(config)
209
+ vm.stubs(:container?).returns(false)
210
+ vm.stubs(:templated?).returns(false)
211
+ vm.stubs(:type).returns('qemu')
212
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
213
+ new_attributes = {
214
+ 'templated' => '0',
215
+ 'config_attributes' => {
216
+ 'cores' => '1',
217
+ 'cpulimit' => '1'
218
+ },
219
+ 'volumes_attributes' => {
220
+ '0' => {
221
+ 'id' => 'scsi0',
222
+ '_delete' => '',
223
+ 'volid' => 'local-lvm:vm-100-disk-0',
224
+ 'device' => '0',
225
+ 'controller' => 'scsi',
226
+ 'storage' => 'local-lvm',
227
+ 'size' => '2147483648',
228
+ 'cache' => 'none'
229
+ }
230
+ }
231
+ }.with_indifferent_access
232
+ @cr.stubs(:parse_server_vm).returns('vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1')
233
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
234
+ expected_volume_attr = ['scsi0', '+1G']
235
+ vm.expects(:extend, expected_volume_attr)
236
+ vm.expects(:update, expected_config_attr)
237
+ @cr.save_vm(uuid, new_attributes)
238
+ end
239
+
240
+ it 'raises error unable to shrink volumes' do
241
+ uuid = '100'
242
+ config = mock('config')
243
+ disks = mock('disks')
244
+ disk = mock('disk')
245
+ disk.stubs(:size).returns(1_073_741_824)
246
+ disk.stubs(:storage).returns('local-lvm')
247
+ disks.stubs(:get).returns(disk)
248
+ config.stubs(:disks).returns(disks)
249
+ config.stubs(:attributes).returns(:cores => '')
250
+ vm = mock('vm')
251
+ vm.stubs(:config).returns(config)
252
+ vm.stubs(:container?).returns(false)
253
+ vm.stubs(:type).returns('qemu')
254
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
255
+ new_attributes = {
256
+ 'templated' => '0',
257
+ 'config_attributes' => {
258
+ 'cores' => '1',
259
+ 'cpulimit' => '1'
260
+ },
261
+ 'volumes_attributes' => {
262
+ '0' => {
263
+ 'id' => 'scsi0',
264
+ '_delete' => '',
265
+ 'volid' => 'local-lvm:vm-100-disk-0',
266
+ 'device' => '0',
267
+ 'controller' => 'scsi',
268
+ 'storage' => 'local-lvm',
269
+ 'size' => '2',
270
+ 'cache' => 'none'
271
+ }
272
+ }
273
+ }.with_indifferent_access
274
+ @cr.stubs(:parse_server_vm).returns('vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1')
275
+ err = assert_raises Foreman::Exception do
276
+ @cr.save_vm(uuid, new_attributes)
277
+ end
278
+ assert err.message.end_with?('Unable to shrink scsi0 size. Proxmox allows only increasing size.')
279
+ end
280
+
281
+ it 'saves modified server config with moved volumes' do
282
+ uuid = '100'
283
+ config = mock('config')
284
+ disks = mock('disks')
285
+ disk = mock('disk')
286
+ disk.stubs(:size).returns(1_073_741_824)
287
+ disk.stubs(:storage).returns('local-lvm')
288
+ disks.stubs(:get).returns(disk)
289
+ config.stubs(:disks).returns(disks)
290
+ config.stubs(:attributes).returns(:cores => '')
291
+ vm = mock('vm')
292
+ vm.stubs(:config).returns(config)
293
+ vm.stubs(:container?).returns(false)
294
+ vm.stubs(:type).returns('qemu')
295
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
296
+ new_attributes = {
297
+ 'templated' => '0',
298
+ 'config_attributes' => {
299
+ 'cores' => '1',
300
+ 'cpulimit' => '1'
301
+ },
302
+ 'volumes_attributes' => {
303
+ '0' => {
304
+ 'id' => 'scsi0',
305
+ '_delete' => '',
306
+ 'volid' => 'local-lvm:vm-100-disk-0',
307
+ 'device' => '0',
308
+ 'controller' => 'scsi',
309
+ 'storage' => 'local-lvm2',
310
+ 'size' => '1073741824',
311
+ 'cache' => 'none'
312
+ }
313
+ }
314
+ }.with_indifferent_access
315
+ @cr.stubs(:parse_server_vm).returns('vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1')
316
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
317
+ expected_volume_attr = ['scsi0', 'local-lvm2']
318
+ vm.expects(:move, expected_volume_attr)
319
+ vm.expects(:update, expected_config_attr)
320
+ @cr.save_vm(uuid, new_attributes)
321
+ end
322
+ end
323
+ end
324
+ end