foreman_fog_proxmox 0.12.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 (113) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +290 -0
  4. data/Rakefile +49 -0
  5. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_compute_resource.js +33 -0
  6. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm.js +187 -0
  7. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_container.js +24 -0
  8. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +125 -0
  9. data/app/controllers/concerns/foreman_fog_proxmox/controller/parameters/compute_resource.rb +41 -0
  10. data/app/controllers/foreman_fog_proxmox/compute_resources_controller.rb +86 -0
  11. data/app/helpers/node_dashboard_helper.rb +35 -0
  12. data/app/helpers/proxmox_compute_selectors_helper.rb +184 -0
  13. data/app/helpers/proxmox_container_helper.rb +163 -0
  14. data/app/helpers/proxmox_form_helper.rb +70 -0
  15. data/app/helpers/proxmox_server_helper.rb +155 -0
  16. data/app/helpers/proxmox_vm_helper.rb +88 -0
  17. data/app/models/concerns/fog_extensions/proxmox/disk.rb +29 -0
  18. data/app/models/concerns/fog_extensions/proxmox/interface.rb +40 -0
  19. data/app/models/concerns/fog_extensions/proxmox/node.rb +41 -0
  20. data/app/models/concerns/fog_extensions/proxmox/server.rb +93 -0
  21. data/app/models/concerns/fog_extensions/proxmox/server_config.rb +71 -0
  22. data/app/models/concerns/fog_extensions/proxmox/volume.rb +29 -0
  23. data/app/models/concerns/host_ext/proxmox/interfaces.rb +52 -0
  24. data/app/models/concerns/orchestration/proxmox/compute.rb +42 -0
  25. data/app/models/foreman_fog_proxmox/options_select.rb +36 -0
  26. data/app/models/foreman_fog_proxmox/proxmox.rb +133 -0
  27. data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +67 -0
  28. data/app/models/foreman_fog_proxmox/proxmox_connection.rb +67 -0
  29. data/app/models/foreman_fog_proxmox/proxmox_console.rb +41 -0
  30. data/app/models/foreman_fog_proxmox/proxmox_images.rb +61 -0
  31. data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +103 -0
  32. data/app/models/foreman_fog_proxmox/proxmox_operating_systems.rb +49 -0
  33. data/app/models/foreman_fog_proxmox/proxmox_pools.rb +56 -0
  34. data/app/models/foreman_fog_proxmox/proxmox_token_expiration.rb +30 -0
  35. data/app/models/foreman_fog_proxmox/proxmox_version.rb +36 -0
  36. data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +116 -0
  37. data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +178 -0
  38. data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +75 -0
  39. data/app/models/foreman_fog_proxmox/proxmox_volumes.rb +94 -0
  40. data/app/models/foreman_fog_proxmox/vms.rb +37 -0
  41. data/app/overrides/compute_resources_vms/form/add_clone_to_new_vm_compute_detail.rb +25 -0
  42. data/app/overrides/compute_resources_vms/form/add_from_profile_to_compute_attributes_form.rb +34 -0
  43. data/app/overrides/compute_resources_vms/form/add_vm_type_node_to_new_form.rb +25 -0
  44. data/app/overrides/compute_resources_vms/form/add_vm_type_to_networks_form.rb +34 -0
  45. data/app/overrides/compute_resources_vms/form/add_vm_type_to_nic_provider_specific_form.rb +26 -0
  46. data/app/overrides/compute_resources_vms/form/add_vm_type_to_volumes_edit.rb +25 -0
  47. data/app/overrides/compute_resources_vms/form/add_vm_type_to_volumes_new_volume.rb +25 -0
  48. data/app/overrides/compute_resources_vms/form/remove_new_vm_from_removable_layout.rb +25 -0
  49. data/app/services/foreman_fog_proxmox/node_dashboard/data.rb +37 -0
  50. data/app/views/api/v2/compute_resources/proxmox.json.rabl +3 -0
  51. data/app/views/compute_resources/form/_proxmox.html.erb +29 -0
  52. data/app/views/compute_resources/show/_proxmox.html.erb +37 -0
  53. data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_compute_attributes_form.html.erb +23 -0
  54. data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_compute_form.html.erb +23 -0
  55. data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_hosts_compute_detail_form.html.erb +24 -0
  56. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_node_to_new_form.html.erb +24 -0
  57. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_form.html.erb +28 -0
  58. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_new_childs_form.html.erb +32 -0
  59. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_nic_provider_specific_form.html.erb +30 -0
  60. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_volumes_edit.html.erb +71 -0
  61. data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +39 -0
  62. data/app/views/compute_resources_vms/form/proxmox/_general.html.erb +39 -0
  63. data/app/views/compute_resources_vms/form/proxmox/_network.html.erb +19 -0
  64. data/app/views/compute_resources_vms/form/proxmox/_removable_layout.html.erb +27 -0
  65. data/app/views/compute_resources_vms/form/proxmox/container/_advanced.html.erb +31 -0
  66. data/app/views/compute_resources_vms/form/proxmox/container/_config.html.erb +41 -0
  67. data/app/views/compute_resources_vms/form/proxmox/container/_extended.html.erb +27 -0
  68. data/app/views/compute_resources_vms/form/proxmox/container/_network.html.erb +33 -0
  69. data/app/views/compute_resources_vms/form/proxmox/container/_volume_mp.html.erb +27 -0
  70. data/app/views/compute_resources_vms/form/proxmox/container/_volume_rootfs.html.erb +24 -0
  71. data/app/views/compute_resources_vms/form/proxmox/server/_advanced.html.erb +31 -0
  72. data/app/views/compute_resources_vms/form/proxmox/server/_config.html.erb +60 -0
  73. data/app/views/compute_resources_vms/form/proxmox/server/_network.html.erb +30 -0
  74. data/app/views/compute_resources_vms/form/proxmox/server/_volume.html.erb +28 -0
  75. data/app/views/compute_resources_vms/index/_proxmox.html.erb +49 -0
  76. data/app/views/compute_resources_vms/show/_proxmox.html.erb +42 -0
  77. data/app/views/dashboard/_foreman_fog_proxmox_widget.erb +21 -0
  78. data/app/views/images/form/_proxmox.html.erb +21 -0
  79. data/config/routes.rb +30 -0
  80. data/lib/foreman_fog_proxmox.rb +23 -0
  81. data/lib/foreman_fog_proxmox/engine.rb +105 -0
  82. data/lib/foreman_fog_proxmox/semver.rb +102 -0
  83. data/lib/foreman_fog_proxmox/value.rb +26 -0
  84. data/lib/foreman_fog_proxmox/version.rb +22 -0
  85. data/lib/tasks/foreman_fog_proxmox_tasks.rake +37 -0
  86. data/locale/Makefile +60 -0
  87. data/locale/en/foreman_fog_proxmox.po +401 -0
  88. data/locale/foreman_fog_proxmox.pot +627 -0
  89. data/locale/fr/foreman_fog_proxmox.po +401 -0
  90. data/locale/gemspec.rb +4 -0
  91. data/test/factories/foreman_fog_proxmox/proxmox_container_mock_factory.rb +137 -0
  92. data/test/factories/foreman_fog_proxmox/proxmox_node_mock_factory.rb +87 -0
  93. data/test/factories/foreman_fog_proxmox/proxmox_server_mock_factory.rb +134 -0
  94. data/test/factories/proxmox_factory.rb +79 -0
  95. data/test/functional/compute_resources_controller_test.rb +48 -0
  96. data/test/test_plugin_helper.rb +19 -0
  97. data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +204 -0
  98. data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +149 -0
  99. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +216 -0
  100. data/test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb +124 -0
  101. data/test/unit/foreman_fog_proxmox/proxmox_images_test.rb +52 -0
  102. data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +117 -0
  103. data/test/unit/foreman_fog_proxmox/proxmox_test.rb +58 -0
  104. data/test/unit/foreman_fog_proxmox/proxmox_version_test.rb +94 -0
  105. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb +280 -0
  106. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_create_test.rb +110 -0
  107. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb +222 -0
  108. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_volumes_test.rb +308 -0
  109. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_test.rb +43 -0
  110. data/test/unit/foreman_fog_proxmox/proxmox_vm_new_test.rb +71 -0
  111. data/test/unit/foreman_fog_proxmox/proxmox_vm_queries_test.rb +68 -0
  112. data/test/unit/foreman_fog_proxmox/semver_test.rb +111 -0
  113. metadata +249 -0
