ruby-proxmox 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.rubocop.yml +41 -0
- data/.travis.yml +7 -0
- data/Gemfile +27 -0
- data/Guardfile +19 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/Rakefile +6 -0
- data/lib/proxmox.rb +405 -0
- data/lib/proxmox/version.rb +5 -0
- data/ruby-proxmox.gemspec +26 -0
- data/spec/lib/proxmox_spec.rb +294 -0
- data/spec/spec_helper.rb +28 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e21fae3fba8bd653738abd93c225830fe7fe3a70d07e8701ae08265479a69873
|
4
|
+
data.tar.gz: b7cf6351dade3050ac1e60c63a3428ced63f21689bdca1c460bf348105ef1bc2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c20c5ec02c7afe1e4a0fc5a654cecf045c5e3ed957219e6c9e5ad26698468e5f3ba45173ec7a3131d5dbd066b6055a69f033d940459fbb141c40c1ab1645a0eb
|
7
|
+
data.tar.gz: e68edbd101fb3f49bb5525859a6d419d71f3026d8f07efe21923096c507cf1dbe0a01b0257d0ec98b026af82383d66f01d0966d596dfc2b3d6091ef036993089
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2015-11-14 20:39:56 -0600 using RuboCop version 0.35.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 1
|
10
|
+
Lint/Void:
|
11
|
+
Exclude:
|
12
|
+
- 'spec/lib/proxmox_spec.rb'
|
13
|
+
|
14
|
+
# Offense count: 1
|
15
|
+
# Configuration parameters: CountComments.
|
16
|
+
Metrics/ClassLength:
|
17
|
+
Max: 130
|
18
|
+
|
19
|
+
# Offense count: 45
|
20
|
+
# Configuration parameters: AllowURI, URISchemes.
|
21
|
+
Metrics/LineLength:
|
22
|
+
Max: 1094
|
23
|
+
|
24
|
+
# Offense count: 1
|
25
|
+
# Configuration parameters: CountComments.
|
26
|
+
Metrics/MethodLength:
|
27
|
+
Max: 11
|
28
|
+
|
29
|
+
# Offense count: 1
|
30
|
+
# Configuration parameters: CountKeywordArgs.
|
31
|
+
Metrics/ParameterLists:
|
32
|
+
Max: 6
|
33
|
+
|
34
|
+
# Offense count: 1
|
35
|
+
# Configuration parameters: Exclude.
|
36
|
+
Style/Documentation:
|
37
|
+
Exclude:
|
38
|
+
- 'spec/**/*'
|
39
|
+
- 'test/**/*'
|
40
|
+
- 'lib/proxmox/version.rb'
|
41
|
+
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in ruby-proxmox.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :developpement do
|
7
|
+
gem 'guard'
|
8
|
+
gem 'guard-rspec'
|
9
|
+
gem 'guard-bundler'
|
10
|
+
|
11
|
+
gem 'growl' if RUBY_PLATFORM =~ /darwin/
|
12
|
+
gem 'wdm' if RUBY_PLATFORM =~ /mingw/
|
13
|
+
gem 'ruby_gntp' if RUBY_PLATFORM =~ /mingw/
|
14
|
+
|
15
|
+
gem 'guard-spork'
|
16
|
+
|
17
|
+
gem 'yard'
|
18
|
+
gem 'redcarpet'
|
19
|
+
gem 'guard-yard'
|
20
|
+
end
|
21
|
+
|
22
|
+
group :test do
|
23
|
+
gem 'spork'
|
24
|
+
gem 'simplecov'
|
25
|
+
gem 'json', '~> 1.8.3'
|
26
|
+
gem 'coveralls'
|
27
|
+
end
|
data/Guardfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'bundler' do
|
5
|
+
watch('Gemfile')
|
6
|
+
watch(/^.+\.gemspec/)
|
7
|
+
end
|
8
|
+
|
9
|
+
guard :rspec, cmd: 'rspec' do
|
10
|
+
watch(%r{^spec/.+_spec\.rb$})
|
11
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
12
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
13
|
+
end
|
14
|
+
|
15
|
+
group :docs do
|
16
|
+
guard 'yard' do
|
17
|
+
watch(%r{lib/.+\.rb})
|
18
|
+
end
|
19
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Nicolas Ledez
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# Proxmox
|
2
|
+
|
3
|
+
A ruby gem for managing Proxmox Servers with Ruby. Based on https://github.com/nledez/proxmox
|
4
|
+
|
5
|
+
### Usage Information
|
6
|
+
|
7
|
+
Current build:
|
8
|
+
[RubyGem](http://rubygems.org/gems/ruby-proxmox)
|
9
|
+
|
10
|
+
[Rubydoc](http://rubydoc.info/github/nledez/proxmox/master/frames)
|
11
|
+
|
12
|
+
Inspirated from:
|
13
|
+
https://bitbucket.org/jmoratilla/knife-proxmox/ but I would like to have
|
14
|
+
the same without chef.
|
15
|
+
https://github.com/maxschulze/uv_proxmox but listing some task does not
|
16
|
+
work for me. No tests, use ssh.
|
17
|
+
|
18
|
+
Documentation from:
|
19
|
+
- http://pve.proxmox.com/wiki/Proxmox_VE_API
|
20
|
+
- http://pve.proxmox.com/pve2-api-doc/
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
gem 'proxmox'
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
$ bundle
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install proxmox
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
require 'awesome_print'
|
39
|
+
require 'proxmox'
|
40
|
+
|
41
|
+
def wait_status(server1, task)
|
42
|
+
puts task
|
43
|
+
while server1.task_status(task) == "running"
|
44
|
+
puts '.'
|
45
|
+
sleep 1
|
46
|
+
end
|
47
|
+
|
48
|
+
puts server1.task_status(task)
|
49
|
+
end
|
50
|
+
|
51
|
+
server1 =
|
52
|
+
Proxmox::Proxmox.new("https://the-proxmox-server:8006/api2/json/",
|
53
|
+
"node", "root", "secret", "pam")
|
54
|
+
ap server1.templates
|
55
|
+
|
56
|
+
vm1 = server1.openvz_post("ubuntu-10.04-standard_10.04-4_i386", 200)
|
57
|
+
wait_status(server1, vm1)
|
58
|
+
|
59
|
+
ap server1.openvz_vm_status(200)
|
60
|
+
vm1 = server1.openvz_vm_start(200)
|
61
|
+
begin
|
62
|
+
wait_status(server1, vm1)
|
63
|
+
rescue
|
64
|
+
end
|
65
|
+
sleep 5
|
66
|
+
ap server1.openvz_vm_shutdown(200)
|
67
|
+
begin
|
68
|
+
wait_status(server1, vm1)
|
69
|
+
rescue
|
70
|
+
end
|
71
|
+
sleep 5
|
72
|
+
ap server1.openvz_vm_status(200)
|
73
|
+
|
74
|
+
vm1 = server1.openvz_delete(200)
|
75
|
+
wait_status(server1, vm1)
|
76
|
+
|
77
|
+
## Contributing
|
78
|
+
|
79
|
+
1. Fork it
|
80
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
81
|
+
3. Create spec (in file spec/lib/proxmox_spec.rb)
|
82
|
+
4. Write your code (in lib/proxmox.rb)
|
83
|
+
5. Check spec & coverage (`bundle exec rspec` or `bundle exec guard`)
|
84
|
+
6. Commit your changes (`git commit -am 'Add some feature'`)
|
85
|
+
7. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
8. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/proxmox.rb
ADDED
@@ -0,0 +1,405 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'proxmox/version'
|
4
|
+
require 'rest_client'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
# This module encapsulates ability to manage Proxmox server
|
8
|
+
module Proxmox
|
9
|
+
# Object to manage Proxmox server
|
10
|
+
class Proxmox
|
11
|
+
# Return connection status
|
12
|
+
# - connected
|
13
|
+
# - error
|
14
|
+
attr_reader :connection_status
|
15
|
+
|
16
|
+
# Create a object to manage a Proxmox server through API
|
17
|
+
#
|
18
|
+
# :call-seq:
|
19
|
+
# new(pve_cluster, node, username, password, realm, ssl_options) -> Proxmox
|
20
|
+
#
|
21
|
+
# Example:
|
22
|
+
#
|
23
|
+
# Proxmox::Proxmox.new('https://the-proxmox-server:8006/api2/json/', 'node', 'root', 'secret', 'pam', {verify_ssl: false})
|
24
|
+
#
|
25
|
+
def initialize(pve_cluster, node, username, password, realm, ssl_options = {})
|
26
|
+
@pve_cluster = pve_cluster
|
27
|
+
@node = node
|
28
|
+
@username = username
|
29
|
+
@password = password
|
30
|
+
@realm = realm
|
31
|
+
@ssl_options = ssl_options
|
32
|
+
@connection_status = 'error'
|
33
|
+
@site = RestClient::Resource.new(@pve_cluster, @ssl_options)
|
34
|
+
@auth_params = create_ticket
|
35
|
+
end
|
36
|
+
|
37
|
+
def get(path, args = {})
|
38
|
+
http_action_get(path, args)
|
39
|
+
end
|
40
|
+
|
41
|
+
def post(path, args = {})
|
42
|
+
http_action_post(path, args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def put(path, args = {})
|
46
|
+
http_action_put(path, args)
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete(path)
|
50
|
+
http_action_delete(path)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get task status
|
54
|
+
#
|
55
|
+
# :call-seq:
|
56
|
+
# task_status(task-id) -> String
|
57
|
+
#
|
58
|
+
# - taksstatus
|
59
|
+
# - taskstatus:exitstatus
|
60
|
+
#
|
61
|
+
# Example:
|
62
|
+
#
|
63
|
+
# taskstatus 'UPID:localhost:00051DA0:119EAABC:521CCB19:vzcreate:203:root@pam:'
|
64
|
+
#
|
65
|
+
# Examples return:
|
66
|
+
# - running
|
67
|
+
# - stopped:OK
|
68
|
+
#
|
69
|
+
def task_status(upid)
|
70
|
+
data = http_action_get "nodes/#{@node}/tasks/#{URI.encode upid}/status"
|
71
|
+
status = data['status']
|
72
|
+
exitstatus = data['exitstatus']
|
73
|
+
if exitstatus
|
74
|
+
"#{status}:#{exitstatus}"
|
75
|
+
else
|
76
|
+
"#{status}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Get template list
|
81
|
+
#
|
82
|
+
# :call-seq:
|
83
|
+
# templates -> Hash
|
84
|
+
#
|
85
|
+
# Return a Hash of all templates
|
86
|
+
#
|
87
|
+
# Example:
|
88
|
+
#
|
89
|
+
# templates
|
90
|
+
#
|
91
|
+
# Example return:
|
92
|
+
#
|
93
|
+
# {
|
94
|
+
# 'ubuntu-10.04-standard_10.04-4_i386' => {
|
95
|
+
# 'format' => 'tgz',
|
96
|
+
# 'content' => 'vztmpl',
|
97
|
+
# 'volid' => 'local:vztmpl/ubuntu-10.04-standard_10.04-4_i386.tar.gz',
|
98
|
+
# 'size' => 142126884
|
99
|
+
# },
|
100
|
+
# 'ubuntu-12.04-standard_12.04-1_i386' => {
|
101
|
+
# 'format' => 'tgz',
|
102
|
+
# 'content' => 'vztmpl',
|
103
|
+
# 'volid' => 'local:vztmpl/ubuntu-12.04-standard_12.04-1_i386.tar.gz',
|
104
|
+
# 'size' => 130040792
|
105
|
+
# }
|
106
|
+
# }
|
107
|
+
#
|
108
|
+
def templates
|
109
|
+
data = http_action_get "nodes/#{@node}/storage/local/content"
|
110
|
+
template_list = {}
|
111
|
+
data.each do |ve|
|
112
|
+
name = ve['volid'].gsub(%r{local:vztmpl\/(.*).tar.gz}, '\1')
|
113
|
+
template_list[name] = ve
|
114
|
+
end
|
115
|
+
template_list
|
116
|
+
end
|
117
|
+
|
118
|
+
# Get CT list
|
119
|
+
#
|
120
|
+
# :call-seq:
|
121
|
+
# openvz_get -> Hash
|
122
|
+
#
|
123
|
+
# Return a Hash of all openvz container
|
124
|
+
#
|
125
|
+
# Example:
|
126
|
+
#
|
127
|
+
# openvz_get
|
128
|
+
#
|
129
|
+
# Example return:
|
130
|
+
# {
|
131
|
+
# '101' => {
|
132
|
+
# 'maxswap' => 536870912,
|
133
|
+
# 'disk' => 405168128,
|
134
|
+
# 'ip' => '192.168.1.5',
|
135
|
+
# 'status' => 'running',
|
136
|
+
# 'netout' => 272,
|
137
|
+
# 'maxdisk' => 4294967296,
|
138
|
+
# 'maxmem' => 536870912,
|
139
|
+
# 'uptime' => 3068073,
|
140
|
+
# 'swap' => 0,
|
141
|
+
# 'vmid' => '101',
|
142
|
+
# 'nproc' => '10',
|
143
|
+
# 'diskread' => 0,
|
144
|
+
# 'cpu' => 0.00031670581100007,
|
145
|
+
# 'netin' => 0,
|
146
|
+
# 'name' => 'test2.domain.com',
|
147
|
+
# 'failcnt' => 0,
|
148
|
+
# 'diskwrite' => 0,
|
149
|
+
# 'mem' => 22487040,
|
150
|
+
# 'type' => 'openvz',
|
151
|
+
# 'cpus' => 1
|
152
|
+
# },
|
153
|
+
# [...]
|
154
|
+
# }
|
155
|
+
def openvz_get
|
156
|
+
data = http_action_get "nodes/#{@node}/openvz"
|
157
|
+
ve_list = {}
|
158
|
+
data.each do |ve|
|
159
|
+
ve_list[ve['vmid']] = ve
|
160
|
+
end
|
161
|
+
ve_list
|
162
|
+
end
|
163
|
+
|
164
|
+
# Create CT container
|
165
|
+
#
|
166
|
+
# :call-seq:
|
167
|
+
# openvz_post(ostemplate, vmid) -> String
|
168
|
+
# openvz_post(ostemplate, vmid, options) -> String
|
169
|
+
#
|
170
|
+
# Return a String as task ID
|
171
|
+
#
|
172
|
+
# Examples:
|
173
|
+
#
|
174
|
+
# openvz_post('ubuntu-10.04-standard_10.04-4_i386', 200)
|
175
|
+
# openvz_post('ubuntu-10.04-standard_10.04-4_i386', 200, {'hostname' => 'test.test.com', 'password' => 'testt' })
|
176
|
+
#
|
177
|
+
# Example return:
|
178
|
+
#
|
179
|
+
# UPID:localhost:000BC66A:1279E395:521EFC4E:vzcreate:200:root@pam:
|
180
|
+
#
|
181
|
+
def openvz_post(ostemplate, vmid, config = {})
|
182
|
+
config['vmid'] = vmid
|
183
|
+
config['ostemplate'] = "local%3Avztmpl%2F#{ostemplate}.tar.gz"
|
184
|
+
vm_definition = config.to_a.map { |v| v.join '=' }.join '&'
|
185
|
+
|
186
|
+
http_action_post("nodes/#{@node}/openvz", vm_definition)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Delete CT
|
190
|
+
#
|
191
|
+
# :call-seq:
|
192
|
+
# openvz_delete(vmid) -> String
|
193
|
+
#
|
194
|
+
# Return a string as task ID
|
195
|
+
#
|
196
|
+
# Example:
|
197
|
+
#
|
198
|
+
# openvz_delete(200)
|
199
|
+
#
|
200
|
+
# Example return:
|
201
|
+
#
|
202
|
+
# UPID:localhost:000BC66A:1279E395:521EFC4E:vzdelete:200:root@pam:
|
203
|
+
#
|
204
|
+
def openvz_delete(vmid)
|
205
|
+
http_action_delete "nodes/#{@node}/openvz/#{vmid}"
|
206
|
+
end
|
207
|
+
|
208
|
+
# Get CT status
|
209
|
+
#
|
210
|
+
# :call-seq:
|
211
|
+
# openvz_delete(vmid) -> String
|
212
|
+
#
|
213
|
+
# Return a string as task ID
|
214
|
+
#
|
215
|
+
# Example:
|
216
|
+
#
|
217
|
+
# openvz_delete(200)
|
218
|
+
#
|
219
|
+
# Example return:
|
220
|
+
#
|
221
|
+
# UPID:localhost:000BC66A:1279E395:521EFC4E:vzdelete:200:root@pam:
|
222
|
+
#
|
223
|
+
def openvz_status(vmid)
|
224
|
+
http_action_get "nodes/#{@node}/openvz/#{vmid}/status/current"
|
225
|
+
end
|
226
|
+
|
227
|
+
# Start CT
|
228
|
+
#
|
229
|
+
# :call-seq:
|
230
|
+
# openvz_start(vmid) -> String
|
231
|
+
#
|
232
|
+
# Return a string as task ID
|
233
|
+
#
|
234
|
+
# Example:
|
235
|
+
#
|
236
|
+
# openvz_start(200)
|
237
|
+
#
|
238
|
+
# Example return:
|
239
|
+
#
|
240
|
+
# UPID:localhost:000BC66A:1279E395:521EFC4E:vzstart:200:root@pam:
|
241
|
+
#
|
242
|
+
def openvz_start(vmid)
|
243
|
+
http_action_post "nodes/#{@node}/openvz/#{vmid}/status/start"
|
244
|
+
end
|
245
|
+
|
246
|
+
# Stop CT
|
247
|
+
#
|
248
|
+
# :call-seq:
|
249
|
+
# openvz_stop(vmid) -> String
|
250
|
+
#
|
251
|
+
# Return a string as task ID
|
252
|
+
#
|
253
|
+
# Example:
|
254
|
+
#
|
255
|
+
# openvz_stop(200)
|
256
|
+
#
|
257
|
+
# Example return:
|
258
|
+
#
|
259
|
+
# UPID:localhost:000BC66A:1279E395:521EFC4E:vzstop:200:root@pam:
|
260
|
+
#
|
261
|
+
def openvz_stop(vmid)
|
262
|
+
http_action_post "nodes/#{@node}/openvz/#{vmid}/status/stop"
|
263
|
+
end
|
264
|
+
|
265
|
+
# Shutdown CT
|
266
|
+
#
|
267
|
+
# :call-seq:
|
268
|
+
# openvz_shutdown(vmid) -> String
|
269
|
+
#
|
270
|
+
# Return a string as task ID
|
271
|
+
#
|
272
|
+
# Example:
|
273
|
+
#
|
274
|
+
# openvz_shutdown(200)
|
275
|
+
#
|
276
|
+
# Example return:
|
277
|
+
#
|
278
|
+
# UPID:localhost:000BC66A:1279E395:521EFC4E:vzshutdown:200:root@pam:
|
279
|
+
#
|
280
|
+
def openvz_shutdown(vmid)
|
281
|
+
http_action_post "nodes/#{@node}/openvz/#{vmid}/status/shutdown"
|
282
|
+
end
|
283
|
+
|
284
|
+
# Get CT config
|
285
|
+
#
|
286
|
+
# :call-seq:
|
287
|
+
# openvz_config(vmid) -> String
|
288
|
+
#
|
289
|
+
# Return a string as task ID
|
290
|
+
#
|
291
|
+
# Example:
|
292
|
+
#
|
293
|
+
# openvz_config(200)
|
294
|
+
#
|
295
|
+
# Example return:
|
296
|
+
#
|
297
|
+
# {
|
298
|
+
# 'quotaugidlimit' => 0,
|
299
|
+
# 'disk' => 0,
|
300
|
+
# 'ostemplate' => 'ubuntu-10.04-standard_10.04-4_i386.tar.gz',
|
301
|
+
# 'hostname' => 'test.test.com',
|
302
|
+
# 'nameserver' => '127.0.0.1 192.168.1.1',
|
303
|
+
# 'memory' => 256,
|
304
|
+
# 'searchdomain' => 'domain.com',
|
305
|
+
# 'onboot' => 0,
|
306
|
+
# 'cpuunits' => 1000,
|
307
|
+
# 'swap' => 256,
|
308
|
+
# 'quotatime' => 0,
|
309
|
+
# 'digest' => 'e7e6e21a215af6b9da87a8ecb934956b8983f960',
|
310
|
+
# 'cpus' => 1,
|
311
|
+
# 'storage' => 'local'
|
312
|
+
# }
|
313
|
+
#
|
314
|
+
def openvz_config(vmid)
|
315
|
+
http_action_get "nodes/#{@node}/openvz/#{vmid}/config"
|
316
|
+
end
|
317
|
+
|
318
|
+
# Set CT config
|
319
|
+
#
|
320
|
+
# :call-seq:
|
321
|
+
# openvz_config_set(vmid, parameters) -> Nil
|
322
|
+
#
|
323
|
+
# Return nil
|
324
|
+
#
|
325
|
+
# Example:
|
326
|
+
#
|
327
|
+
# openvz_config(200, { 'swap' => 2048 })
|
328
|
+
#
|
329
|
+
# Example return:
|
330
|
+
#
|
331
|
+
# nil
|
332
|
+
#
|
333
|
+
def openvz_config_set(vmid, data)
|
334
|
+
http_action_put("nodes/#{@node}/openvz/#{vmid}/config", data)
|
335
|
+
end
|
336
|
+
|
337
|
+
# Reset Qemu
|
338
|
+
def qemu_reset(vmid)
|
339
|
+
http_action_post("nodes/#{@node}/qemu/#{vmid}/status/reset")
|
340
|
+
end
|
341
|
+
|
342
|
+
private
|
343
|
+
|
344
|
+
# Methods manages auth
|
345
|
+
def create_ticket
|
346
|
+
post_param = { username: @username, realm: @realm, password: @password }
|
347
|
+
@site['access/ticket'].post post_param do |response, _request, _result, &_block|
|
348
|
+
if response.code == 200
|
349
|
+
extract_ticket response
|
350
|
+
else
|
351
|
+
@connection_status = 'error'
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
# Method create ticket
|
357
|
+
def extract_ticket(response)
|
358
|
+
data = JSON.parse(response.body)
|
359
|
+
ticket = data['data']['ticket']
|
360
|
+
csrf_prevention_token = data['data']['CSRFPreventionToken']
|
361
|
+
unless ticket.nil?
|
362
|
+
token = 'PVEAuthCookie=' + ticket.gsub!(/:/, '%3A').gsub!(/=/, '%3D')
|
363
|
+
end
|
364
|
+
@connection_status = 'connected'
|
365
|
+
{
|
366
|
+
CSRFPreventionToken: csrf_prevention_token,
|
367
|
+
cookie: token
|
368
|
+
}
|
369
|
+
end
|
370
|
+
|
371
|
+
# Extract data or return error
|
372
|
+
def check_response(response)
|
373
|
+
if response.code == 200
|
374
|
+
JSON.parse(response.body)['data']
|
375
|
+
else
|
376
|
+
'NOK: error code = ' + response.code.to_s
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
# Methods manage http dialogs
|
381
|
+
def http_action_post(url, data = {})
|
382
|
+
@site[url].post data, @auth_params do |response, _request, _result, &_block|
|
383
|
+
check_response response
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
def http_action_put(url, data = {})
|
388
|
+
@site[url].put data, @auth_params do |response, _request, _result, &_block|
|
389
|
+
check_response response
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
def http_action_get(url, data = {})
|
394
|
+
@site[url].get @auth_params.merge(data) do |response, _request, _result, &_block|
|
395
|
+
check_response response
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
def http_action_delete(url)
|
400
|
+
@site[url].delete @auth_params do |response, _request, _result, &_block|
|
401
|
+
check_response response
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'proxmox/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'ruby-proxmox'
|
8
|
+
spec.version = Proxmox::VERSION
|
9
|
+
spec.authors = ['Nathaniel Suchy', 'Nicolas Ledez']
|
10
|
+
spec.email = ['me@lunorian.is']
|
11
|
+
spec.description = 'A ruby gem for managing Proxmox Servers with Ruby. Based on https://github.com/nledez/proxmox'
|
12
|
+
spec.summary = 'A ruby gem for managing Proxmox Servers with Ruby. Based on https://github.com/nledez/proxmox'
|
13
|
+
spec.homepage = 'https://github.com/ulayer/ruby-proxmox'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.add_dependency 'rest-client', '>=1.6.7'
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
23
|
+
spec.add_development_dependency 'rake'
|
24
|
+
spec.add_development_dependency 'rspec'
|
25
|
+
spec.add_development_dependency 'webmock'
|
26
|
+
end
|
@@ -0,0 +1,294 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
require 'proxmox'
|
4
|
+
|
5
|
+
describe Proxmox do
|
6
|
+
before(:each) do
|
7
|
+
@common_headers_in = { 'User-Agent' => 'Ruby',
|
8
|
+
'Cookie' => /.*/,
|
9
|
+
'Csrfpreventiontoken' => /.*/ }
|
10
|
+
@common_headers_out = { connection: 'close',
|
11
|
+
server: 'pve-api-daemon/3.0',
|
12
|
+
content_type: 'application/json;charset=UTF-8' }
|
13
|
+
|
14
|
+
# Common auth
|
15
|
+
stub_request(:post, 'http://localhost:8006/api2/json/access/ticket').with(
|
16
|
+
headers: {
|
17
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
18
|
+
'User-Agent' => 'Ruby'
|
19
|
+
},
|
20
|
+
body: {
|
21
|
+
'username' => 'root',
|
22
|
+
'password' => 'secret',
|
23
|
+
'realm' => 'pam'
|
24
|
+
}
|
25
|
+
).to_return(
|
26
|
+
status: 200,
|
27
|
+
headers: @common_headers_out,
|
28
|
+
body: '{"data":{"cap":{"dc":{"Sys.Audit":1},"access":{"Group.Allocate":1,"User.Modify":1},"nodes":{"Sys.Audit":1,"Sys.Syslog":1,"Sys.Console":1,"Sys.Modify":1,"Sys.PowerMgmt":1},"vms":{"VM.Backup":1,"VM.Allocate":1,"VM.Config.CPU":1,"VM.Config.Network":1,"VM.Migrate":1,"VM.Config.Memory":1,"VM.Config.Options":1,"Permissions.Modify":1,"VM.Monitor":1,"VM.Console":1,"VM.Config.Disk":1,"VM.Config.HWType":1,"VM.Clone":1,"VM.Snapshot":1,"VM.Audit":1,"VM.PowerMgmt":1,"VM.Config.CDROM":1},"storage":{"Datastore.AllocateTemplate":1,"Datastore.Allocate":1,"Datastore.Audit":1,"Permissions.Modify":1,"Datastore.AllocateSpace":1}},"CSRFPreventionToken":"51F00E60:Pnd0AHehuTE++j87nUz0nLuyW+0","ticket":"PVE:root@pam:51F00E60::OS5lBKlaabgnmekdbVY2JYAbd5Z/MPWCeZ9b33UwjsE1yVB1esIwUQoXJ4Xgb/+UVE9mtS2K3dJ65wyPDsGYTDc0TCl0VmdOGz7djXMlMy5ShRjXcX/GLs77LHXlLQOO+ED/jCoz0tHV55igNSBNMG2UrSLlTGvgm8zf1fNqAsVszrAWgeFu+e/1CLIfs//cWyimBuDx+r3m/NOjaoyeb2u63eBCPrWyEiCJZniMZDVnqqQcOm32tE2XQj4D2LS+xaHn2fdZDlcAo0uY4qVspKiMjf9g2AudRblkobCTf7KdhanIm0kCSqkvHJy2EMcAbxcqnGnjPiYSH0WYZMTnlA==","username":"root@pam"}}'
|
29
|
+
)
|
30
|
+
|
31
|
+
@server1 = Proxmox::Proxmox.new('http://localhost:8006/api2/json/', 'localhost', 'root', 'secret', 'pam')
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'get' do
|
35
|
+
it 'calls http_action_get' do
|
36
|
+
expect(@server1).to receive(:http_action_get).with("version", {})
|
37
|
+
@server1.get("version")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'post' do
|
42
|
+
it 'calls http_action_post' do
|
43
|
+
expect(@server1).to receive(:http_action_post).with("version", {})
|
44
|
+
@server1.post("version")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'put' do
|
49
|
+
it 'calls http_action_put' do
|
50
|
+
expect(@server1).to receive(:http_action_put).with("version", {})
|
51
|
+
@server1.put("version")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'delete' do
|
56
|
+
it 'calls http_action_delete' do
|
57
|
+
expect(@server1).to receive(:http_action_delete).with("version")
|
58
|
+
@server1.delete("version")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should connect to Proxmox server' do
|
63
|
+
# Bad auth
|
64
|
+
stub_request(:post, 'http://localhost:8006/api2/json/access/ticket').with(
|
65
|
+
headers: {
|
66
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
67
|
+
'User-Agent' => 'Ruby'
|
68
|
+
},
|
69
|
+
body: {
|
70
|
+
'username' => 'root',
|
71
|
+
'password' => 'bad',
|
72
|
+
'realm' => 'pam'
|
73
|
+
}
|
74
|
+
).to_return(
|
75
|
+
status: 500,
|
76
|
+
headers: @common_headers_out,
|
77
|
+
body: '{"data":null}'
|
78
|
+
)
|
79
|
+
expect(@server1.connection_status).to eq 'connected'
|
80
|
+
|
81
|
+
server2 = Proxmox::Proxmox.new('http://localhost:8006/api2/json/', 'localhost', 'root', 'bad', 'pam')
|
82
|
+
expect(server2.connection_status).to eq 'error'
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'task_status' do
|
86
|
+
it 'should get task status' do
|
87
|
+
# Status done
|
88
|
+
stub_request(:get, 'http://localhost:8006/api2/json/nodes/localhost/tasks/UPID:localhost:00051DA0:119EAABB:521CCB19:vzcreate:200:root@pam:/status').with(
|
89
|
+
headers: @common_headers_in).to_return(
|
90
|
+
status: 200,
|
91
|
+
headers: {
|
92
|
+
connection: 'close', server: 'pve-api-daemon/3.0', content_type: 'application/json;charset=UTF-8' },
|
93
|
+
body: '{"data":{"exitstatus":"OK","status":"stopped","upid":"UPID:localhost:00051DA0:119EAABB:521CCB19:vzcreate:200:root@pam:","node":"localhost","pid":335264,"starttime":1377618713,"user":"root@pam","type":"vzcreate","id":"200","pstart":295611067}}'
|
94
|
+
)
|
95
|
+
|
96
|
+
# Status running
|
97
|
+
stub_request(:get, 'http://localhost:8006/api2/json/nodes/localhost/tasks/UPID:localhost:00055DDA:11A99D07:521CE71F:vzcreate:200:root@pam:/status').with(
|
98
|
+
headers: @common_headers_in).to_return(
|
99
|
+
status: 200,
|
100
|
+
headers: @common_headers_out,
|
101
|
+
body: '{"data":{"status":"running","upid":"UPID:localhost:00055DDA:11A99D07:521CE71F:vzcreate:200:root@pam:","node":"localhost","pid":351706,"starttime":1377625887,"user":"root@pam","type":"vzcreate","id":"200","pstart":296328455}}'
|
102
|
+
)
|
103
|
+
|
104
|
+
# Get status
|
105
|
+
expect(@server1.task_status('UPID:localhost:00051DA0:119EAABB:521CCB19:vzcreate:200:root@pam:')).to be_eql 'stopped:OK'
|
106
|
+
expect(@server1.task_status('UPID:localhost:00055DDA:11A99D07:521CE71F:vzcreate:200:root@pam:')).to be_eql 'running'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'templates' do
|
111
|
+
it 'should get template list' do
|
112
|
+
# First template list
|
113
|
+
stub_request(:get, 'http://localhost:8006/api2/json/nodes/localhost/storage/local/content').with(
|
114
|
+
headers: @common_headers_in).to_return(
|
115
|
+
status: 200,
|
116
|
+
headers: @common_headers_out,
|
117
|
+
body: '{"data":[{"format":"tgz","content":"vztmpl","volid":"local:vztmpl/ubuntu-10.04-standard_10.04-4_i386.tar.gz","size":142126884},{"format":"tgz","content":"vztmpl","volid":"local:vztmpl/ubuntu-12.04-standard_12.04-1_i386.tar.gz","size":130040792}]}'
|
118
|
+
)
|
119
|
+
|
120
|
+
expect(@server1.templates).to be_an_instance_of Hash
|
121
|
+
expect(@server1.templates.keys.sort).to be_eql ['ubuntu-10.04-standard_10.04-4_i386', 'ubuntu-12.04-standard_12.04-1_i386']
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe 'openvz_get' do
|
126
|
+
it 'should get openvz vm list' do
|
127
|
+
# First VM list
|
128
|
+
stub_request(:get, 'http://localhost:8006/api2/json/nodes/localhost/openvz').with(
|
129
|
+
headers: @common_headers_in).to_return(
|
130
|
+
status: 200,
|
131
|
+
headers: @common_headers_out,
|
132
|
+
body: '{"data":[{"maxswap":536870912,"disk":404037632,"ip":"192.168.1.5","status":"running","netout":272,"maxdisk":4294967296,"maxmem":536870912,"uptime":3847,"swap":0,"vmid":"101","nproc":"10","diskread":0,"cpu":0.00183354942808597,"netin":0,"name":"test2.dummy.tld","failcnt":0,"diskwrite":0,"mem":21303296,"type":"openvz","cpus":1},{"maxswap":536870912,"disk":387186688,"ip":"192.168.1.1","status":"running","netout":272,"maxdisk":4294967296,"maxmem":536870912,"uptime":17120,"swap":0,"vmid":"100","nproc":"17","diskread":0,"cpu":0.000504170031344927,"netin":0,"name":"test.dummy.tld","failcnt":0,"diskwrite":0,"mem":27987968,"type":"openvz","cpus":1}]}'
|
133
|
+
)
|
134
|
+
|
135
|
+
# Second VM list
|
136
|
+
stub_request(:get, 'http://localhost:8006/api2/json/nodes/otherone/openvz').with(
|
137
|
+
headers: @common_headers_in).to_return(
|
138
|
+
status: 200,
|
139
|
+
headers: @common_headers_out,
|
140
|
+
body: '{"data":[{"maxswap":536870912,"disk":404041728,"ip":"192.168.1.5","status":"running","netout":272,"maxdisk":4294967296,"maxmem":536870912,"uptime":6176,"swap":0,"vmid":"101","nproc":"10","diskread":0,"cpu":0.00161487378340585,"netin":0,"name":"test2.dummy.tld","failcnt":0,"diskwrite":0,"mem":21299200,"type":"openvz","cpus":1},{"maxswap":2147483648,"disk":0,"ip":"10.0.0.1","status":"stopped","netout":0,"maxdisk":10737418240,"maxmem":1073741824,"uptime":0,"swap":0,"vmid":"102","nproc":0,"diskread":0,"cpu":0,"netin":0,"name":"test3.other.domain","failcnt":0,"diskwrite":0,"mem":0,"type":"openvz","cpus":2},{"maxswap":536870912,"disk":387194880,"ip":"192.168.1.1","status":"running","netout":272,"maxdisk":4294967296,"maxmem":536870912,"uptime":19449,"swap":0,"vmid":"100","nproc":"17","diskread":0,"cpu":0.000589570582552814,"netin":0,"name":"test.dummy.tld","failcnt":0,"diskwrite":0,"mem":28282880,"type":"openvz","cpus":1}]}'
|
141
|
+
)
|
142
|
+
|
143
|
+
expect(@server1.openvz_get).to be_an_instance_of Hash
|
144
|
+
expect(@server1.openvz_get.keys.sort).to be_eql %w(100 101)
|
145
|
+
|
146
|
+
server2 = Proxmox::Proxmox.new('http://localhost:8006/api2/json/', 'otherone', 'root', 'secret', 'pam')
|
147
|
+
expect(server2.openvz_get).to be_an_instance_of Hash
|
148
|
+
expect(server2.openvz_get.keys.sort).to be_eql %w(100 101 102)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe 'openvz_post' do
|
153
|
+
it 'should create a container' do
|
154
|
+
# Create VM
|
155
|
+
stub_request(:post, 'http://localhost:8006/api2/json/nodes/localhost/openvz').with(
|
156
|
+
body: 'vmid=200&ostemplate=local%3Avztmpl%2Fubuntu-10.04-standard_10.04-4_i386.tar.gz',
|
157
|
+
headers: @common_headers_in).to_return(
|
158
|
+
status: 200,
|
159
|
+
headers: @common_headers_out,
|
160
|
+
body: '{"data":"UPID:localhost:00051DA0:119EAABB:521CCB19:vzcreate:200:root@pam:"}'
|
161
|
+
)
|
162
|
+
|
163
|
+
stub_request(:post, 'http://localhost:8006/api2/json/nodes/localhost/openvz').with(
|
164
|
+
body: 'hostname=vm1.domain.com&password=secret&memory=512&swap=512&disk=4&vmid=203&ostemplate=local%3Avztmpl%2Fubuntu-10.04-standard_10.04-4_i386.tar.gz',
|
165
|
+
headers: @common_headers_in).to_return(
|
166
|
+
status: 200,
|
167
|
+
headers: @common_headers_out,
|
168
|
+
body: '{"data":"UPID:localhost:00051DA0:119EAABC:521CCB19:vzcreate:203:root@pam:"}'
|
169
|
+
)
|
170
|
+
|
171
|
+
stub_request(:post, 'http://localhost:8006/api2/json/nodes/localhost/openvz').with(
|
172
|
+
body: 'vmid=204&ostemplate=local%3Avztmpl%2Fubuntu-10.04-standard_10.04-4_i386.tar.gz',
|
173
|
+
headers: @common_headers_in).to_return(
|
174
|
+
status: 500,
|
175
|
+
headers: { connection: 'close', server: 'pve-api-daemon/3.0', content_type: 'application/json;charset=UTF-8'
|
176
|
+
},
|
177
|
+
body: 'NOK: error code = 500'
|
178
|
+
)
|
179
|
+
|
180
|
+
# Create the vm
|
181
|
+
expect(@server1.openvz_post('ubuntu-10.04-standard_10.04-4_i386', 200)).to be_eql 'UPID:localhost:00051DA0:119EAABB:521CCB19:vzcreate:200:root@pam:'
|
182
|
+
expect(@server1.openvz_post('ubuntu-10.04-standard_10.04-4_i386', 203, 'hostname' => 'vm1.domain.com', 'password' => 'secret', 'memory' => 512, 'swap' => 512, 'disk' => 4)).to be_eql 'UPID:localhost:00051DA0:119EAABC:521CCB19:vzcreate:203:root@pam:'
|
183
|
+
expect(@server1.openvz_post('ubuntu-10.04-standard_10.04-4_i386', 204)).to be_eql 'NOK: error code = 500'
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe 'openvz_delete' do
|
188
|
+
it 'should delete openvz container' do
|
189
|
+
# Delete VM
|
190
|
+
stub_request(:delete, 'http://localhost:8006/api2/json/nodes/localhost/openvz/200').with(
|
191
|
+
headers: @common_headers_in).to_return(
|
192
|
+
status: 200,
|
193
|
+
headers: @common_headers_out,
|
194
|
+
body: '{"data":"UPID:localhost:0005C1EB:11BAA4EB:521D12B8:vzdestroy:200:root@pam:"}'
|
195
|
+
)
|
196
|
+
|
197
|
+
stub_request(:delete, 'http://localhost:8006/api2/json/nodes/localhost/openvz/201').with(
|
198
|
+
headers: @common_headers_in).to_return(
|
199
|
+
status: 500,
|
200
|
+
headers: @common_headers_out,
|
201
|
+
body: 'NOK: error code = 500'
|
202
|
+
)
|
203
|
+
|
204
|
+
# Delete the vm
|
205
|
+
expect(@server1.openvz_delete(200)).to be_eql 'UPID:localhost:0005C1EB:11BAA4EB:521D12B8:vzdestroy:200:root@pam:'
|
206
|
+
expect(@server1.openvz_delete(201)).to be_eql 'NOK: error code = 500'
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe 'openvz_status' do
|
211
|
+
it 'should get container status' do
|
212
|
+
# VM Status
|
213
|
+
stub_request(:get, 'http://localhost:8006/api2/json/nodes/localhost/openvz/200/status/current').with(
|
214
|
+
headers: @common_headers_in).to_return(
|
215
|
+
status: 200,
|
216
|
+
headers: @common_headers_out,
|
217
|
+
body: '{"data":{"maxswap":268435456,"disk":0,"ip":"-","status":"stopped","ha":0,"netout":0,"maxdisk":9.44473296573929e+21,"maxmem":268435456,"uptime":0,"swap":0,"nproc":0,"diskread":0,"cpu":0,"netin":0,"name":"CT200","failcnt":0,"diskwrite":0,"mem":0,"type":"openvz","cpus":1}}'
|
218
|
+
)
|
219
|
+
|
220
|
+
expect(@server1.openvz_status(200)).to be_an_instance_of Hash
|
221
|
+
expect(@server1.openvz_status(200)['status']).to be_eql 'stopped'
|
222
|
+
expect(@server1.openvz_status(200)['cpus']).to be_eql 1
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe 'openvz_start' do
|
227
|
+
it 'should start vm' do
|
228
|
+
stub_request(:post, 'http://localhost:8006/api2/json/nodes/localhost/openvz/200/status/start').with(
|
229
|
+
headers: @common_headers_in).to_return(
|
230
|
+
status: 200,
|
231
|
+
headers: @common_headers_out,
|
232
|
+
body: '{"data":"UPID:ks311324:0005D91C:11BE5277:521D1C23:vzstart:200:root@pam:"}'
|
233
|
+
)
|
234
|
+
|
235
|
+
expect(@server1.openvz_start(200)).to be_eql 'UPID:ks311324:0005D91C:11BE5277:521D1C23:vzstart:200:root@pam:'
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe 'openvz_stop' do
|
240
|
+
it 'should stop vm' do
|
241
|
+
stub_request(:post, 'http://localhost:8006/api2/json/nodes/localhost/openvz/200/status/stop').with(
|
242
|
+
headers: @common_headers_in).to_return(
|
243
|
+
status: 200,
|
244
|
+
headers: @common_headers_out,
|
245
|
+
body: '{"data":"UPID:ks311324:0005D91C:11BE5277:521D1C23:vzstop:200:root@pam:"}'
|
246
|
+
)
|
247
|
+
|
248
|
+
expect(@server1.openvz_stop(200)).to be_eql 'UPID:ks311324:0005D91C:11BE5277:521D1C23:vzstop:200:root@pam:'
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe 'openvz_shutdown' do
|
253
|
+
it 'should shutdown vm' do
|
254
|
+
stub_request(:post, 'http://localhost:8006/api2/json/nodes/localhost/openvz/200/status/shutdown').with(
|
255
|
+
headers: @common_headers_in).to_return(
|
256
|
+
status: 200,
|
257
|
+
headers: @common_headers_out,
|
258
|
+
body: '{"data":"UPID:ks311324:0005D91C:11BE5277:521D1C23:vzshutdown:200:root@pam:"}'
|
259
|
+
)
|
260
|
+
|
261
|
+
expect(@server1.openvz_shutdown(200)).to be_eql 'UPID:ks311324:0005D91C:11BE5277:521D1C23:vzshutdown:200:root@pam:'
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe 'openvz_config' do
|
266
|
+
it 'should get container config' do
|
267
|
+
# VM config
|
268
|
+
stub_request(:get, 'http://localhost:8006/api2/json/nodes/localhost/openvz/200/config').with(
|
269
|
+
headers: @common_headers_in).to_return(
|
270
|
+
status: 200,
|
271
|
+
headers: @common_headers_out,
|
272
|
+
body: '{"data":{"quotaugidlimit":0,"disk":0,"ostemplate":"ubuntu-10.04-standard_10.04-4_i386.tar.gz","nameserver":"127.0.0.1 192.168.1.1","memory":256,"searchdomain":"domain.com","onboot":0,"cpuunits":1000,"swap":256,"quotatime":0,"digest":"5a6f4052d559d3ecc89c849214f482217018a07e","cpus":1,"storage":"local"}}'
|
273
|
+
)
|
274
|
+
|
275
|
+
expect(@server1.openvz_config(200)).to be_an_instance_of Hash
|
276
|
+
expect(@server1.openvz_config(200)['searchdomain']).to be_eql 'domain.com'
|
277
|
+
expect(@server1.openvz_config(200)['ostemplate']).to be_eql 'ubuntu-10.04-standard_10.04-4_i386.tar.gz'
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
describe 'openvz_config_set' do
|
282
|
+
it 'should modify container config' do
|
283
|
+
# VM config
|
284
|
+
stub_request(:put, 'http://localhost:8006/api2/json/nodes/localhost/openvz/200/config').with(
|
285
|
+
headers: @common_headers_in).to_return(
|
286
|
+
status: 200,
|
287
|
+
headers: @common_headers_out,
|
288
|
+
body: '{"data":null}'
|
289
|
+
)
|
290
|
+
|
291
|
+
@server1.openvz_config_set(200, 'searchdomain' => 'other.com')
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spork'
|
2
|
+
require 'rspec'
|
3
|
+
|
4
|
+
Spork.prefork do
|
5
|
+
unless ENV['DRB']
|
6
|
+
require 'simplecov'
|
7
|
+
SimpleCov.start 'rails'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Spork.each_run do
|
12
|
+
if ENV['DRB']
|
13
|
+
require 'simplecov'
|
14
|
+
SimpleCov.start 'rails'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
if ENV['CI']
|
19
|
+
require 'coveralls'
|
20
|
+
Coveralls.wear!
|
21
|
+
end
|
22
|
+
|
23
|
+
RSpec.configure do |config|
|
24
|
+
config.run_all_when_everything_filtered = true
|
25
|
+
config.filter_run :focus
|
26
|
+
|
27
|
+
config.order = 'random'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-proxmox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nathaniel Suchy
|
8
|
+
- Nicolas Ledez
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2019-03-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 1.6.7
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 1.6.7
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: bundler
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.3'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.3'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rspec
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: webmock
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
description: A ruby gem for managing Proxmox Servers with Ruby. Based on https://github.com/nledez/proxmox
|
85
|
+
email:
|
86
|
+
- me@lunorian.is
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".rspec"
|
93
|
+
- ".rubocop.yml"
|
94
|
+
- ".travis.yml"
|
95
|
+
- Gemfile
|
96
|
+
- Guardfile
|
97
|
+
- LICENSE.txt
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- lib/proxmox.rb
|
101
|
+
- lib/proxmox/version.rb
|
102
|
+
- ruby-proxmox.gemspec
|
103
|
+
- spec/lib/proxmox_spec.rb
|
104
|
+
- spec/spec_helper.rb
|
105
|
+
homepage: https://github.com/ulayer/ruby-proxmox
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 2.7.6
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: A ruby gem for managing Proxmox Servers with Ruby. Based on https://github.com/nledez/proxmox
|
129
|
+
test_files:
|
130
|
+
- spec/lib/proxmox_spec.rb
|
131
|
+
- spec/spec_helper.rb
|