solusvm 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,108 @@
1
+ Solusvm
2
+ =======
3
+
4
+ Solusvm allows for easy interaction with the SolusVM Admin::API.
5
+ This library was first created for internal use at {Site5 LLC}[http://www.site5.com].
6
+
7
+ Basic Examples
8
+ ==============
9
+
10
+ Solusvm.config('api_id', 'api_password', :url => 'http://www.example.com/api')
11
+ server = Solusvm::Server.new
12
+
13
+ # 200 is the id of the virtual server
14
+ server.shutdown(200) # => true
15
+ server.boot(200) # => true
16
+ server.reboot(200) # => true
17
+ server.suspend(200) # => true
18
+ server.resume(200) # => true
19
+
20
+ Server creation
21
+ ===============
22
+
23
+ options = {:type => 'xen', :username => 'bob', :node => 'node1', :plan => 'plan1', :template => 'mytpl', :ips => 1}
24
+ result = sever.create('server.hostname.com', 'password', options}
25
+ p server.successful?
26
+ => true
27
+
28
+ p result
29
+ => {"mainipaddress"=>"127.0.0.1", "consoleuser"=>"console-user", "vserverid"=>"10",
30
+ "statusmsg"=>"Virtual server created", "virtid"=>"vm10", "consolepassword"=>"myPassisL33t",
31
+ "extraipaddress"=>{}, "hostname"=>"server.hostname", "rootpassword"=>"password", "status"=>"success"}
32
+
33
+
34
+ Command Line Usage
35
+ ==================
36
+
37
+ USAGE: solusvm <command> [options]
38
+ -I, --api-login [id] API ID
39
+ -K, --api-key [key] API KEY
40
+ -N, --node [node] Node to provision on
41
+ -U, --api-url [URL] URL to the API
42
+ -u, --username [username] The client to put the VPS under
43
+ -k, --kind [kind] Type of VPS (openvz,xen,xen hvm)
44
+ -t, --template [template] VPS template to boot from
45
+ -p, --plan [plan] Plan to use
46
+ -i, --ips [number] Number of ips to add to the VPS
47
+ -h, --help Show help documentation
48
+ Commands:
49
+ server-check-exists <vserverid>
50
+ server-shutdown <vserverid>
51
+ server-changeplan <vserverid> <newplan>
52
+ server-resume <vserverid>
53
+ server-reboot <vserverid>
54
+ server-status <vserverid>
55
+ server-boot <vserverid>
56
+ server-create <hostname> <password> -t myimag -k xen -p myplan -i 1
57
+ server-suspend <vserverid>
58
+ server-addip <vserverid>
59
+
60
+ Default Config for Command Line
61
+ ================================
62
+
63
+ The command line utility, solusvm, will look for a .solusvm.yml file in ~/. You can specify some defaults.
64
+
65
+ ~/.solusvm.yml
66
+ id: api_id
67
+ key: api_key
68
+ # URL to the API endpoint
69
+ url: https://portal.yoursite.com/api/admin/command.php
70
+ # Default client to put servers under
71
+ username: bob
72
+
73
+ REQUIREMENTS
74
+ ============
75
+
76
+ * xml-simple
77
+
78
+ DOCUMENTATION
79
+ =============
80
+
81
+ * http://solusvm.rubyforge.org/solusvm/
82
+
83
+ INSTALL:
84
+ ========
85
+
86
+ gem install solusvm
87
+
88
+ Contributors
89
+ ============
90
+
91
+ * [Justin Mazzi](http://github.com/jmazzi)
92
+ * [Maran H.](http://github.com/maran)
93
+
94
+ Note on Patches/Pull Requests
95
+ =============================
96
+
97
+ * Fork the project.
98
+ * Make your feature addition or bug fix.
99
+ * Add tests for it. This is important so I don't break it in a
100
+ future version unintentionally.
101
+ * Commit, do not mess with rakefile, version, or history.
102
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
103
+ * Send me a pull request. Bonus points for topic branches.
104
+
105
+ Copyright
106
+ =========
107
+
108
+ Copyright (c) 2010 Site5. See LICENSE for details.
@@ -1,5 +1,5 @@
1
1
  ---
2
- :patch: 1
3
- :build:
4
2
  :major: 0
5
- :minor: 5
3
+ :build:
4
+ :minor: 6
5
+ :patch: 0
@@ -8,20 +8,28 @@ $:.unshift(File.join(File.dirname(__FILE__), "/../lib"))
8
8
  require "solusvm"
9
9
 
10
10
  opts = {}
11
- shell_methods = {}
12
- shell_methods['server-create'] = "<hostname> <password> -t myimage -k xen -p myplan -i 1"
13
- shell_methods['server-boot'] = "<vserverid>"
14
- shell_methods['server-reboot'] = "<vserverid>"
15
- shell_methods['server-shutdown'] = "<vserverid>"
16
- shell_methods['server-suspend'] = "<vserverid>"
17
- shell_methods['server-resume'] = "<vserverid>"
18
- shell_methods['server-status'] = "<vserverid>"
19
- shell_methods['server-addip'] = "<vserverid>"
20
- shell_methods['server-changeplan'] = "<vserverid> <newplan>"
21
- shell_methods['server-check-exists'] = "<vserverid>"
22
- shell_methods['server-terminate'] = "<vserverid>"
23
-
24
- OptionParser.new do |o|
11
+ $shell_methods = {}
12
+ $shell_methods['server-create'] = "<hostname> <password> -t myimage -k xen -p myplan -i 1"
13
+ $shell_methods['server-boot'] = "<vserverid>"
14
+ $shell_methods['server-reboot'] = "<vserverid>"
15
+ $shell_methods['server-shutdown'] = "<vserverid>"
16
+ $shell_methods['server-suspend'] = "<vserverid>"
17
+ $shell_methods['server-resume'] = "<vserverid>"
18
+ $shell_methods['server-status'] = "<vserverid>"
19
+ $shell_methods['server-addip'] = "<vserverid>"
20
+ $shell_methods['server-changeplan'] = "<vserverid> <newplan>"
21
+ $shell_methods['server-check-exists'] = "<vserverid>"
22
+ $shell_methods['server-terminate'] = "<vserverid>"
23
+
24
+ $shell_methods['node-available-ips'] = "<nodeid>"
25
+
26
+ def list_commands
27
+ puts "Commands:"
28
+ puts $shell_methods.collect { |k,v| " #{k} #{v}"}.join("\n")
29
+ exit
30
+ end
31
+
32
+ op = OptionParser.new do |o|
25
33
  o.banner = "USAGE: #{File.basename($0)} <command> [options]"
26
34
  o.on("-I", "--api-login [id]", "API ID") do |opt|
27
35
  opts[:api_id] = opt
@@ -61,17 +69,21 @@ OptionParser.new do |o|
61
69
 
62
70
  o.on("-h", "--help", "Show help documentation") do |h|
63
71
  puts o
64
- puts "Commands:"
65
- puts shell_methods.collect { |k,v| " #{k} #{v}"}.join("\n")
66
-
67
- exit
72
+ list_commands
68
73
  end
69
- end.parse!
74
+ end
75
+
76
+ optparse = op
77
+ op.parse!
70
78
 
71
79
  config_file = File.join(File.expand_path(ENV['HOME']), '.solusvm.yml')
72
80
  server = Solusvm::Server.new
81
+ general = Solusvm::General.new
82
+
73
83
  if ARGV.empty?
74
- STDERR.puts "USAGE: #{File.basename($0)} [function] [options]"
84
+ # STDERR.puts "USAGE: #{File.basename($0)} [function] [options]"
85
+ puts optparse.help
86
+ list_commands
75
87
  else
76
88
  if File.exists?(config_file)
77
89
  config = YAML::load(File.open(config_file))
@@ -84,37 +96,44 @@ else
84
96
  exit
85
97
  end
86
98
  meth = ARGV[0].chomp
87
- if shell_methods.include?(meth)
99
+ if $shell_methods.include?(meth)
88
100
  ARGV.shift
89
101
  if ARGV.empty?
90
- p shell_methods[meth]
102
+ p $shell_methods[meth]
91
103
  exit
92
104
  else
93
- case meth
94
- when 'server-create'
95
- unless ARGV.size == 2
96
- p shell_methods[meth]
97
- exit
105
+ begin
106
+ case meth
107
+ when 'server-create'
108
+ unless ARGV.size == 2
109
+ list_commands
110
+ end
111
+ p server.create(ARGV[0], ARGV[1], :plan => opts[:plan], :ips => opts[:ips], :type => opts[:kind],
112
+ :username => opts[:username], :template => opts[:template], :node => opts[:node])
113
+ when 'server-status'
114
+ p server.status(ARGV[0])
115
+ when 'server-boot'
116
+ p server.boot(ARGV[0])
117
+ when 'server-reboot'
118
+ p server.reboot(ARGV[0])
119
+ when 'server-suspend'
120
+ p server.suspend(ARGV[0])
121
+ when 'server-resume'
122
+ p server.resume(ARGV[0])
123
+ when 'server-check-exists'
124
+ p server.exists?(ARGV[0])
125
+ when 'server-terminate'
126
+ p server.terminate(ARGV[0])
127
+ when 'node-available-ips'
128
+ p general.node_available_ips(ARGV[0])
98
129
  end
99
- p server.create(ARGV[0], ARGV[1], :plan => opts[:plan], :ips => opts[:ips], :type => opts[:kind],
100
- :username => opts[:username], :template => opts[:template], :node => opts[:node])
101
- when 'server-status'
102
- p server.status(ARGV[0])
103
- when 'server-boot'
104
- p server.boot(ARGV[0])
105
- when 'server-reboot'
106
- p server.reboot(ARGV[0])
107
- when 'server-suspend'
108
- p server.suspend(ARGV[0])
109
- when 'server-resume'
110
- p server.resume(ARGV[0])
111
- when 'server-check-exists'
112
- p server.exists?(ARGV[0])
113
- when 'server-terminate'
114
- p server.terminate(ARGV[0])
130
+ rescue Exception => e
131
+ puts "Error: #{e}\n\n"
132
+ puts "Backtrace: \n\n"
133
+ puts e.backtrace.join("\n")
115
134
  end
116
135
  end
117
136
  else
118
137
  puts "#{meth} is not a valid function"
119
138
  end
120
- end
139
+ end
@@ -26,6 +26,7 @@ module Solusvm
26
26
  request = Net::HTTP::Get.new("#{api_endpoint.path}?#{options.to_query}")
27
27
  response = http.request(request)
28
28
 
29
+ handle_errors(response.body)
29
30
  @returned_parameters = parse_response(response.body)
30
31
  log_messages(options)
31
32
  end
@@ -38,6 +39,18 @@ module Solusvm
38
39
  XmlSimple.xml_in(body, 'ForceArray' => false)
39
40
  end
40
41
 
42
+ # Look for known error messages
43
+ def handle_errors(body)
44
+ case body.downcase
45
+ when /invalid ipaddress/i
46
+ raise "This IP is not authorized to use the API"
47
+ when /Invalid id or key/i
48
+ raise "Invalid ID or key"
49
+ when /Node not found/i
50
+ raise "Node does not exist"
51
+ end
52
+ end
53
+
41
54
  # Returns true when a request has been successful
42
55
  #
43
56
  # my_class = MyClass.new
@@ -80,4 +93,4 @@ module Solusvm
80
93
  end
81
94
  end
82
95
  end
83
- end
96
+ end
@@ -16,5 +16,16 @@ module Solusvm
16
16
  perform_request(:action => 'node-statistics', :nodeid => nodeid)
17
17
  returned_parameters
18
18
  end
19
+
20
+ # List a nodes available IPs
21
+ def node_available_ips(nodeid)
22
+ perform_request(:action => 'node-iplist', :nodeid => nodeid)
23
+ puts statusmsg
24
+ if statusmsg.match /no available ip/i
25
+ []
26
+ else
27
+ returned_parameters['ips'].split(',')
28
+ end
29
+ end
19
30
  end
20
- end
31
+ end
@@ -5,18 +5,18 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{solusvm}
8
- s.version = "0.5.1"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Justin Mazzi"]
12
- s.date = %q{2010-07-24}
12
+ s.date = %q{2010-08-04}
13
13
  s.default_executable = %q{solusvm}
14
14
  s.description = %q{Solusvm allows for easy interaction with the SolusVM Admin::API.}
15
15
  s.email = %q{jmazzi@gmail.com}
16
16
  s.executables = ["solusvm"]
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE",
19
- "README.rdoc"
19
+ "README.markdown"
20
20
  ]
21
21
  s.files = [
22
22
  ".document",
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
  "Gemfile",
25
25
  "Gemfile.lock",
26
26
  "LICENSE",
27
- "README.rdoc",
27
+ "README.markdown",
28
28
  "Rakefile",
29
29
  "VERSION.yml",
30
30
  "bin/solusvm",
@@ -36,6 +36,9 @@ Gem::Specification.new do |s|
36
36
  "lib/solusvm/hash.rb",
37
37
  "lib/solusvm/server.rb",
38
38
  "solusvm.gemspec",
39
+ "test/fixtures/base_bad_key.txt",
40
+ "test/fixtures/base_node_does_not_exist.txt",
41
+ "test/fixtures/base_unauthorized_ip.txt",
39
42
  "test/fixtures/client_authenticate_error.txt",
40
43
  "test/fixtures/client_authenticate_success.txt",
41
44
  "test/fixtures/client_change_password_error.txt",
@@ -44,6 +47,8 @@ Gem::Specification.new do |s|
44
47
  "test/fixtures/client_create_success.txt",
45
48
  "test/fixtures/client_exists_success.txt",
46
49
  "test/fixtures/error.txt",
50
+ "test/fixtures/general_node_list_all_ips_available.txt",
51
+ "test/fixtures/general_node_list_all_ips_not_available.txt",
47
52
  "test/fixtures/general_node_statistics_success.txt",
48
53
  "test/fixtures/general_nodes_success.txt",
49
54
  "test/fixtures/general_templates_success.txt",
@@ -0,0 +1 @@
1
+ Invalid id or key
@@ -0,0 +1 @@
1
+ Node not found
@@ -0,0 +1 @@
1
+ Invalid ipaddress
@@ -0,0 +1,4 @@
1
+ <status>success</status>
2
+ <statusmsg>Available ip addresses</statusmsg>
3
+ <ipcount>3</ipcount>
4
+ <ips>123.123.123.123,124.124.124.124,125.125.125.125</ips>
@@ -0,0 +1,4 @@
1
+ <status>success</status>
2
+ <statusmsg>No available ip addresses</statusmsg>
3
+ <ipcount>3</ipcount>
4
+ <ips></ips>
@@ -68,4 +68,37 @@ class TestBase < Test::Unit::TestCase
68
68
  assert_equal 'Invalid Virtual Server type: bob', e.message
69
69
  end
70
70
  end
71
+
72
+ def test_unautorized_ip
73
+ FakeWeb.register_uri(:get, "#{base_uri}&action=unauthorized", :body => load_response('base_unauthorized_ip'))
74
+ message = ""
75
+ begin
76
+ @base.perform_request(:action => 'unauthorized')
77
+ rescue Exception => e
78
+ message = e
79
+ end
80
+ assert_equal "This IP is not authorized to use the API", message.to_s
81
+ end
82
+
83
+ def test_invalid_key_or_id
84
+ FakeWeb.register_uri(:get, "#{base_uri}&action=badkey", :body => load_response('base_bad_key'))
85
+ message = ""
86
+ begin
87
+ @base.perform_request(:action => 'badkey')
88
+ rescue Exception => e
89
+ message = e
90
+ end
91
+ assert_equal "Invalid ID or key", message.to_s
92
+ end
93
+
94
+ def test_node_does_not_exist
95
+ FakeWeb.register_uri(:get, "#{base_uri}&action=nodeexist", :body => load_response('base_node_does_not_exist'))
96
+ message = ""
97
+ begin
98
+ @base.perform_request(:action => 'nodeexist')
99
+ rescue Exception => e
100
+ message = e
101
+ end
102
+ assert_equal "Node does not exist", message.to_s
103
+ end
71
104
  end
@@ -60,4 +60,20 @@ class TestGeneral < Test::Unit::TestCase
60
60
  assert_equal 'hostname.com', node_statistics['hostname']
61
61
  assert_equal 'success', node_statistics['status']
62
62
  end
63
- end
63
+
64
+ def test_list_all_ips_available
65
+ FakeWeb.register_uri(:get, "#{base_uri}&action=node-iplist&nodeid=1", :body => load_response('general_node_list_all_ips_available'))
66
+ avaialble_ips = @general.node_available_ips(1)
67
+
68
+ expected_ips = %w(123.123.123.123 124.124.124.124 125.125.125.125).sort
69
+ assert !avaialble_ips.empty?
70
+ assert_equal expected_ips, avaialble_ips.sort
71
+ end
72
+
73
+ def test_list_all_ips_not_available
74
+ FakeWeb.register_uri(:get, "#{base_uri}&action=node-iplist&nodeid=1", :body => load_response('general_node_list_all_ips_not_available'))
75
+ avaialble_ips = @general.node_available_ips(1)
76
+
77
+ assert avaialble_ips.empty?
78
+ end
79
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solusvm
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Justin Mazzi
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-24 00:00:00 -04:00
18
+ date: 2010-08-04 00:00:00 -04:00
19
19
  default_executable: solusvm
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -40,14 +40,14 @@ extensions: []
40
40
 
41
41
  extra_rdoc_files:
42
42
  - LICENSE
43
- - README.rdoc
43
+ - README.markdown
44
44
  files:
45
45
  - .document
46
46
  - .gitignore
47
47
  - Gemfile
48
48
  - Gemfile.lock
49
49
  - LICENSE
50
- - README.rdoc
50
+ - README.markdown
51
51
  - Rakefile
52
52
  - VERSION.yml
53
53
  - bin/solusvm
@@ -59,6 +59,9 @@ files:
59
59
  - lib/solusvm/hash.rb
60
60
  - lib/solusvm/server.rb
61
61
  - solusvm.gemspec
62
+ - test/fixtures/base_bad_key.txt
63
+ - test/fixtures/base_node_does_not_exist.txt
64
+ - test/fixtures/base_unauthorized_ip.txt
62
65
  - test/fixtures/client_authenticate_error.txt
63
66
  - test/fixtures/client_authenticate_success.txt
64
67
  - test/fixtures/client_change_password_error.txt
@@ -67,6 +70,8 @@ files:
67
70
  - test/fixtures/client_create_success.txt
68
71
  - test/fixtures/client_exists_success.txt
69
72
  - test/fixtures/error.txt
73
+ - test/fixtures/general_node_list_all_ips_available.txt
74
+ - test/fixtures/general_node_list_all_ips_not_available.txt
70
75
  - test/fixtures/general_node_statistics_success.txt
71
76
  - test/fixtures/general_nodes_success.txt
72
77
  - test/fixtures/general_templates_success.txt
@@ -1,85 +0,0 @@
1
- = Solusvm
2
-
3
- Solusvm allows for easy interaction with the SolusVM Admin::API.
4
-
5
- This library was first created for internal use at {Site5 LLC}[http://www.site5.com].
6
-
7
- == Basic Examples
8
- Solusvm.config('api_id', 'api_password', :url => 'http://www.example.com/api')
9
- server = Solusvm::Server.new
10
-
11
- # 200 is the id of the virtual server
12
- server.shutdown(200) # => true
13
- server.boot(200) # => true
14
- server.reboot(200) # => true
15
- server.suspend(200) # => true
16
- server.resume(200) # => true
17
-
18
- == Server creation
19
- options = {:type => 'xen', :username => 'bob', :node => 'node1', :plan => 'plan1', :template => 'mytpl', :ips => 1}
20
- result = sever.create('server.hostname.com', 'password', options}
21
- p server.successful?
22
- => true
23
-
24
- p result
25
- => {"mainipaddress"=>"127.0.0.1", "consoleuser"=>"console-user", "vserverid"=>"10",
26
- "statusmsg"=>"Virtual server created", "virtid"=>"vm10", "consolepassword"=>"myPassisL33t",
27
- "extraipaddress"=>{}, "hostname"=>"server.hostname", "rootpassword"=>"password", "status"=>"success"}
28
-
29
-
30
- == Command Line Usage
31
- USAGE: solusvm <command> [options]
32
- -I, --api-login [id] API ID
33
- -K, --api-key [key] API KEY
34
- -N, --node [node] Node to provision on
35
- -U, --api-url [URL] URL to the API
36
- -u, --username [username] The client to put the VPS under
37
- -k, --kind [kind] Type of VPS (openvz,xen,xen hvm)
38
- -t, --template [template] VPS template to boot from
39
- -p, --plan [plan] Plan to use
40
- -i, --ips [number] Number of ips to add to the VPS
41
- -h, --help Show help documentation
42
- Commands:
43
- server-check-exists <vserverid>
44
- server-shutdown <vserverid>
45
- server-changeplan <vserverid> <newplan>
46
- server-resume <vserverid>
47
- server-reboot <vserverid>
48
- server-status <vserverid>
49
- server-boot <vserverid>
50
- server-create <hostname> <password> -t myimag -k xen -p myplan -i 1
51
- server-suspend <vserverid>
52
- server-addip <vserverid>
53
-
54
- == Default Config for Command Line
55
- The command line utility, solusvm, will look for a .solusvm.yml file in ~/. You can specify some defaults.
56
- ~/.solusvm.yml
57
- id: api_id
58
- key: api_key
59
- # URL to the API endpoint
60
- url: https://portal.yoursite.com/api/admin/command.php
61
- # Default client to put servers under
62
- username: bob
63
-
64
- == REQUIREMENTS:
65
- * xml-simple
66
-
67
- == DOCUMENTATION
68
- * http://solusvm.rubyforge.org/solusvm/
69
-
70
- == INSTALL:
71
- * gem install solusvm
72
-
73
- == Note on Patches/Pull Requests
74
-
75
- * Fork the project.
76
- * Make your feature addition or bug fix.
77
- * Add tests for it. This is important so I don't break it in a
78
- future version unintentionally.
79
- * Commit, do not mess with rakefile, version, or history.
80
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
81
- * Send me a pull request. Bonus points for topic branches.
82
-
83
- == Copyright
84
-
85
- Copyright (c) 2010 Site5. See LICENSE for details.