@@ -0,0 +1,52 @@
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 'active_support/core_ext/hash/indifferent_access'
22
+
23
+ module ForemanFogProxmox
24
+ class ProxmoxVmCommandsServerTest < ActiveSupport::TestCase
25
+ include ComputeResourceTestHelpers
26
+
27
+ describe 'clone_from_image' do
28
+ before do
29
+ @cr = FactoryBot.build_stubbed(:proxmox_cr)
30
+ @args = { :name => 'name' }
31
+ @image_id = 100
32
+ @vmid = 101
33
+ @image = mock('vm')
34
+ @image.expects(:clone)
35
+ @cr.stubs(:find_vm_by_uuid).with(@image_id).returns(@image)
36
+ @clone = mock('vm')
37
+ end
38
+ it 'clones server from image' do
39
+ @clone.expects(:update).with(:name => 'name')
40
+ @clone.stubs(:container?).returns(false)
41
+ @cr.stubs(:find_vm_by_uuid).with(@vmid).returns(@clone)
42
+ @cr.clone_from_image(@image_id, @args, @vmid)
43
+ end
44
+ it 'clones container from image' do
45
+ @clone.stubs(:container?).returns(true)
46
+ @clone.expects(:update).with(:hostname => 'name')
47
+ @cr.stubs(:find_vm_by_uuid).with(@vmid).returns(@clone)
48
+ @cr.clone_from_image(@image_id, @args, @vmid)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,117 @@
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 'factories/foreman_fog_proxmox/proxmox_container_mock_factory'
25
+ require 'active_support/core_ext/hash/indifferent_access'
26
+
27
+ module ForemanFogProxmox
28
+ class ProxmoxInterfacesTest < ActiveSupport::TestCase
29
+ include ComputeResourceTestHelpers
30
+ include ProxmoxNodeMockFactory
31
+ include ProxmoxServerMockFactory
32
+ include ProxmoxContainerMockFactory
33
+ include ProxmoxVmHelper
34
+
35
+ describe 'host_interfaces_attrs' do
36
+ before do
37
+ @cr = FactoryBot.build_stubbed(:proxmox_cr)
38
+ end
39
+
40
+ it 'raises Foreman::Exception when physical identifier does not match net[k] with k integer' do
41
+ physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'eth0')
42
+ host = FactoryBot.build(:host_empty, :interfaces => [physical_nic])
43
+ err = assert_raises Foreman::Exception do
44
+ @cr.host_interfaces_attrs(host)
45
+ end
46
+ assert err.message.end_with?('Invalid identifier interface[0]. Must be net[n] with n integer >= 0')
47
+ end
48
+
49
+ it 'sets server compute id with identifier, ip and ip6' do
50
+ ip = '192.168.56.100'
51
+ ip6 = Array.new(4) { format('%<x>s', x: rand(16**4)) }.join(':') + '::1'
52
+ physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6)
53
+ host = FactoryBot.build(
54
+ :host_empty,
55
+ :interfaces => [physical_nic],
56
+ :compute_attributes => {
57
+ 'type' => 'qemu',
58
+ 'interfaces_attributes' => {
59
+ '0' => physical_nic
60
+ }
61
+ }
62
+ )
63
+ nic_attributes = @cr.host_interfaces_attrs(host).values.select(&:present?)
64
+ nic_attr = nic_attributes.first
65
+ assert_equal 'net0', nic_attr[:id]
66
+ assert_equal ip, nic_attr[:ip]
67
+ assert_equal ip6, nic_attr[:ip6]
68
+ end
69
+
70
+ it 'sets container compute id with identifier, ip/CIDR, gw and ip6' do
71
+ ip = '192.168.56.100'
72
+ cidr_suffix = '31'
73
+ ip6 = Array.new(4) { format('%<x>s', x: rand(16**4)) }.join(':') + '::1'
74
+ physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6, :compute_attributes => { 'cidrv4_prefix' => cidr_suffix, 'gwv4' => ip, 'dhcpv6' => '1' })
75
+ host = FactoryBot.build(
76
+ :host_empty,
77
+ :interfaces => [physical_nic],
78
+ :compute_attributes => {
79
+ 'type' => 'lxc',
80
+ 'interfaces_attributes' => {
81
+ '0' => physical_nic
82
+ }
83
+ }
84
+ )
85
+ nic_attributes = @cr.host_interfaces_attrs(host).values.select(&:present?)
86
+ nic_attr = nic_attributes.first
87
+ assert_equal 'net0', nic_attr[:id]
88
+ assert_equal Fog::Proxmox::IpHelper.to_cidr(ip, cidr_suffix), nic_attr[:ip]
89
+ assert_equal ip, nic_attr[:gw]
90
+ assert_equal 'dhcp', nic_attr[:ip6]
91
+ end
92
+
93
+ it 'sets container compute id with identifier, ip DHCP, gw6 and ip6' do
94
+ ip = '192.168.56.100'
95
+ cidr6_suffix = '100'
96
+ ip6 = '2001:0:1234::c1c0:abcd:876'
97
+ physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6, :compute_attributes => { 'cidrv6_prefix' => cidr6_suffix, 'dhcpv4' => '1', 'gwv6' => ip6 })
98
+ host = FactoryBot.build(
99
+ :host_empty,
100
+ :interfaces => [physical_nic],
101
+ :compute_attributes => {
102
+ 'type' => 'lxc',
103
+ 'interfaces_attributes' => {
104
+ '0' => physical_nic
105
+ }
106
+ }
107
+ )
108
+ nic_attributes = @cr.host_interfaces_attrs(host).values.select(&:present?)
109
+ nic_attr = nic_attributes.first
110
+ assert_equal 'net0', nic_attr[:id]
111
+ assert_equal 'dhcp', nic_attr[:ip]
112
+ assert_equal Fog::Proxmox::IpHelper.to_cidr6(ip6, cidr6_suffix), nic_attr[:ip6]
113
+ assert_equal ip6, nic_attr[:gw6]
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,58 @@
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 'factories/foreman_fog_proxmox/proxmox_container_mock_factory'
25
+ require 'active_support/core_ext/hash/indifferent_access'
26
+
27
+ module ForemanFogProxmox
28
+ class ProxmoxTest < ActiveSupport::TestCase
29
+ include ComputeResourceTestHelpers
30
+ include ProxmoxNodeMockFactory
31
+ include ProxmoxServerMockFactory
32
+ include ProxmoxContainerMockFactory
33
+ include ProxmoxVmHelper
34
+
35
+ should validate_presence_of(:url)
36
+ should validate_presence_of(:user)
37
+ should validate_presence_of(:password)
38
+ should allow_value('root@pam').for(:user)
39
+ should_not allow_value('root').for(:user)
40
+ should_not allow_value('a').for(:url)
41
+ should allow_values('http://foo.com', 'http://bar.com/baz').for(:url)
42
+
43
+ test '#associated_host matches any NIC' do
44
+ mac = 'ca:d0:e6:32:16:97'
45
+ host = FactoryBot.create(:host, :mac => mac)
46
+ cr = FactoryBot.build_stubbed(:proxmox_cr)
47
+ vm = mock('vm', :mac => mac)
48
+ assert_equal host, (as_admin { cr.associated_host(vm) })
49
+ end
50
+
51
+ test '#node' do
52
+ node = mock('node')
53
+ cr = FactoryBot.build_stubbed(:proxmox_cr)
54
+ cr.stubs(:node).returns(node)
55
+ assert_equal node, (as_admin { cr.node })
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,94 @@
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
+ supported_6_version = { version: '6.0', release: '1' }.with_indifferent_access
32
+ supported_6_1_version = { version: '6.1', release: '3' }.with_indifferent_access
33
+ unsupported_version = { version: '5.2', release: '2' }.with_indifferent_access
34
+
35
+ describe 'version' do
36
+ before do
37
+ @cr = FactoryBot.build_stubbed(:proxmox_cr)
38
+ @identity_client = mock('identity_client')
39
+ @cr.stubs(:identity_client).returns(@identity_client)
40
+ end
41
+
42
+ it 'returns 5.a.1 with 5.a-1' do
43
+ @identity_client.stubs(:read_version).returns(wrong_version)
44
+ assert_equal '5.a.1', @cr.version
45
+ end
46
+
47
+ it 'returns 5.4.3 with 5.4-3' do
48
+ @identity_client.stubs(:read_version).returns(supported_version)
49
+ assert_equal '5.4.3', @cr.version
50
+ end
51
+
52
+ it 'returns 5.2.2 with 5.2-2' do
53
+ @identity_client.stubs(:read_version).returns(unsupported_version)
54
+ assert_equal '5.2.2', @cr.version
55
+ end
56
+ end
57
+
58
+ describe 'version_suitable?' do
59
+ before do
60
+ @cr = FactoryBot.build_stubbed(:proxmox_cr)
61
+ @identity_client = mock('identity_client')
62
+ @cr.stubs(:identity_client).returns(@identity_client)
63
+ end
64
+
65
+ it 'raises error with 5.a.1' do
66
+ @identity_client.stubs(:read_version).returns(wrong_version)
67
+ err = assert_raises Foreman::Exception do
68
+ @cr.version_suitable?
69
+ end
70
+ assert err.message.end_with?('Proxmox version 5.a.1 is not semver suitable')
71
+ end
72
+
73
+ it 'is true with 5.4-3' do
74
+ @identity_client.stubs(:read_version).returns(supported_version)
75
+ assert @cr.version_suitable?
76
+ end
77
+
78
+ it 'is true with 6.0-1' do
79
+ @identity_client.stubs(:read_version).returns(supported_6_version)
80
+ assert @cr.version_suitable?
81
+ end
82
+
83
+ it 'is true with 6.1-3' do
84
+ @identity_client.stubs(:read_version).returns(supported_6_1_version)
85
+ assert @cr.version_suitable?
86
+ end
87
+
88
+ it 'is false with 5.2-2' do
89
+ @identity_client.stubs(:read_version).returns(unsupported_version)
90
+ assert_not @cr.version_suitable?
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,280 @@
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 'migrates container from one node to another in the cluster' 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
+ vm.stubs(:node_id).returns('pve')
47
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
48
+ attr = { 'templated' => '0', 'node_id' => 'pve', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1', 'onboot' => '0' } }.with_indifferent_access
49
+ @cr.stubs(:parse_container_vm).returns('vmid' => '100', 'node_id' => 'pve2', 'type' => 'lxc', 'cores' => '1', 'cpulimit' => '1')
50
+ expected_attr = { :cores => '1', :cpulimit => '1' }
51
+ vm.expects(:update, expected_attr)
52
+ @cr.save_vm(uuid, attr)
53
+ end
54
+
55
+ it 'saves modified container config' 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(true)
62
+ vm.stubs(:type).returns('lxc')
63
+ vm.stubs(:node_id).returns('pve')
64
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
65
+ attr = { 'templated' => '0', 'node_id' => 'pve', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1', 'onboot' => '0' } }.with_indifferent_access
66
+ @cr.stubs(:parse_container_vm).returns('vmid' => '100', 'node_id' => 'pve', 'type' => 'lxc', 'cores' => '1', 'cpulimit' => '1')
67
+ expected_attr = { :cores => '1', :cpulimit => '1' }
68
+ vm.expects(:update, expected_attr)
69
+ @cr.save_vm(uuid, attr)
70
+ end
71
+
72
+ it 'saves modified container config with added volumes' do
73
+ uuid = '100'
74
+ config = mock('config')
75
+ disks = mock('disks')
76
+ disk = mock('disk')
77
+ disk.stubs(:size).returns(1_073_741_824)
78
+ disk.stubs(:storage).returns('local-lvm')
79
+ disk.stubs(:id).returns('mp0')
80
+ disks.stubs(:get).returns
81
+ config.stubs(:disks).returns(disks)
82
+ config.stubs(:attributes).returns(:cores => '')
83
+ vm = mock('vm')
84
+ vm.stubs(:config).returns(config)
85
+ vm.stubs(:container?).returns(true)
86
+ vm.stubs(:type).returns('lxc')
87
+ vm.stubs(:node_id).returns('pve')
88
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
89
+ new_attributes = {
90
+ 'templated' => '0',
91
+ 'node_id' => 'pve',
92
+ 'config_attributes' => {
93
+ 'cores' => '1',
94
+ 'cpulimit' => '1'
95
+ },
96
+ 'volumes_attributes' => {
97
+ '0' => {
98
+ 'id' => 'mp0',
99
+ '_delete' => '',
100
+ 'device' => '0',
101
+ 'storage' => 'local-lvm',
102
+ 'size' => '2147483648',
103
+ 'cache' => 'none',
104
+ 'mp' => '/opt/path'
105
+ }
106
+ }
107
+ }.with_indifferent_access
108
+ @cr.stubs(:parse_container_vm).returns('vmid' => '100', 'node_id' => 'pve', 'type' => 'lxc', 'cores' => '1', 'cpulimit' => '1')
109
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
110
+ expected_volume_attr =
111
+ [
112
+ {
113
+ id: 'mp0',
114
+ storage: 'local:lvm',
115
+ size: (2_147_483_648 / GIGA).to_s
116
+ },
117
+ {
118
+ mp: '/opt/path'
119
+ }
120
+ ]
121
+ vm.expects(:attach, expected_volume_attr)
122
+ vm.expects(:update, expected_config_attr)
123
+ @cr.save_vm(uuid, new_attributes)
124
+ end
125
+
126
+ it 'saves modified container config with resized volumes' do
127
+ uuid = '100'
128
+ config = mock('config')
129
+ disks = mock('disks')
130
+ disk = mock('disk')
131
+ disk.stubs(:size).returns(1_073_741_824)
132
+ disk.stubs(:storage).returns('local-lvm')
133
+ disk.stubs(:id).returns('rootfs')
134
+ disks.stubs(:get).returns(disk)
135
+ config.stubs(:disks).returns(disks)
136
+ config.stubs(:attributes).returns(:cores => '')
137
+ vm = mock('vm')
138
+ vm.stubs(:config).returns(config)
139
+ vm.stubs(:container?).returns(true)
140
+ vm.stubs(:type).returns('lxc')
141
+ vm.stubs(:node_id).returns('pve')
142
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
143
+ new_attributes =
144
+ {
145
+ 'templated' => '0',
146
+ 'node_id' => 'pve',
147
+ 'config_attributes' => {
148
+ 'cores' => '1',
149
+ 'cpulimit' => '1',
150
+ 'onboot' => '0'
151
+ },
152
+ 'volumes_attributes' => {
153
+ '0' => {
154
+ 'id' => 'rootfs',
155
+ '_delete' => '',
156
+ 'volid' => 'local-lvm:1073741824',
157
+ 'device' => '0',
158
+ 'storage' => 'local-lvm',
159
+ 'size' => '2147483648',
160
+ 'cache' => 'none'
161
+ }
162
+ }
163
+ }.with_indifferent_access
164
+ @cr.stubs(:parse_container_vm).returns(
165
+ 'vmid' => '100',
166
+ 'node_id' => 'pve',
167
+ 'type' => 'lxc',
168
+ 'cores' => '1',
169
+ 'cpulimit' => '1'
170
+ )
171
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
172
+ expected_volume_attr = ['rootfs', '+1G']
173
+ vm.expects(:extend, expected_volume_attr)
174
+ vm.expects(:update, expected_config_attr)
175
+ @cr.save_vm(uuid, new_attributes)
176
+ end
177
+
178
+ it 'saves modified container config with modified volumes options' do
179
+ uuid = '100'
180
+ config = mock('config')
181
+ disks = mock('disks')
182
+ disk = mock('disk')
183
+ disk.stubs(:rootfs?).returns(false)
184
+ disk.stubs(:volid).returns('local-lvm:vm-100-disk-0')
185
+ disk.stubs(:id).returns('mp0')
186
+ disk.stubs(:size).returns(1_073_741_824)
187
+ disk.stubs(:storage).returns('local-lvm')
188
+ disks.stubs(:get).returns(disk)
189
+ config.stubs(:disks).returns(disks)
190
+ config.stubs(:attributes).returns(:cores => '')
191
+ vm = mock('vm')
192
+ vm.stubs(:config).returns(config)
193
+ vm.stubs(:container?).returns(true)
194
+ vm.stubs(:type).returns('lxc')
195
+ vm.stubs(:node_id).returns('pve')
196
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
197
+ new_attributes = {
198
+ 'templated' => '0',
199
+ 'node_id' => 'pve',
200
+ 'config_attributes' => {
201
+ 'cores' => '1',
202
+ 'cpulimit' => '1'
203
+ },
204
+ 'volumes_attributes' => {
205
+ '0' => {
206
+ 'id' => 'mp0',
207
+ '_delete' => '',
208
+ 'volid' => 'local-lvm:vm-100-disk-0',
209
+ 'device' => '0',
210
+ 'controller' => 'mp',
211
+ 'storage' => 'local-lvm',
212
+ 'size' => '1073741824',
213
+ 'mp' => '/opt/toto'
214
+ }
215
+ }
216
+ }.with_indifferent_access
217
+ @cr.stubs(:parse_server_vm).returns('vmid' => '100', 'node_id' => 'pve', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1')
218
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
219
+ expected_volume_attr = { :id => 'mp0', :volid => 'local-lvm:vm-100-disk-0', :size => 1_073_741_824 }, { :mp => '/opt/toto' }
220
+ vm.expects(:attach, expected_volume_attr)
221
+ vm.expects(:update, expected_config_attr)
222
+ @cr.save_vm(uuid, new_attributes)
223
+ end
224
+ end
225
+
226
+ describe 'create_vm' do
227
+ it 'creates container without bootstart' do
228
+ args = { vmid: '100', type: 'lxc', node_id: 'pve', start_after_create: '0' }
229
+ servers = mock('servers')
230
+ servers.stubs(:id_valid?).returns(true)
231
+ containers = mock('containers')
232
+ containers.stubs(:create).with(vmid: 100, type: 'lxc', node_id: 'pve', start_after_create: '0')
233
+ cr = mock_node_servers_containers(ForemanFogProxmox::Proxmox.new, servers, containers)
234
+ cr.stubs(:convert_sizes).with(args)
235
+ cr.stubs(:parse_container_vm).with(args).returns(args)
236
+ vm = mock('vm')
237
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
238
+ cr.create_vm(args)
239
+ end
240
+
241
+ it 'creates container with bootstart' do
242
+ args = { vmid: '100', type: 'lxc', node_id: 'pve', start_after_create: '1' }
243
+ servers = mock('servers')
244
+ servers.stubs(:id_valid?).returns(true)
245
+ containers = mock('containers')
246
+ vm = mock('vm')
247
+ containers.stubs(:create).with(vmid: 100, type: 'lxc', node_id: 'pve', start_after_create: '1').returns(vm)
248
+ cr = mock_node_servers_containers(ForemanFogProxmox::Proxmox.new, servers, containers)
249
+ cr.stubs(:convert_sizes).with(args)
250
+ cr.stubs(:parse_container_vm).with(args).returns(args)
251
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
252
+ cr.stubs(:start_on_boot).with(vm, args).returns(vm)
253
+ cr.create_vm(args)
254
+ end
255
+
256
+ it 'creates container within pool' do
257
+ args = { vmid: '100', type: 'lxc', node_id: 'pve', start_after_create: '0', pool: 'pool1' }
258
+ servers = mock('servers')
259
+ servers.stubs(:id_valid?).returns(true)
260
+ containers = mock('containers')
261
+ vm = mock('vm')
262
+ containers.stubs(:create).with(vmid: 100, type: 'lxc', node_id: 'pve', start_after_create: '0', pool: 'pool1').returns(vm)
263
+ cr = mock_node_servers_containers(ForemanFogProxmox::Proxmox.new, servers, containers)
264
+ cr.stubs(:convert_sizes).with(args)
265
+ cr.stubs(:parse_container_vm).with(args).returns(args)
266
+ cr.stubs(:find_vm_by_uuid).with((args[:vmid]).to_s).returns(vm)
267
+ cr.create_vm(args)
268
+ end
269
+
270
+ it 'clones container' do
271
+ args = { vmid: '100', type: 'lxc', image_id: '999', name: 'name' }
272
+ servers = mock('servers')
273
+ servers.stubs(:id_valid?).returns(true)
274
+ cr = mock_node_servers(ForemanFogProxmox::Proxmox.new, servers)
275
+ cr.expects(:clone_from_image).with('999', args, 100)
276
+ cr.create_vm(args)
277
+ end
278
+ end
279
+ end
280
+ end