profitbricks 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ === 0.5.0 / 2012-04-11
2
+
3
+ * 2 major enhancements:
4
+
5
+ * Added a binary profitbricks to use the API from the command line
6
+ * DataCenter.create now excepts a Hash
7
+
1
8
  === 0.4.1 / 2012-04-11
2
9
 
3
10
  * 1 bug fix:
data/Manifest.txt CHANGED
@@ -10,6 +10,7 @@ Rakefile
10
10
  bin/profitbricks
11
11
  examples/create_datacenter.rb
12
12
  lib/profitbricks.rb
13
+ lib/profitbricks/cli.rb
13
14
  lib/profitbricks/config.rb
14
15
  lib/profitbricks/data_center.rb
15
16
  lib/profitbricks/extensions.rb
@@ -132,6 +133,7 @@ spec/fixtures/update_server/basic.json
132
133
  spec/fixtures/update_server/basic.xml
133
134
  spec/fixtures/update_storage/success.json
134
135
  spec/fixtures/update_storage/success.xml
136
+ spec/profitbricks/cli_spec.rb
135
137
  spec/profitbricks/data_center_spec.rb
136
138
  spec/profitbricks/firewall_spec.rb
137
139
  spec/profitbricks/image_spec.rb
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Profitbricks [![Build Status](https://secure.travis-ci.org/dsander/profitbricks.png)](http://travis-ci.org/dsander/profitbricks)
1
+ # Profitbricks [![Build Status](https://secure.travis-ci.org/dsander/profitbricks.png?branch=master)](http://travis-ci.org/dsander/profitbricks)
2
2
 
3
3
  * http://github.com/dsander/profitbricks
4
4
  * http://rubydoc.info/github/dsander/profitbricks/master/frames
@@ -29,7 +29,7 @@ Get a list of all your Datacenters
29
29
 
30
30
  Create a new Datacenter
31
31
 
32
- dc = DataCenter.create('Name')
32
+ dc = DataCenter.create(:name => 'Name')
33
33
 
34
34
  Find a Datacenter by name
35
35
 
@@ -45,6 +45,22 @@ or
45
45
 
46
46
  Check out the examples directory for more detailed usage information, or have a look at the [documentation](http://rubydoc.info/github/dsander/profitbricks/master/frames) for the class reference.
47
47
 
48
+ ## CLI
49
+
50
+ To use the profitbricks binary you first have to store your username and password in environment variables
51
+
52
+ export PROFITBRICKS_USER=yourusername
53
+ export PROFITBRICKS_PASSWORD=yourpassword
54
+
55
+ The binary always takes at least two arguments. The first represents a class name (in snake- or camel-case) and the second a method name of this class.
56
+ Get a list of all your datacenters:
57
+
58
+ profitbricks data_center all
59
+
60
+ The following arguments are coverted into a Hash and passed to the method, if you want to call instance methods you _have_ to provide the id of the Server/DataCenter, etc:
61
+
62
+ profitbricks server update id=03h17g46-3040-d1af-bb01-9579fe0300e7 cores=2 ram=1024
63
+
48
64
  ## License
49
65
  (The MIT License)
50
66
 
data/bin/profitbricks CHANGED
@@ -1,3 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- abort "you need to write me"
3
+ require 'profitbricks'
4
+ require 'profitbricks/cli'
5
+
6
+ cli = Profitbricks::CLI.new()
7
+ exit cli.run(ARGV)
@@ -13,7 +13,7 @@ end
13
13
  # * and a database server
14
14
  #
15
15
 
16
- dc = DataCenter.create('Example Project')
16
+ dc = DataCenter.create(:name => 'Example Project')
17
17
  dc.wait_for_provisioning
18
18
 
19
19
  debian = Image.find(:name => "profitbricks-debian-squeeze-EN-6.0.1a-amd64.img")
data/lib/profitbricks.rb CHANGED
@@ -13,7 +13,7 @@ require 'profitbricks/firewall'
13
13
  require 'profitbricks/rule'
14
14
 
15
15
  module Profitbricks
16
- VERSION = '0.4.1'
16
+ VERSION = '0.5.0'
17
17
  end
18
18
 
19
19
  PB = Profitbricks
@@ -0,0 +1,107 @@
1
+ require 'optparse'
2
+ require 'pp'
3
+
4
+ module Profitbricks
5
+ class CLI
6
+ attr_accessor :stdout
7
+
8
+ def initialize(stdout = $stdout)
9
+ @options = {:debug => false}
10
+ @stdout = stdout
11
+ end
12
+
13
+ def run(options)
14
+ options = OptionParser.new do |opts|
15
+ opts.banner = "Usage: profitbricks [options] <class> <method> argument=value argument2=value2 .."
16
+ opts.separator ""
17
+ opts.separator "You have to supply your Profitbricks user name and password in the environmental variables PROFITBRICKS_USER and PROFITBRICKS_PASSWORD"
18
+ opts.separator ""
19
+ opts.on("-d", "--debug", "Enable debugging output") do |d|
20
+ @options[:debug] = d
21
+ end
22
+ opts.on_tail("-h", "--help", "Show this message") do
23
+ @stdout.puts opts
24
+ return -1
25
+ end
26
+ if !ENV['PROFITBRICKS_USER'] or !ENV['PROFITBRICKS_PASSWORD'] or options.length < 2
27
+ @stdout.puts opts
28
+ return -1
29
+ end
30
+
31
+ end.parse!(options)
32
+
33
+ Profitbricks.configure do |config|
34
+ config.username = ENV['PROFITBRICKS_USER']
35
+ config.password = ENV['PROFITBRICKS_PASSWORD']
36
+ config.log = @options[:debug]
37
+ end
38
+
39
+ (klass, m, arguments) = convert_arguments(options)
40
+
41
+ begin
42
+ klass = Profitbricks.get_class(klass)
43
+ rescue LoadError
44
+ @stdout.puts "Invalid class name #{klass}."
45
+ return -1
46
+ end
47
+
48
+ if method = get_singleton_method(klass, m)
49
+ dump = PP.pp(call_singleton_method(klass, m, arguments), "")
50
+ @stdout.puts dump
51
+ elsif method = get_instance_method(klass, m)
52
+ dump = PP.pp(call_instance_method(klass, m, arguments), "")
53
+ @stdout.puts dump
54
+ else
55
+ @stdout.puts "#{klass} has no method #{m}"
56
+ return -1
57
+ end
58
+ return 0
59
+ end
60
+
61
+
62
+ def convert_arguments(options)
63
+ arguments = Hash[options[2..-1].collect { |x|
64
+ a = x.split('=');
65
+ a[1] = a[1].to_i if a[1] =~ /^\d+$/
66
+ [a[0].to_sym, a[1]]
67
+ }]
68
+ [options[0], options[1], arguments]
69
+ end
70
+
71
+ def get_singleton_method(klass, method)
72
+ methods = klass.singleton_methods(false)
73
+ if methods.collect { |m| m.to_sym }.include?(method.to_sym)
74
+ return klass.method(method.to_sym)
75
+ end
76
+ end
77
+
78
+ def get_instance_method(klass, method)
79
+ obj = klass.send(:new, {})
80
+ methods = obj.public_methods(false)
81
+ if methods.collect { |m| m.to_sym }.include?(method.to_sym)
82
+ return obj.method(method)
83
+ end
84
+ end
85
+
86
+ def call_singleton_method(klass, method, arguments)
87
+ call_method(klass, method, arguments)
88
+ end
89
+
90
+ def call_instance_method(klass, method, arguments)
91
+ id = arguments.delete(:id)
92
+ obj = klass.send(:find, {:id => id})
93
+ call_method(obj, method, arguments)
94
+ end
95
+
96
+ def call_method(klass, method, arguments)
97
+ if arguments.length > 0
98
+ klass.send(method, arguments)
99
+ else
100
+ klass.send(method)
101
+ end
102
+ end
103
+
104
+ class << self
105
+ end
106
+ end
107
+ end
@@ -75,10 +75,11 @@ module Profitbricks
75
75
 
76
76
  # Creates and saves a new, empty Virtual Data Center.
77
77
  #
78
- # @param [String] Name of the Virtual Data Center (can not start with or contain (@, /, \\, |, ", '))
78
+ # @param [Hash] options
79
+ # @option options [String] :name Name of the Virtual Data Center (can not start with or contain (@, /, \\, |, ", '))
79
80
  # @return [DataCenter] The newly created Virtual Data Center
80
- def create(name)
81
- response = Profitbricks.request :create_data_center, "<dataCenterName>#{name}</dataCenterName>"
81
+ def create(options)
82
+ response = Profitbricks.request :create_data_center, "<dataCenterName>#{options[:name]}</dataCenterName>"
82
83
  self.find(:id => response.to_hash[:create_data_center_response][:return][:data_center_id] )
83
84
  end
84
85
 
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'profitbricks/cli'
3
+
4
+ describe Profitbricks::CLI do
5
+ include Savon::Spec::Macros
6
+
7
+ before(:all) do
8
+ ENV['PROFITBRICKS_USER'] = 'bogus'
9
+ ENV['PROFITBRICKS_PASSWORD'] = 'bogus'
10
+ end
11
+ let(:cli) { Profitbricks::CLI.new(StringIO.new) }
12
+
13
+ it "should return with no username and password" do
14
+ ENV.delete('PROFITBRICKS_USER')
15
+ cli.run(["data_center", "all"]).should == -1
16
+ ENV['PROFITBRICKS_USER'] = 'bogus'
17
+ end
18
+
19
+ it "should require at least to arguments" do
20
+ cli.run(["data_center"]).should == -1
21
+ end
22
+
23
+ it "should display the help message" do
24
+ cli.run(["-h bogus"]).should == -1
25
+ end
26
+
27
+ it "should abort with a invalid class" do
28
+ cli.run(%w(bogus fail)).should == -1
29
+ end
30
+
31
+ it "should abort with a invalid method" do
32
+ cli.run(%w(server fail)).should == -1
33
+ end
34
+
35
+ it "should convert the arguments to a hash" do
36
+ args = %w(data_center create id=12 name=Test)
37
+ (klass, m, arguments) = cli.convert_arguments(args)
38
+ klass.should == "data_center"
39
+ m.should == "create"
40
+ arguments.class.should == Hash
41
+ arguments[:id].should == 12
42
+ arguments[:name].should == "Test"
43
+ end
44
+
45
+ it "should get a singleton method" do
46
+ method = cli.get_singleton_method(Profitbricks::DataCenter, 'all')
47
+ method.should == Profitbricks::DataCenter.method('all')
48
+ end
49
+
50
+ it "should get a instance method" do
51
+ method = cli.get_instance_method(Profitbricks::Server, 'update')
52
+ method.to_s.should == Profitbricks::Server.new({}).method('update').to_s
53
+ end
54
+
55
+ it "should get all data centers" do
56
+ savon.expects(:get_all_data_centers).returns(:test_datacenter)
57
+ savon.expects(:get_data_center).returns(:two_servers_with_storage)
58
+ cli.run(%w(data_center all)).should == 0
59
+ end
60
+
61
+ it "should update a server" do
62
+ savon.expects(:get_server).returns(:after_create)
63
+ savon.expects(:update_server).returns(:basic)
64
+ cli.run(%w(server update id=1234-123 name=meme ram=256 cores=1)).should == 0
65
+ end
66
+ end
@@ -6,7 +6,7 @@ describe Profitbricks::DataCenter do
6
6
  it "should create a new datacenter" do
7
7
  savon.expects(:create_data_center).returns(:success)
8
8
  savon.expects(:get_data_center).returns(:create)
9
- dc = DataCenter.create('Test2')
9
+ dc = DataCenter.create(:name => 'Test2')
10
10
  dc.name.should == 'Test2'
11
11
  dc.id.should == "b3eebede-5c78-417c-b1bc-ff5de01a0602"
12
12
  dc.version.should == 9
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: profitbricks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-04-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: savon
16
- requirement: &22770020 !ruby/object:Gem::Requirement
16
+ requirement: &17993060 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *22770020
24
+ version_requirements: *17993060
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rdoc
27
- requirement: &22769000 !ruby/object:Gem::Requirement
27
+ requirement: &17990940 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.10'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *22769000
35
+ version_requirements: *17990940
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: hoe
38
- requirement: &22768260 !ruby/object:Gem::Requirement
38
+ requirement: &17989460 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '3.0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *22768260
46
+ version_requirements: *17989460
47
47
  description: A Ruby client for the ProfitBricks API.
48
48
  email:
49
49
  - git@dsander.de
@@ -65,6 +65,7 @@ files:
65
65
  - bin/profitbricks
66
66
  - examples/create_datacenter.rb
67
67
  - lib/profitbricks.rb
68
+ - lib/profitbricks/cli.rb
68
69
  - lib/profitbricks/config.rb
69
70
  - lib/profitbricks/data_center.rb
70
71
  - lib/profitbricks/extensions.rb
@@ -187,6 +188,7 @@ files:
187
188
  - spec/fixtures/update_server/basic.xml
188
189
  - spec/fixtures/update_storage/success.json
189
190
  - spec/fixtures/update_storage/success.xml
191
+ - spec/profitbricks/cli_spec.rb
190
192
  - spec/profitbricks/data_center_spec.rb
191
193
  - spec/profitbricks/firewall_spec.rb
192
194
  - spec/profitbricks/image_spec.rb