fog-proxmox-configlmm 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +8 -0
  3. data/LICENSE +674 -0
  4. data/README.md +110 -0
  5. data/docs/compute.md +874 -0
  6. data/docs/connection_parameters.md +45 -0
  7. data/docs/getting_started.md +53 -0
  8. data/docs/identity.md +382 -0
  9. data/examples/compute.rb +276 -0
  10. data/examples/identity.rb +203 -0
  11. data/lib/fog/proxmox/attributes.rb +34 -0
  12. data/lib/fog/proxmox/auth/token/access_ticket.rb +96 -0
  13. data/lib/fog/proxmox/auth/token/user_token.rb +107 -0
  14. data/lib/fog/proxmox/auth/token.rb +94 -0
  15. data/lib/fog/proxmox/compute/models/disk.rb +94 -0
  16. data/lib/fog/proxmox/compute/models/disks.rb +55 -0
  17. data/lib/fog/proxmox/compute/models/interface.rb +56 -0
  18. data/lib/fog/proxmox/compute/models/interfaces.rb +44 -0
  19. data/lib/fog/proxmox/compute/models/node.rb +93 -0
  20. data/lib/fog/proxmox/compute/models/nodes.rb +39 -0
  21. data/lib/fog/proxmox/compute/models/server.rb +271 -0
  22. data/lib/fog/proxmox/compute/models/server_config.rb +161 -0
  23. data/lib/fog/proxmox/compute/models/servers.rb +80 -0
  24. data/lib/fog/proxmox/compute/models/snapshot.rb +83 -0
  25. data/lib/fog/proxmox/compute/models/snapshots.rb +47 -0
  26. data/lib/fog/proxmox/compute/models/storage.rb +65 -0
  27. data/lib/fog/proxmox/compute/models/storages.rb +51 -0
  28. data/lib/fog/proxmox/compute/models/task.rb +79 -0
  29. data/lib/fog/proxmox/compute/models/tasks.rb +65 -0
  30. data/lib/fog/proxmox/compute/models/volume.rb +68 -0
  31. data/lib/fog/proxmox/compute/models/volumes.rb +58 -0
  32. data/lib/fog/proxmox/compute/requests/action_server.rb +45 -0
  33. data/lib/fog/proxmox/compute/requests/clone_server.rb +44 -0
  34. data/lib/fog/proxmox/compute/requests/create_backup.rb +42 -0
  35. data/lib/fog/proxmox/compute/requests/create_server.rb +43 -0
  36. data/lib/fog/proxmox/compute/requests/create_snapshot.rb +46 -0
  37. data/lib/fog/proxmox/compute/requests/create_spice.rb +44 -0
  38. data/lib/fog/proxmox/compute/requests/create_term.rb +45 -0
  39. data/lib/fog/proxmox/compute/requests/create_vnc.rb +44 -0
  40. data/lib/fog/proxmox/compute/requests/delete_server.rb +45 -0
  41. data/lib/fog/proxmox/compute/requests/delete_snapshot.rb +47 -0
  42. data/lib/fog/proxmox/compute/requests/delete_volume.rb +40 -0
  43. data/lib/fog/proxmox/compute/requests/get_node_statistics.rb +44 -0
  44. data/lib/fog/proxmox/compute/requests/get_server_config.rb +60 -0
  45. data/lib/fog/proxmox/compute/requests/get_server_status.rb +63 -0
  46. data/lib/fog/proxmox/compute/requests/get_snapshot_config.rb +44 -0
  47. data/lib/fog/proxmox/compute/requests/get_task.rb +41 -0
  48. data/lib/fog/proxmox/compute/requests/get_vnc.rb +45 -0
  49. data/lib/fog/proxmox/compute/requests/get_volume.rb +42 -0
  50. data/lib/fog/proxmox/compute/requests/list_nodes.rb +48 -0
  51. data/lib/fog/proxmox/compute/requests/list_servers.rb +113 -0
  52. data/lib/fog/proxmox/compute/requests/list_snapshots.rb +66 -0
  53. data/lib/fog/proxmox/compute/requests/list_storages.rb +46 -0
  54. data/lib/fog/proxmox/compute/requests/list_tasks.rb +44 -0
  55. data/lib/fog/proxmox/compute/requests/list_volumes.rb +44 -0
  56. data/lib/fog/proxmox/compute/requests/log_task.rb +44 -0
  57. data/lib/fog/proxmox/compute/requests/migrate_server.rb +44 -0
  58. data/lib/fog/proxmox/compute/requests/move_disk.rb +43 -0
  59. data/lib/fog/proxmox/compute/requests/move_volume.rb +43 -0
  60. data/lib/fog/proxmox/compute/requests/next_vmid.rb +42 -0
  61. data/lib/fog/proxmox/compute/requests/resize_container.rb +43 -0
  62. data/lib/fog/proxmox/compute/requests/resize_server.rb +43 -0
  63. data/lib/fog/proxmox/compute/requests/rollback_snapshot.rb +48 -0
  64. data/lib/fog/proxmox/compute/requests/status_task.rb +41 -0
  65. data/lib/fog/proxmox/compute/requests/stop_task.rb +41 -0
  66. data/lib/fog/proxmox/compute/requests/template_server.rb +44 -0
  67. data/lib/fog/proxmox/compute/requests/update_server.rb +44 -0
  68. data/lib/fog/proxmox/compute/requests/update_snapshot.rb +45 -0
  69. data/lib/fog/proxmox/compute.rb +141 -0
  70. data/lib/fog/proxmox/core.rb +147 -0
  71. data/lib/fog/proxmox/errors.rb +65 -0
  72. data/lib/fog/proxmox/hash.rb +37 -0
  73. data/lib/fog/proxmox/helpers/controller_helper.rb +63 -0
  74. data/lib/fog/proxmox/helpers/cpu_helper.rb +88 -0
  75. data/lib/fog/proxmox/helpers/disk_helper.rb +185 -0
  76. data/lib/fog/proxmox/helpers/ip_helper.rb +101 -0
  77. data/lib/fog/proxmox/helpers/nic_helper.rb +132 -0
  78. data/lib/fog/proxmox/identity/models/domain.rb +69 -0
  79. data/lib/fog/proxmox/identity/models/domain_type.rb +47 -0
  80. data/lib/fog/proxmox/identity/models/domains.rb +44 -0
  81. data/lib/fog/proxmox/identity/models/group.rb +51 -0
  82. data/lib/fog/proxmox/identity/models/groups.rb +44 -0
  83. data/lib/fog/proxmox/identity/models/permission.rb +66 -0
  84. data/lib/fog/proxmox/identity/models/permissions.rb +46 -0
  85. data/lib/fog/proxmox/identity/models/pool.rb +89 -0
  86. data/lib/fog/proxmox/identity/models/pools.rb +46 -0
  87. data/lib/fog/proxmox/identity/models/principal.rb +42 -0
  88. data/lib/fog/proxmox/identity/models/role.rb +48 -0
  89. data/lib/fog/proxmox/identity/models/roles.rb +44 -0
  90. data/lib/fog/proxmox/identity/models/token.rb +72 -0
  91. data/lib/fog/proxmox/identity/models/token_info.rb +41 -0
  92. data/lib/fog/proxmox/identity/models/tokens.rb +54 -0
  93. data/lib/fog/proxmox/identity/models/user.rb +82 -0
  94. data/lib/fog/proxmox/identity/models/users.rb +44 -0
  95. data/lib/fog/proxmox/identity/requests/change_password.rb +41 -0
  96. data/lib/fog/proxmox/identity/requests/check_permissions.rb +41 -0
  97. data/lib/fog/proxmox/identity/requests/create_domain.rb +40 -0
  98. data/lib/fog/proxmox/identity/requests/create_group.rb +40 -0
  99. data/lib/fog/proxmox/identity/requests/create_pool.rb +40 -0
  100. data/lib/fog/proxmox/identity/requests/create_role.rb +40 -0
  101. data/lib/fog/proxmox/identity/requests/create_token.rb +40 -0
  102. data/lib/fog/proxmox/identity/requests/create_user.rb +40 -0
  103. data/lib/fog/proxmox/identity/requests/delete_domain.rb +40 -0
  104. data/lib/fog/proxmox/identity/requests/delete_group.rb +40 -0
  105. data/lib/fog/proxmox/identity/requests/delete_pool.rb +39 -0
  106. data/lib/fog/proxmox/identity/requests/delete_role.rb +40 -0
  107. data/lib/fog/proxmox/identity/requests/delete_token.rb +40 -0
  108. data/lib/fog/proxmox/identity/requests/delete_user.rb +39 -0
  109. data/lib/fog/proxmox/identity/requests/get_domain.rb +41 -0
  110. data/lib/fog/proxmox/identity/requests/get_group.rb +41 -0
  111. data/lib/fog/proxmox/identity/requests/get_pool.rb +41 -0
  112. data/lib/fog/proxmox/identity/requests/get_role.rb +41 -0
  113. data/lib/fog/proxmox/identity/requests/get_token_info.rb +41 -0
  114. data/lib/fog/proxmox/identity/requests/get_user.rb +41 -0
  115. data/lib/fog/proxmox/identity/requests/list_domains.rb +41 -0
  116. data/lib/fog/proxmox/identity/requests/list_groups.rb +41 -0
  117. data/lib/fog/proxmox/identity/requests/list_permissions.rb +41 -0
  118. data/lib/fog/proxmox/identity/requests/list_pools.rb +41 -0
  119. data/lib/fog/proxmox/identity/requests/list_roles.rb +40 -0
  120. data/lib/fog/proxmox/identity/requests/list_tokens.rb +41 -0
  121. data/lib/fog/proxmox/identity/requests/list_user_permissions.rb +44 -0
  122. data/lib/fog/proxmox/identity/requests/list_users.rb +42 -0
  123. data/lib/fog/proxmox/identity/requests/read_version.rb +39 -0
  124. data/lib/fog/proxmox/identity/requests/update_domain.rb +41 -0
  125. data/lib/fog/proxmox/identity/requests/update_group.rb +40 -0
  126. data/lib/fog/proxmox/identity/requests/update_permissions.rb +41 -0
  127. data/lib/fog/proxmox/identity/requests/update_pool.rb +41 -0
  128. data/lib/fog/proxmox/identity/requests/update_role.rb +41 -0
  129. data/lib/fog/proxmox/identity/requests/update_token.rb +41 -0
  130. data/lib/fog/proxmox/identity/requests/update_user.rb +41 -0
  131. data/lib/fog/proxmox/identity.rb +144 -0
  132. data/lib/fog/proxmox/json.rb +32 -0
  133. data/lib/fog/proxmox/network/models/network.rb +76 -0
  134. data/lib/fog/proxmox/network/models/networks.rb +48 -0
  135. data/lib/fog/proxmox/network/models/node.rb +75 -0
  136. data/lib/fog/proxmox/network/models/nodes.rb +39 -0
  137. data/lib/fog/proxmox/network/requests/create_network.rb +41 -0
  138. data/lib/fog/proxmox/network/requests/delete_network.rb +42 -0
  139. data/lib/fog/proxmox/network/requests/get_network.rb +43 -0
  140. data/lib/fog/proxmox/network/requests/get_node.rb +41 -0
  141. data/lib/fog/proxmox/network/requests/list_networks.rb +43 -0
  142. data/lib/fog/proxmox/network/requests/list_nodes.rb +42 -0
  143. data/lib/fog/proxmox/network/requests/power_node.rb +43 -0
  144. data/lib/fog/proxmox/network/requests/update_network.rb +42 -0
  145. data/lib/fog/proxmox/network.rb +90 -0
  146. data/lib/fog/proxmox/storage/requests/create.rb +23 -0
  147. data/lib/fog/proxmox/storage/requests/download_appliance.rb +24 -0
  148. data/lib/fog/proxmox/storage/requests/list.rb +22 -0
  149. data/lib/fog/proxmox/storage/requests/list_appliances.rb +23 -0
  150. data/lib/fog/proxmox/storage/requests/upload.rb +44 -0
  151. data/lib/fog/proxmox/storage.rb +82 -0
  152. data/lib/fog/proxmox/string.rb +32 -0
  153. data/lib/fog/proxmox/variables.rb +40 -0
  154. data/lib/fog/proxmox/version.rb +24 -0
  155. data/lib/fog/proxmox.rb +53 -0
  156. data/spec/compute_spec.rb +447 -0
  157. data/spec/fixtures/proxmox/compute/common_auth.yml +40 -0
  158. data/spec/fixtures/proxmox/compute/containers.yml +6921 -0
  159. data/spec/fixtures/proxmox/compute/nodes.yml +115 -0
  160. data/spec/fixtures/proxmox/compute/servers.yml +19011 -0
  161. data/spec/fixtures/proxmox/compute/snapshots.yml +1376 -0
  162. data/spec/fixtures/proxmox/compute/storages.yml +151 -0
  163. data/spec/fixtures/proxmox/compute/tasks.yml +465 -0
  164. data/spec/fixtures/proxmox/identity/auth.yml +42 -0
  165. data/spec/fixtures/proxmox/identity/auth_access_ticket.yml +77 -0
  166. data/spec/fixtures/proxmox/identity/auth_user_token.yml +77 -0
  167. data/spec/fixtures/proxmox/identity/common_auth.yml +40 -0
  168. data/spec/fixtures/proxmox/identity/domains.yml +665 -0
  169. data/spec/fixtures/proxmox/identity/groups.yml +345 -0
  170. data/spec/fixtures/proxmox/identity/permissions.yml +911 -0
  171. data/spec/fixtures/proxmox/identity/pools.yml +946 -0
  172. data/spec/fixtures/proxmox/identity/read_version.yml +40 -0
  173. data/spec/fixtures/proxmox/identity/roles.yml +345 -0
  174. data/spec/fixtures/proxmox/identity/tokens.yml +494 -0
  175. data/spec/fixtures/proxmox/identity/users.yml +725 -0
  176. data/spec/fixtures/proxmox/network/common_auth.yml +40 -0
  177. data/spec/fixtures/proxmox/network/networks.yml +375 -0
  178. data/spec/fixtures/proxmox/pve.home +34 -0
  179. data/spec/hash_spec.rb +43 -0
  180. data/spec/helpers/controller_helper_spec.rb +157 -0
  181. data/spec/helpers/cpu_helper_spec.rb +82 -0
  182. data/spec/helpers/disk_helper_spec.rb +304 -0
  183. data/spec/helpers/ip_helper_spec.rb +177 -0
  184. data/spec/helpers/nic_helper_spec.rb +144 -0
  185. data/spec/identity_spec.rb +416 -0
  186. data/spec/network_spec.rb +67 -0
  187. data/spec/proxmox_vcr.rb +97 -0
  188. data/spec/spec_helper.rb +41 -0
  189. metadata +566 -0
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Tristan Robert
4
+
5
+ # This file is part of Fog::Proxmox.
6
+
7
+ # Fog::Proxmox 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
+ # Fog::Proxmox 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 Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module Fog
21
+ module Proxmox
22
+ # module String mixins
23
+ module String
24
+ def self.to_boolean(text)
25
+ return true if text == true || text =~ (/(true|t|yes|y|1)$/i)
26
+ return false if text == false || text.empty? || text =~ (/(false|f|no|n|0)$/i)
27
+
28
+ raise ArgumentError, "invalid value for Boolean: \"#{text}\""
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Tristan Robert
4
+
5
+ # This file is part of Fog::Proxmox.
6
+
7
+ # Fog::Proxmox 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
+ # Fog::Proxmox 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 Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module Fog
21
+ module Proxmox
22
+ # module Variables mixins
23
+ module Variables
24
+ def self.to_variables(instance, hash, prefix)
25
+ hash.select { |key| key.to_s.start_with? prefix }.each do |key, value|
26
+ instance.instance_variable_set "@#{key}".to_sym, value
27
+ end
28
+ end
29
+
30
+ def self.to_hash(instance, prefix)
31
+ hash = {}
32
+ instance.instance_variables.select { |variable| variable.to_s.start_with? '@' + prefix }.each do |param|
33
+ name = param.to_s[1..-1]
34
+ hash.store(name.to_sym, instance.instance_variable_get(param))
35
+ end
36
+ hash
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Tristan Robert
4
+
5
+ # This file is part of Fog::Proxmox.
6
+
7
+ # Fog::Proxmox 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
+ # Fog::Proxmox 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 Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module Fog
21
+ module Proxmox
22
+ VERSION = '0.15.0'
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ # Copyright 2018 Tristan Robert
3
+
4
+ # This file is part of Fog::Proxmox.
5
+
6
+ # Fog::Proxmox is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+
11
+ # Fog::Proxmox is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ # frozen_string_literal: true
20
+
21
+ require 'fog/core'
22
+ require 'fog/json'
23
+
24
+ module Fog
25
+ # Proxmox module
26
+ module Proxmox
27
+ require 'fog/proxmox/auth/token'
28
+
29
+ autoload :Core, 'fog/proxmox/core'
30
+ autoload :Errors, 'fog/proxmox/errors'
31
+ autoload :Identity, 'fog/proxmox/identity'
32
+ autoload :Compute, 'fog/proxmox/compute'
33
+ autoload :Storage, 'fog/proxmox/storage'
34
+ autoload :Network, 'fog/proxmox/network'
35
+
36
+ extend Fog::Provider
37
+
38
+ service(:identity, 'Identity')
39
+ service(:compute, 'Compute')
40
+ service(:storage, 'Storage')
41
+ service(:network, 'Network')
42
+
43
+ @token_cache = {}
44
+
45
+ class << self
46
+ attr_accessor :token_cache
47
+ end
48
+
49
+ def self.clear_token_cache
50
+ Fog::Proxmox.token_cache = {}
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,447 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Tristan Robert
4
+
5
+ # This file is part of Fog::Proxmox.
6
+
7
+ # Fog::Proxmox 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
+ # Fog::Proxmox 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 Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ require 'spec_helper'
21
+ require_relative './proxmox_vcr'
22
+
23
+ describe Fog::Proxmox::Compute do
24
+ before :all do
25
+ @proxmox_vcr = ProxmoxVCR.new(
26
+ vcr_directory: 'spec/fixtures/proxmox/compute',
27
+ service_class: Fog::Proxmox::Compute
28
+ )
29
+ @service = @proxmox_vcr.service
30
+ @proxmox_url = @proxmox_vcr.url
31
+ @username = @proxmox_vcr.username
32
+ @password = @proxmox_vcr.password
33
+ @tokenid = @proxmox_vcr.tokenid
34
+ @token = @proxmox_vcr.token
35
+ end
36
+
37
+ it 'Manage tasks' do
38
+ VCR.use_cassette('tasks') do
39
+ # List all tasks
40
+ filters = { limit: 1 }
41
+ node_name = 'pve'
42
+ node = @service.nodes.get node_name
43
+ tasks = node.tasks.all(filters)
44
+ _(tasks).wont_be_nil
45
+ _(tasks).wont_be_empty
46
+ _(tasks.size).must_equal 1
47
+ # Get task
48
+ upid = tasks[0].upid
49
+ task = node.tasks.get(upid)
50
+ _(task).wont_be_nil
51
+ # Stop task
52
+ task.stop
53
+ task.wait_for { finished? }
54
+ _(task.finished?).must_equal true
55
+ end
56
+ end
57
+
58
+ it 'Manage nodes' do
59
+ VCR.use_cassette('nodes') do
60
+ # Get node
61
+ node_name = 'pve'
62
+ node = @service.nodes.get node_name
63
+ # Get statistics data
64
+ data = node.statistics
65
+ _(data).wont_be_nil
66
+ _(data).wont_be_empty
67
+ # Get statistics image
68
+ data = node.statistics('rrd', { timeframe: 'hour', ds: 'cpu,memused', cf: 'AVERAGE' })
69
+ _(data).wont_be_nil
70
+ _(data['image']).wont_be_nil
71
+ end
72
+ end
73
+
74
+ it 'Manage storages' do
75
+ VCR.use_cassette('storages') do
76
+ # Get node
77
+ node_name = 'pve'
78
+ node = @service.nodes.get node_name
79
+ # List all storages
80
+ storages = node.storages.all
81
+ _(storages).wont_be_nil
82
+ _(storages).wont_be_empty
83
+ _(storages.size).must_equal 2
84
+ # List by content type
85
+ storages = node.storages.list_by_content_type 'iso'
86
+ _(storages).wont_be_nil
87
+ _(storages).wont_be_empty
88
+ _(storages.size).must_equal 1
89
+ # Get storage
90
+ storage = node.storages.get('local')
91
+ _(storage).wont_be_nil
92
+ _(storage.identity).must_equal 'local'
93
+ end
94
+ end
95
+
96
+ it 'CRUD servers' do
97
+ VCR.use_cassette('servers') do
98
+ node_name = 'pve'
99
+ node = @service.nodes.get node_name
100
+ # Get next vmid
101
+ vmid = node.servers.next_id
102
+ server_hash = { vmid: vmid }
103
+ # Check valid vmid
104
+ valid = node.servers.id_valid? vmid
105
+ _(valid).must_equal true
106
+ # Check not valid vmid
107
+ valid = node.servers.id_valid? 99
108
+ _(valid).must_equal false
109
+ # Create 1st time
110
+ server = node.servers.create(server_hash)
111
+ ok = server.persisted?
112
+ _(ok).must_equal true
113
+ # Check already used vmid
114
+ valid = node.servers.id_valid? vmid
115
+ _(valid).must_equal false
116
+ # Clone server
117
+ newid = node.servers.next_id
118
+ # Get server
119
+ server = node.servers.get vmid
120
+ _(server).wont_be_nil
121
+ # Backup it
122
+ server.backup(compress: 'lzo')
123
+ # Get this backup image
124
+ # Find available backup volumes
125
+ volume = server.backups.first
126
+ _(volume).wont_be_nil
127
+ # Restore it
128
+ server.restore(volume, storage: 'local')
129
+ # Delete it
130
+ volume.destroy
131
+ # Add hdd
132
+ # Find available storages with images
133
+ storages = node.storages.list_by_content_type 'images'
134
+ storage = storages[0]
135
+ virtio0 = { id: 'virtio0', storage: storage.storage, size: '1' }
136
+ ide0 = { id: 'ide0', storage: storage.storage, size: '1' }
137
+ options = { backup: 0, replicate: 0 }
138
+ server.attach(virtio0, options)
139
+ server.attach(ide0, options)
140
+ server.detach('ide0')
141
+ server.detach('unused0')
142
+ sleep 1
143
+ # Clone it (linked fails)
144
+ server.clone(newid, full: 1)
145
+ # Get clone
146
+ clone = node.servers.get newid
147
+ # Template this clone (read-only)
148
+ clone.create_template
149
+ # Get clone disk image
150
+ image = clone.images.first
151
+ _(image).wont_be_nil
152
+ # Delete clone
153
+ clone.destroy
154
+ _(proc do
155
+ clone = node.servers.get newid
156
+ end).must_raise Fog::Errors::NotFound
157
+ # Create 2nd time must fails
158
+ _(proc do
159
+ node.servers.create server_hash
160
+ end).must_raise Excon::Errors::InternalServerError
161
+ # Update config server
162
+ # Add empty cdrom
163
+ config_hash = { ide2: 'none,media=cdrom' }
164
+ server.update(config_hash)
165
+ # Resize disk server
166
+ server.extend('virtio0', '+1G')
167
+ # Move disk server
168
+ server.move('virtio0', 'local')
169
+ # Add network interface
170
+ config_hash = { net0: 'virtio,bridge=vmbr0' }
171
+ server.update(config_hash)
172
+ # Add start at boot, keyboard fr,
173
+ # linux 4.x os type, kvm hardware disabled (proxmox guest in virtualbox) and vga enabled to console
174
+ config_hash = { onboot: 1, keyboard: 'fr', ostype: 'l26', kvm: 0 }
175
+ server.update(config_hash)
176
+ # server config
177
+ config = server.config
178
+ _(config.identity).must_equal vmid
179
+ disks = server.config.disks
180
+ interfaces = server.config.interfaces
181
+ _(interfaces).wont_be_nil
182
+ _(interfaces).wont_be_empty
183
+ net0 = interfaces.get('net0')
184
+ _(net0).wont_be_nil
185
+ _(disks).wont_be_nil
186
+ _(disks).wont_be_empty
187
+ virtio0 = disks.get('virtio0')
188
+ _(virtio0).wont_be_nil
189
+ ide2 = disks.get('ide2')
190
+ _(ide2).wont_be_nil
191
+ # Get a mac adress
192
+ mac_address = server.config.mac_addresses.first
193
+ _(mac_address).wont_be_nil
194
+ # all servers
195
+ servers_all = node.servers.all
196
+ _(servers_all).wont_be_empty
197
+ _(servers_all).must_include server
198
+ # server not running exception
199
+ _(proc do
200
+ server.start_console(websocket: 1)
201
+ end).must_raise Fog::Proxmox::Errors::ServiceError
202
+ # Start server
203
+ server.action('start')
204
+ server.wait_for { ready? }
205
+ status = server.ready?
206
+ _(status).must_equal true
207
+ # server vga not set exception
208
+ _(proc do
209
+ server.start_console(websocket: 1)
210
+ end).must_raise Fog::Proxmox::Errors::ServiceError
211
+ # Stop server
212
+ server.action('stop')
213
+ server.wait_for { server.status == 'stopped' }
214
+ status = server.status
215
+ _(status).must_equal 'stopped'
216
+ server.update(vga: 'std')
217
+ # Start server
218
+ server.action('start')
219
+ server.wait_for { ready? }
220
+ status = server.ready?
221
+ _(status).must_equal true
222
+ vnc = server.start_console(websocket: 1)
223
+ _(vnc['cert']).wont_be_nil
224
+ port = server.connect_vnc(vnc)
225
+ _(port).wont_be_nil
226
+ # Stop server
227
+ server.action('stop')
228
+ server.wait_for { server.status == 'stopped' }
229
+ status = server.status
230
+ _(status).must_equal 'stopped'
231
+ server.update(serial0: 'socket', vga: 'serial0')
232
+ # Start server
233
+ server.action('start')
234
+ server.wait_for { ready? }
235
+ status = server.ready?
236
+ _(status).must_equal true
237
+ term = server.start_console
238
+ _(term['ticket']).wont_be_nil
239
+ # Stop server
240
+ server.action('stop')
241
+ server.wait_for { server.status == 'stopped' }
242
+ status = server.status
243
+ _(status).must_equal 'stopped'
244
+ server.update(vga: 'qxl')
245
+ # Start server
246
+ server.action('start')
247
+ server.wait_for { ready? }
248
+ status = server.ready?
249
+ _(status).must_equal true
250
+ spice = server.start_console
251
+ _(spice['password']).wont_be_nil
252
+ # Suspend server
253
+ server.action('suspend')
254
+ server.wait_for { server.qmpstatus == 'paused' }
255
+ qmpstatus = server.qmpstatus
256
+ _(qmpstatus).must_equal 'paused'
257
+ # Resume server
258
+ server.action('resume')
259
+ server.wait_for { ready? }
260
+ status = server.ready?
261
+ _(status).must_equal true
262
+ # Stop server
263
+ server.action('stop')
264
+ server.wait_for { server.status == 'stopped' }
265
+ status = server.status
266
+ _(status).must_equal 'stopped'
267
+ _(proc do
268
+ server.action('hello')
269
+ end).must_raise Fog::Errors::Error
270
+ # Delete
271
+ server.destroy
272
+ _(proc do
273
+ node.servers.get vmid
274
+ end).must_raise Fog::Errors::NotFound
275
+ end
276
+ end
277
+
278
+ it 'CRUD snapshots' do
279
+ VCR.use_cassette('snapshots') do
280
+ node_name = 'proxmox-noris'
281
+ node = @service.nodes.get node_name
282
+ vmid = node.servers.next_id
283
+ server_hash = { vmid: vmid }
284
+ node.servers.create server_hash
285
+ # Create
286
+ snapname = 'snapshot1'
287
+ vmstate = 0
288
+ server = node.servers.get vmid
289
+ snapshot_hash = { name: snapname, vmstate: vmstate }
290
+ server.snapshots.create(snapshot_hash)
291
+ # Find by id
292
+ snapshot = server.snapshots.get snapname
293
+ _(snapshot).wont_be_nil
294
+ # Update
295
+ snapshot.description = 'Snapshot 1'
296
+ snapshot.update
297
+ # all snapshots
298
+ snapshots_all = server.snapshots.all
299
+ _(snapshots_all).wont_be_nil
300
+ _(snapshots_all).wont_be_empty
301
+ _(snapshots_all).must_include snapshot
302
+ # Delete
303
+ snapshot.destroy
304
+ server.destroy
305
+ end
306
+ end
307
+
308
+ it 'CRUD containers' do
309
+ VCR.use_cassette('containers') do
310
+ node_name = 'pve'
311
+ node = @service.nodes.get node_name
312
+ _(node).wont_be_nil
313
+ # Get next vmid
314
+ vmid = node.containers.next_id
315
+ ostemplate = 'local:vztmpl/alpine-3.12-default_20200823_amd64.tar.xz'
316
+ container_hash = { ostemplate: ostemplate, storage: 'local-lvm', password: 'proxmox01', rootfs: 'local-lvm:1' }
317
+ # Check valid vmid
318
+ valid = node.containers.id_valid? vmid
319
+ _(valid).must_equal true
320
+ # Check not valid vmid
321
+ valid = node.containers.id_valid? 99
322
+ _(valid).must_equal false
323
+ # Create 1st time
324
+ node.containers.create(container_hash.merge(vmid: vmid))
325
+ # Check already used vmid
326
+ valid = node.containers.id_valid? vmid
327
+ _(valid).must_equal false
328
+ # Clone container
329
+ newid = node.containers.next_id
330
+ # Get container
331
+ container = node.containers.get vmid
332
+ _(container).wont_be_nil
333
+ rootfs_a = container.config.disks.select { |disk| disk.rootfs? }
334
+ _(rootfs_a).wont_be_empty
335
+ rootfs = rootfs_a.first
336
+ _(rootfs).wont_be_nil
337
+ # Backup it
338
+ container.backup(compress: 'lzo')
339
+ # Get this backup image
340
+ # Find available backup volumes
341
+ backup = container.backups.first
342
+ _(container).wont_be_nil
343
+ # Restore it
344
+ container.restore(backup, storage: 'local-lvm')
345
+ # Delete it
346
+ backup.destroy
347
+ _(container.backups).must_be_empty
348
+ # Add mount points
349
+ # Find available storages with images
350
+ storages = node.storages.list_by_content_type 'images'
351
+ storage = storages[0]
352
+ mp0 = { id: 'mp0', storage: storage.storage, size: '1' }
353
+ options = { mp: '/opt/app', backup: 0, replicate: 0, quota: 1 }
354
+ container.attach(mp0, options)
355
+ # Fetch mount points
356
+ mount_points = container.config.disks.select { |disk| disk.mount_point? }
357
+ _(mount_points).wont_be_empty
358
+ _(mount_points.get('mp0')).wont_be_nil
359
+ # Remove mount points
360
+ container.detach('mp0')
361
+ container.detach('unused0')
362
+ sleep 1
363
+ # Clone it
364
+ container.clone(newid)
365
+ # Get clone
366
+ clone = node.containers.get newid
367
+ # Template this clone (read-only)
368
+ clone.template
369
+ # Get clone disk image
370
+ image = clone.images.first
371
+ _(image).wont_be_nil
372
+ # Delete clone
373
+ clone.destroy
374
+ _(proc do
375
+ node.containers.get newid
376
+ end).must_raise Fog::Errors::NotFound
377
+ # Create 2nd time must fails
378
+ _(proc do
379
+ node.containers.create(container_hash.merge(vmid: vmid))
380
+ end).must_raise Excon::Errors::InternalServerError
381
+ # Update config container
382
+ # Resize rootfs container
383
+ container.extend('rootfs', '+5M')
384
+ # Move rootfs container and delete original
385
+ container.move('rootfs', 'local-lvm', delete: 1)
386
+ # Add network interface
387
+ config_hash = { net0: 'bridge=vmbr0,name=eth0,ip=dhcp,ip6=dhcp' }
388
+ container.update(config_hash)
389
+ # Add start at boot, keyboard fr,
390
+ # linux os type alpine
391
+ config_hash = { onboot: 1, ostype: 'alpine' }
392
+ container.update(config_hash)
393
+ # get container config
394
+ config = container.config
395
+ _(config).wont_be_nil
396
+ _(config.identity).must_equal vmid
397
+ # Fetch nics
398
+ interfaces = container.config.interfaces
399
+ _(interfaces).wont_be_empty
400
+ _(interfaces.get('net0')).wont_be_nil
401
+ # Get a mac address
402
+ mac_address = container.config.mac_addresses.first
403
+ _(mac_address).wont_be_nil
404
+ # all containers
405
+ containers_all = node.containers.all
406
+ _(containers_all).wont_be_nil
407
+ _(containers_all).wont_be_empty
408
+ _(containers_all.first.vmid).must_equal container.vmid.to_s
409
+ # Start container
410
+ container.action('start')
411
+ container.wait_for { ready? }
412
+ status = container.ready?
413
+ _(status).must_equal true
414
+ # Start console
415
+ _(proc do
416
+ container.start_console
417
+ end).must_raise Fog::Errors::Error
418
+ spice = container.start_console(console: 'spice')
419
+ _(spice['password']).wont_be_nil
420
+ # Suspend container (: command 'lxc-checkpoint -n 100 -s -D /var/lib/vz/dump' failed: exit code 1)
421
+ # container.action('suspend')
422
+ # container.wait_for { container.qmpstatus == 'paused' }
423
+ # qmpstatus = container.qmpstatus
424
+ # _(qmpstatus).must_equal 'paused'
425
+ # Resume server
426
+ # container.action('resume')
427
+ # container.wait_for { ready? }
428
+ # status = container.ready?
429
+ # _(status).must_equal true
430
+ # Stop container
431
+ container.action('stop')
432
+ container.wait_for { container.status == 'stopped' }
433
+ status = container.status
434
+ _(status).must_equal 'stopped'
435
+ _(proc do
436
+ container.action('hello')
437
+ end).must_raise Fog::Errors::Error
438
+ # Delete
439
+ container.destroy
440
+ # Delete container does not delete images
441
+ storage.volumes.each(&:destroy)
442
+ _(proc do
443
+ node.containers.get vmid
444
+ end).must_raise Fog::Errors::NotFound
445
+ end
446
+ end
447
+ end
@@ -0,0 +1,40 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://192.168.56.101:8006/api2/json/access/ticket
6
+ body:
7
+ encoding: US-ASCII
8
+ string: username=root%40pam&password=proxmox01
9
+ headers:
10
+ User-Agent:
11
+ - fog-core/2.2.3
12
+ Accept:
13
+ - application/json
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Cache-Control:
20
+ - max-age=0
21
+ Connection:
22
+ - close, Keep-Alive
23
+ Date:
24
+ - Wed, 25 Nov 2020 13:40:06 GMT
25
+ Pragma:
26
+ - no-cache
27
+ Server:
28
+ - pve-api-daemon/3.0
29
+ Content-Length:
30
+ - '1167'
31
+ Content-Type:
32
+ - application/json;charset=UTF-8
33
+ Expires:
34
+ - Wed, 25 Nov 2020 13:40:06 GMT
35
+ body:
36
+ encoding: ASCII-8BIT
37
+ string: '{"data":{"username":"root@pam","cap":{"storage":{"Datastore.AllocateSpace":1,"Datastore.Allocate":1,"Permissions.Modify":1,"Datastore.Audit":1,"Datastore.AllocateTemplate":1},"vms":{"VM.Config.Memory":1,"VM.Config.Disk":1,"VM.Migrate":1,"VM.Config.HWType":1,"VM.Snapshot.Rollback":1,"VM.Config.CPU":1,"VM.Allocate":1,"VM.Clone":1,"VM.Config.Network":1,"Permissions.Modify":1,"VM.Config.Options":1,"VM.Snapshot":1,"VM.Console":1,"VM.Backup":1,"VM.PowerMgmt":1,"VM.Monitor":1,"VM.Config.CDROM":1,"VM.Audit":1},"dc":{"Sys.Audit":1},"nodes":{"Sys.Audit":1,"Sys.Console":1,"Permissions.Modify":1,"Sys.Syslog":1,"Sys.Modify":1,"Sys.PowerMgmt":1},"access":{"User.Modify":1,"Permissions.Modify":1,"Group.Allocate":1}},"ticket":"PVE:root@pam:5FBE5EB6::g4qMFg0e3MKdn9WVHBLmbv0nBEx/ABBWlk4Gfe/wae+YGWnaw3XRUDvHbZudrd1UDYXpszaCbwIR2YJPhHMU8coLAFAYqIE3wtbfMQzGwwuHPPiNm3EeVOKx4SPtRqXJOSE9LBuAnDo9tmhEmZ7m8i0y4XVEwV68VghDAqxInStyIbI/1rIlMikgMKx1JApaK9+UlT5K7eAP7Lxpi8n+2wmcLgVaC34A+C8r2eJFiO+99zbEGjE6JZZLO384biMUbpoR0K56tuRxFE3Df9sRCLkEHQWD+AewWg887r3n3VMpcM250Fw7boFvRGjvFLlP0nBylFYmgf5AMrxbEI2eUw==","CSRFPreventionToken":"5FBE5EB6:VSdRDpLPnZZ5sus603Nds5Nu3o4VE02VdkljtT0/YHk"}}'
38
+ http_version:
39
+ recorded_at: Wed, 25 Nov 2020 13:40:08 GMT
40
+ recorded_with: VCR 4.0.0