profitbricks 0.9.9 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -2
  3. data/Gemfile.lock +19 -22
  4. data/Guardfile +9 -0
  5. data/Manifest.txt +15 -0
  6. data/README.md +1 -1
  7. data/Rakefile +13 -5
  8. data/lib/profitbricks.rb +7 -5
  9. data/lib/profitbricks/data_center.rb +19 -20
  10. data/lib/profitbricks/extensions.rb +0 -3
  11. data/lib/profitbricks/firewall.rb +14 -20
  12. data/lib/profitbricks/image.rb +4 -6
  13. data/lib/profitbricks/ip_block.rb +5 -6
  14. data/lib/profitbricks/load_balancer.rb +23 -48
  15. data/lib/profitbricks/model.rb +8 -35
  16. data/lib/profitbricks/nic.rb +17 -22
  17. data/lib/profitbricks/profitbricks.rb +35 -27
  18. data/lib/profitbricks/rule.rb +2 -2
  19. data/lib/profitbricks/server.rb +96 -18
  20. data/lib/profitbricks/storage.rb +17 -22
  21. data/profitbricks.gemspec +6 -6
  22. data/spec/fixtures/get_server/two_nics.json +1 -0
  23. data/spec/fixtures/get_server/two_nics.xml +1 -0
  24. data/spec/fixtures/get_storage/mount_image.json +21 -0
  25. data/spec/fixtures/get_storage/mount_image.xml +1 -0
  26. data/spec/fixtures/power_off_server/success.json +1 -0
  27. data/spec/fixtures/power_off_server/success.xml +1 -0
  28. data/spec/fixtures/reset_server/success.json +1 -0
  29. data/spec/fixtures/reset_server/success.xml +1 -0
  30. data/spec/fixtures/shutdown_server/success.json +1 -0
  31. data/spec/fixtures/shutdown_server/success.xml +1 -0
  32. data/spec/fixtures/start_server/success.json +1 -0
  33. data/spec/fixtures/start_server/success.xml +1 -0
  34. data/spec/live/data_center_spec.rb +47 -0
  35. data/spec/live/server_spec.rb +58 -0
  36. data/spec/profitbricks/cli_spec.rb +13 -6
  37. data/spec/profitbricks/data_center_spec.rb +54 -29
  38. data/spec/profitbricks/firewall_spec.rb +17 -11
  39. data/spec/profitbricks/image_spec.rb +8 -5
  40. data/spec/profitbricks/ip_block_spec.rb +8 -5
  41. data/spec/profitbricks/load_balancer_spec.rb +23 -16
  42. data/spec/profitbricks/model_spec.rb +10 -13
  43. data/spec/profitbricks/nic_spec.rb +16 -13
  44. data/spec/profitbricks/server_spec.rb +117 -11
  45. data/spec/profitbricks/storage_spec.rb +22 -13
  46. data/spec/spec_helper.rb +10 -23
  47. metadata +19 -5
  48. data/.gemtest +0 -0
@@ -18,8 +18,8 @@ module Profitbricks
18
18
  #
19
19
  # @return [Boolean] true on success, false otherwise
20
20
  def release
21
- response = Profitbricks.request :release_public_ip_block, "<blockId>#{self.id}</blockId>"
22
- return true if response.to_hash[:release_public_ip_block_response][:return]
21
+ response = Profitbricks.request :release_public_ip_block, block_id: self.id
22
+ return true
23
23
  end
24
24
 
25
25
  class << self
@@ -28,8 +28,7 @@ module Profitbricks
28
28
  # @return [Array<IpBlock>] List of all IpBlocks
29
29
  def all
30
30
  response = Profitbricks.request :get_all_public_ip_blocks
31
- datacenters = response.to_hash[:get_all_public_ip_blocks_response][:return]
32
- [datacenters].flatten.compact.collect do |block|
31
+ [response].flatten.compact.collect do |block|
33
32
  PB::IpBlock.new(block)
34
33
  end
35
34
  end
@@ -39,8 +38,8 @@ module Profitbricks
39
38
  # @param [Fixnum] Block size / amount of IPs to reserve
40
39
  # @return [IpBlock] The reserved IpBlock
41
40
  def reserve(amount)
42
- response = Profitbricks.request :reserve_public_ip_block, "<blockSize>#{amount}</blockSize>"
43
- return PB::IpBlock.new(response.to_hash[:reserve_public_ip_block_response][:return])
41
+ response = Profitbricks.request :reserve_public_ip_block, block_size: amount
42
+ return PB::IpBlock.new(response)
44
43
  end
45
44
 
46
45
 
@@ -12,12 +12,10 @@ module Profitbricks
12
12
  # @return [Boolean] true on success, false otherwise
13
13
  def update(options = {})
14
14
  options.merge!(:load_balancer_id=> self.id)
15
- xml = "<arg0>"
16
- xml += get_xml_and_update_attributes options, [:load_balancer_id, :ip, :name, :algorithm]
17
- xml += "</arg0>"
18
- response = Profitbricks.request :update_load_balancer, xml
15
+ options[:load_balancer_name] = options.delete :name
16
+ response = Profitbricks.request :update_load_balancer, options
19
17
  self.reload
20
- return true if response.to_hash[:update_load_balancer_response][:return]
18
+ return true
21
19
  end
22
20
 
23
21
  # Adds new servers to the Load Balancer within the respective LAN.
@@ -31,14 +29,10 @@ module Profitbricks
31
29
  # @return [Boolean] true on success, false otherwise
32
30
  def register_servers(servers)
33
31
  raise "You have to provide at least one server" unless servers
34
- options = {:load_balancer_id => self.id}
35
- xml = get_xml_and_update_attributes options, [:load_balancer_id]
36
- servers.each do |server|
37
- xml += "<serverIds>#{server.id}</serverIds>"
38
- end
39
- response = Profitbricks.request :register_servers_on_load_balancer, xml
40
- update_attributes(response.to_hash[:register_servers_on_load_balancer_response][:return])
41
- return true if response.to_hash[:register_servers_on_load_balancer_response][:return]
32
+ options = {load_balancer_id: self.id, server_ids: servers.collect(&:id)}
33
+ response = Profitbricks.request :register_servers_on_load_balancer, options
34
+ self.reload
35
+ return true
42
36
  end
43
37
 
44
38
  # Removes servers from the load balancer
@@ -51,13 +45,9 @@ module Profitbricks
51
45
  # @return [Boolean] true on success, false otherwise
52
46
  def deregister_servers(servers)
53
47
  raise "You have to provide at least one server" unless servers
54
- options = {:load_balancer_id => self.id}
55
- xml = get_xml_and_update_attributes options, [:load_balancer_id]
56
- servers.each do |server|
57
- xml += "<serverIds>#{server.id}</serverIds>"
58
- end
59
- response = Profitbricks.request :deregister_servers_on_load_balancer, xml
60
- return true if response.to_hash[:deregister_servers_on_load_balancer_response][:return]
48
+ options = {load_balancer_id: self.id, server_ids: servers.collect(&:id)}
49
+ response = Profitbricks.request :deregister_servers_on_load_balancer, options
50
+ return true
61
51
  end
62
52
 
63
53
  # Enables the load balancer to distribute traffic to the specified servers.
@@ -66,13 +56,9 @@ module Profitbricks
66
56
  # @return [Boolean] true on success, false otherwise
67
57
  def activate_servers(servers)
68
58
  raise "You have to provide at least one server" unless servers
69
- options = {:load_balancer_id => self.id}
70
- xml = get_xml_and_update_attributes options, [:load_balancer_id]
71
- servers.each do |server|
72
- xml += "<serverIds>#{server.id}</serverIds>"
73
- end
74
- response = Profitbricks.request :activate_load_balancing_on_servers, xml
75
- return true if response.to_hash[:activate_load_balancing_on_servers_response][:return]
59
+ options = {load_balancer_id: self.id, server_ids: servers.collect(&:id)}
60
+ response = Profitbricks.request :activate_load_balancing_on_servers, options
61
+ return true
76
62
  end
77
63
 
78
64
  # Disables the load balancer to distribute traffic to the specified servers.
@@ -81,13 +67,9 @@ module Profitbricks
81
67
  # @return [Boolean] true on success, false otherwise
82
68
  def deactivate_servers(servers)
83
69
  raise "You have to provide at least one server" unless servers
84
- options = {:load_balancer_id => self.id}
85
- xml = get_xml_and_update_attributes options, [:load_balancer_id]
86
- servers.each do |server|
87
- xml += "<serverIds>#{server.id}</serverIds>"
88
- end
89
- response = Profitbricks.request :deactivate_load_balancing_on_servers, xml
90
- return true if response.to_hash[:deactivate_load_balancing_on_servers_response][:return]
70
+ options = {load_balancer_id: self.id, server_ids: servers.collect(&:id)}
71
+ response = Profitbricks.request :deactivate_load_balancing_on_servers, options
72
+ return true
91
73
  end
92
74
 
93
75
  # Deletes an existing load balancer.
@@ -96,8 +78,8 @@ module Profitbricks
96
78
  #
97
79
  # @return [Boolean] true on success, false otherwise
98
80
  def delete
99
- response = Profitbricks.request :delete_load_balancer, "<loadBalancerId>#{self.id}</loadBalancerId>"
100
- return true if response.to_hash[:delete_load_balancer_response][:return]
81
+ Profitbricks.request :delete_load_balancer, load_balancer_id: self.id
82
+ return true
101
83
  end
102
84
 
103
85
  class << self
@@ -116,16 +98,9 @@ module Profitbricks
116
98
  # @option options [Array<Server>] :servers Array of servers to connect to the LoadBalancer
117
99
  # @return [LoadBalancer] The created LoadBalancer
118
100
  def create(options = {})
119
- xml = "<arg0>"
120
- xml += get_xml_and_update_attributes options, [:data_center_id, :lan_id, :ip, :name, :algorithm]
121
- unless options[:servers].nil?
122
- options[:servers].each do |server|
123
- xml += "<serverIds>#{server.id}</serverIds>"
124
- end
125
- end
126
- xml += "</arg0>"
127
- response = Profitbricks.request :create_load_balancer, xml
128
- self.find(:id => response.to_hash[:create_load_balancer_response][:return][:load_balancer_id])
101
+ options[:server_ids] = options.delete(:servers).collect(&:id) if options[:servers]
102
+ response = Profitbricks.request :create_load_balancer, options
103
+ self.find(:id => response[:load_balancer_id])
129
104
  end
130
105
 
131
106
  # Returns information about a virtual load balancer.
@@ -135,8 +110,8 @@ module Profitbricks
135
110
  # @return [LoadBalancer] The found LoadBalancer
136
111
  def find(options = {})
137
112
  raise "Unable to locate the LoadBalancer named '#{options[:name]}'" unless options[:id]
138
- response = Profitbricks.request :get_load_balancer, "<loadBalancerId>#{options[:id]}</loadBalancerId>"
139
- PB::LoadBalancer.new(response.to_hash[:get_load_balancer_response][:return])
113
+ response = Profitbricks.request :get_load_balancer, load_balancer_id: options[:id]
114
+ PB::LoadBalancer.new(response)
140
115
  end
141
116
  end
142
117
  end
@@ -28,21 +28,6 @@ module Profitbricks
28
28
  def self.belongs_to(model, options = {})
29
29
  klass = Profitbricks.get_class model.to_s, options
30
30
  @@associations[model] = {:type => :belongs_to, :class => klass}
31
- define_method(model) { instance_variable_get("@#{model}") }
32
- end
33
-
34
- def get_xml_and_update_attributes(hash, attributes=nil)
35
- attributes = hash.keys if attributes.nil?
36
- attributes.each do |a|
37
- initialize_getter(a, hash[a]) if hash[a]
38
- end
39
- hash, attributes = self.class.expand_attributes(hash, attributes, self.class)
40
- xml = self.class.build_xml(hash, attributes)
41
- end
42
-
43
- def self.get_xml_and_update_attributes(hash, attributes=[])
44
- hash, attributes = expand_attributes(hash, attributes, name())
45
- self.build_xml(hash, attributes)
46
31
  end
47
32
 
48
33
  def attributes
@@ -54,6 +39,12 @@ module Profitbricks
54
39
  end
55
40
 
56
41
  private
42
+ def update_attributes_from_hash(updated)
43
+ updated.keys.each do |a|
44
+ initialize_getter(a, updated[a])
45
+ self.instance_variable_set("@#{a}", updated[a])
46
+ end
47
+ end
57
48
  def update_attributes(updated)
58
49
  self.instance_variables.each do |var|
59
50
  self.instance_variable_set(var, updated.instance_variable_get(var))
@@ -66,12 +57,6 @@ module Profitbricks
66
57
  value
67
58
  end
68
59
 
69
- def self.build_xml(hash ,attributes)
70
- attributes.collect do |a|
71
- "<#{a.to_s.lower_camelcase}>#{hash[a]}</#{a.to_s.lower_camelcase}>" if hash[a]
72
- end.join('')
73
- end
74
-
75
60
  def initialize_getter name, value=nil
76
61
  self.class.send :define_method, name do
77
62
  instance_variable_get("@#{name}")
@@ -95,19 +80,7 @@ module Profitbricks
95
80
  end
96
81
 
97
82
  def initialize_belongs_to_association name, association, value
98
- self.instance_variable_set("@#{name}", association[:class].send(:new, value, self))
99
- end
100
-
101
- def self.expand_attributes(hash, attributes, klass=nil)
102
- [:name, :algorithm].each do |a|
103
- deleted = hash.delete(a)
104
- if deleted
105
- hash["#{klass.to_s.underscore}_#{a.to_s}"] = deleted
106
- attributes.delete(a)
107
- attributes.push "#{klass.to_s.underscore}_#{a.to_s}"
108
- end
109
- end
110
- return hash, attributes
83
+ initialize_getter name, association[:class].send(:new, value, self)
111
84
  end
112
- end
85
+ end
113
86
  end
@@ -13,9 +13,8 @@ module Profitbricks
13
13
  # @param [Boolean] Internet access (trUe/false)
14
14
  # @return [Boolean] true on success, false otherwise
15
15
  def set_internet_access=(value)
16
- xml = get_xml_and_update_attributes :data_center_id => self.data_center_id, :lan_id => self.lan_id, :land_id => self.lan_id, :internet_access => value
17
- response = Profitbricks.request :set_internet_access, xml
18
- return true if response.to_hash[:set_internet_access_response][:return]
16
+ response = Profitbricks.request :set_internet_access, data_center_id: self.data_center_id, lan_id: self.lan_id, internet_access: value
17
+ return true
19
18
  end
20
19
 
21
20
  # Changes the settings of an existing NIC.
@@ -27,38 +26,36 @@ module Profitbricks
27
26
  # @option options [String] :name Names the NIC
28
27
  # @return [Boolean] true on success, false otherwise
29
28
  def update(options = {})
30
- xml = "<arg0>"
31
- options.merge!(:nic_id => self.id)
32
- xml += get_xml_and_update_attributes options , [:nic_id, :lan_id, :server_id, :ip, :name]
33
- xml += "</arg0>"
34
- response = Profitbricks.request :update_nic, xml
35
- return true if response.to_hash[:update_nic_response][:return]
29
+ update_attributes_from_hash options
30
+ options[:nic_name] = options.delete :name if options[:name]
31
+ response = Profitbricks.request :update_nic, options.merge(:nic_id => self.id)
32
+ return true
36
33
  end
37
34
 
38
35
  # Adds an existing reserved public IP to a NIC. This operation is required, when dealing with reserved public IPs to ensure proper routing by the ProfitBricks cloud networking layer.
39
36
  #
40
37
  # @param [String] Reserved IP
41
38
  def add_ip(ip)
42
- response = Profitbricks.request :add_public_ip_to_nic, "<nicId>#{self.id}</nicId><ip>#{ip}</ip>"
39
+ response = Profitbricks.request :add_public_ip_to_nic, nic_id: self.id, ip: ip
43
40
  @ips.push ip
44
- return true if response.to_hash[:add_public_ip_to_nic_response][:return]
41
+ return true
45
42
  end
46
43
 
47
44
  # Removes a reserved public IP from a NIC. This operation is required, when dealing with reserved public IPs to ensure proper routing by the ProfitBricks cloud networking layer.
48
45
  #
49
46
  # @param [String] Reserved IP
50
47
  def remove_ip(ip)
51
- response = Profitbricks.request :remove_public_ip_from_nic, "<nicId>#{self.id}</nicId><ip>#{ip}</ip>"
48
+ response = Profitbricks.request :remove_public_ip_from_nic, nic_id: self.id, ip: ip
52
49
  @ips.delete ip
53
- return true if response.to_hash[:remove_public_ip_from_nic_response][:return]
50
+ return true
54
51
  end
55
52
 
56
53
  # Deletes an existing NIC.
57
54
  #
58
55
  # @return [Boolean] true on success, false otherwise
59
56
  def delete
60
- response = Profitbricks.request :delete_nic, "<nicId>#{self.id}</nicId>"
61
- return true if response.to_hash[:delete_nic_response][:return]
57
+ response = Profitbricks.request :delete_nic, nic_id: self.id
58
+ return true
62
59
  end
63
60
 
64
61
  def ip
@@ -82,11 +79,9 @@ module Profitbricks
82
79
  # @option options [String] :name Names the NIC
83
80
  # @return [Nic] The created NIC
84
81
  def create(options = {})
85
- xml = "<arg0>"
86
- xml += get_xml_and_update_attributes options, [:server_id, :lan_id, :ip, :name]
87
- xml += "</arg0>"
88
- response = Profitbricks.request :create_nic, xml
89
- self.find(:id => response.to_hash[:create_nic_return][:return][:nic_id])
82
+ options[:nic_name] = options.delete :name if options[:name]
83
+ response = Profitbricks.request :create_nic, options
84
+ self.find(:id => response[:nic_id])
90
85
  end
91
86
 
92
87
  # Returns information about the state and configuration of an existing NIC.
@@ -95,8 +90,8 @@ module Profitbricks
95
90
  # @option options [String] :id The id of the NIC to locate
96
91
  def find(options = {})
97
92
  raise "Unable to locate the Nic named '#{options[:name]}'" unless options[:id]
98
- response = Profitbricks.request :get_nic, "<nicId>#{options[:id]}</nicId>"
99
- PB::Nic.new(response.to_hash[:get_nic_response][:return])
93
+ response = Profitbricks.request :get_nic, nic_id: options[:id]
94
+ PB::Nic.new(response)
100
95
  end
101
96
  end
102
97
  end
@@ -1,4 +1,8 @@
1
1
  module Profitbricks
2
+ NEED_PREFIX = [:create_nic, :create_load_balancer, :update_storage, :create_storage,
3
+ :update_data_center, :rom_drive, :update_nic, :create_server,
4
+ :update_load_balancer, :connect_storage_to_server, :update_server]
5
+
2
6
  # Configure the Profitbricks API client
3
7
  #
4
8
  # @see Profitbricks::Config
@@ -9,21 +13,21 @@ module Profitbricks
9
13
  Profitbricks::Config.polling_interval = 1
10
14
  yield Profitbricks::Config
11
15
 
12
- Savon.configure do |config|
13
- config.raise_errors = false
14
- config.log = Profitbricks::Config.log
15
- config.pretty_print_xml = true
16
- end
17
16
  HTTPI.log = false
18
17
 
19
- @client = Savon::Client.new do |wsdl, http|
20
- wsdl.endpoint = "https://api.profitbricks.com/1.2"
21
- wsdl.document = "https://api.profitbricks.com/1.2/wsdl"
22
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && !ENV['SSL_CERT_DIR']
23
- puts "Warning: SSL certificate verification has been disabled"
24
- http.auth.ssl.verify_mode = :none
25
- end
26
- http.auth.basic Profitbricks::Config.username, Profitbricks::Config.password
18
+ @client = Savon::Client.new do |globals|
19
+ globals.wsdl "https://api.profitbricks.com/1.2/wsdl"
20
+ globals.convert_request_keys_to :lower_camelcase
21
+ globals.raise_errors true
22
+ globals.log Profitbricks::Config.log
23
+ globals.pretty_print_xml true
24
+
25
+ # Looks like ssl verifycation works with current jruby
26
+ #if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && !ENV['SSL_CERT_DIR']
27
+ # puts "Warning: SSL certificate verification has been disabled"
28
+ # globals.ssl_verify_mode = :none
29
+ #end
30
+ globals.basic_auth [Profitbricks::Config.username, Profitbricks::Config.password]
27
31
  end
28
32
 
29
33
  Profitbricks.client = @client
@@ -38,22 +42,26 @@ module Profitbricks
38
42
  end
39
43
 
40
44
  private
41
- def self.request(method, body=nil)
42
- resp = Profitbricks.client.request method do
43
- soap.body = body if body
44
- end
45
- self.store(method, body, resp.to_xml, resp.to_hash) if Profitbricks::Config.save_responses
46
- if resp.soap_fault?
47
- puts "Error during request '#{method}': #{resp.soap_fault.message}"
45
+ def self.request(method, options={})
46
+ begin
47
+ message = if NEED_PREFIX.include? method
48
+ { arg0: options }
49
+ else
50
+ options
51
+ end
52
+ resp = Profitbricks.client.call(method, message: message)
53
+ self.store(method, message, resp.to_xml, resp.to_hash) if Profitbricks::Config.save_responses
54
+ rescue Savon::SOAPFault => error
55
+ puts "Error during request '#{method}': #{error.to_s}"
48
56
  puts "------------------------------ Request XML -------------------------------"
49
- puts body
57
+ puts message
50
58
  puts "--------------------------------------------------------------------------"
51
- puts "------------------------------ Response XML ------------------------------"
52
- puts resp.to_xml
59
+ puts "------------------------------ Response ----------------------------------"
60
+ puts error.to_hash
53
61
  puts "--------------------------------------------------------------------------"
54
- raise RuntimeError.new("Error during request '#{method}': #{resp.soap_fault.message}")
62
+ raise RuntimeError.new("Error during request '#{method}': #{error.to_s}")
55
63
  end
56
- resp
64
+ (resp.body["#{method}_response".to_sym] || resp.body["#{method}_return".to_sym])[:return]
57
65
  end
58
66
 
59
67
  def self.client=(client)
@@ -83,10 +91,10 @@ module Profitbricks
83
91
  klass = Profitbricks.const_get(klass)
84
92
  else
85
93
  begin
86
- require "profitbricks/#{name.downcase}"
94
+ require "profitbricks/#{klass.downcase}"
87
95
  klass = Profitbricks.const_get(klass)
88
96
  rescue LoadError
89
- raise LoadError.new("Invalid association, could not locate the class '#{name}'")
97
+ raise LoadError.new("Invalid association, could not locate the class '#{klass}'")
90
98
  end
91
99
  end
92
100
  klass
@@ -4,8 +4,8 @@ module Profitbricks
4
4
  #
5
5
  # @return [Boolean] true on success, false otherwise
6
6
  def delete
7
- response = Profitbricks.request :remove_firewall_rules, "<firewallRuleIds>#{self.id}</firewallRuleIds>"
8
- return true if response[:remove_firewall_rules_response][:return]
7
+ response = Profitbricks.request :remove_firewall_rules, firewall_rule_ids: self.id
8
+ return true
9
9
  end
10
10
  end
11
11
  end
@@ -1,19 +1,53 @@
1
1
  module Profitbricks
2
2
  class Server < Profitbricks::Model
3
3
  has_many :nics
4
+ has_many :connected_storages, :class_name => :storage
4
5
 
5
6
  # Deletes the virtual Server.
6
7
  # @return [Boolean] true on success, false otherwise
7
8
  def delete
8
- response = Profitbricks.request :delete_server, "<serverId>#{self.id}</serverId>"
9
- return true if response.to_hash[:delete_server_response][:return]
9
+ Profitbricks.request :delete_server, server_id: self.id
10
+ return true
10
11
  end
11
12
 
12
- # Reboots the virtual Server (POWER CYCLE).
13
+ # Reboots an existing virtual server (SOFT REBOOT).
13
14
  # @return [Boolean] true on success, false otherwise
14
15
  def reboot
15
- response = Profitbricks.request :reboot_server, "<serverId>#{self.id}</serverId>"
16
- return true if response.to_hash[:reboot_server_response][:return]
16
+ @virtual_machine_state = 'NOSTATE'
17
+ Profitbricks.request :reboot_server, server_id: self.id
18
+ return true
19
+ end
20
+
21
+ # Resets an existing virtual server (POWER CYCLE).
22
+ # @return [Boolean] true on success, false otherwise
23
+ def reset
24
+ @virtual_machine_state = 'NOSTATE'
25
+ Profitbricks.request :reset_server, server_id: self.id
26
+ return true
27
+ end
28
+
29
+ # Starts an existing virtual server
30
+ # @return [Boolean] true on success, false otherwise
31
+ def start
32
+ @virtual_machine_state = 'NOSTATE'
33
+ Profitbricks.request :start_server, server_id: self.id
34
+ return true
35
+ end
36
+
37
+ # Stops an existing virtual server (HARD power off)
38
+ # @return [Boolean] true on success, false otherwise
39
+ def power_off
40
+ @virtual_machine_state = 'SHUTOFF'
41
+ Profitbricks.request :power_off_server, server_id: self.id
42
+ return true
43
+ end
44
+
45
+ # Stops an existing virtual server gracefully (SOFT stop)
46
+ # @return [Boolean] true on success, false otherwise
47
+ def shutdown
48
+ @virtual_machine_state = 'SHUTDOWN'
49
+ Profitbricks.request :shutdown_server, server_id: self.id
50
+ return true
17
51
  end
18
52
 
19
53
  # Updates parameters of an existing virtual Server device.
@@ -31,11 +65,11 @@ module Profitbricks
31
65
  raise ArgumentError.new(":ram has to be at least 256MiB and a multiple of it") if options[:ram] and (options[:ram] < 256 or (options[:ram] % 256) > 0)
32
66
  raise ArgumentError.new(":availability_zone has to be either 'AUTO', 'ZONE_1', or 'ZONE_2'") if options[:availability_zone] and !['AUTO', 'ZONE_1', 'ZONE_2'].include? options[:availability_zone]
33
67
  raise ArgumentError.new(":os_type has to be either 'WINDOWS' or 'OTHER'") if options[:os_type] and !['WINDOWS', 'OTHER'].include? options[:os_type]
34
- xml = "<arg0><serverId>#{self.id}</serverId>"
35
- xml += get_xml_and_update_attributes options, [:cores, :ram, :name, :boot_from_storage_id, :boot_from_image_id, :availability_zone, :os_type]
36
- xml += "</arg0>"
37
- response = Profitbricks.request :update_server, xml
38
- return true if response.to_hash[:update_server_response][:return]
68
+ update_attributes_from_hash options
69
+ options[:server_name] = options.delete :name if options[:name]
70
+ options[:server_id] = self.id
71
+ response = Profitbricks.request :update_server, options
72
+ return true
39
73
  end
40
74
 
41
75
  # Checks if the Server is running
@@ -53,13 +87,54 @@ module Profitbricks
53
87
  end
54
88
  end
55
89
 
90
+ # Checks if the Server was successfully provisioned
91
+ #
92
+ # @return [Boolean] true if the Server was provisioned, false otherwise
93
+ def provisioned?
94
+ self.reload
95
+ if @provisioning_state == 'AVAILABLE'
96
+ true
97
+ else
98
+ false
99
+ end
100
+ end
101
+
102
+ # Blocks until the Server is provisioned
103
+ def wait_for_provisioning
104
+ while !self.provisioned?
105
+ sleep Profitbricks::Config.polling_interval
106
+ end
107
+ end
108
+
56
109
  # Creates a Nic for the current Server, automatically sets the :server_id
57
110
  # @see Profitbricks::Nic#create
58
111
  def create_nic(options)
59
112
  Nic.create(options.merge(:server_id => self.id))
60
113
  end
61
114
 
115
+ # Helper method to get a list of all public IP adresses
116
+ #
117
+ # @return [Array <String>] Array of all public IP adresses
118
+ def public_ips
119
+ filter_nics_and_return_ips {|nic| nic.internet_access == true }
120
+ end
121
+
122
+ # Helper method to get a list of all private IP adresses
123
+ #
124
+ # @return [Array <String>] Array of all private IP adresses
125
+ def private_ips
126
+ filter_nics_and_return_ips {|nic| nic.internet_access == false }
127
+ end
128
+
129
+
62
130
  class << self
131
+ # Returns a list of all Servers created by the user.
132
+ #
133
+ # @return [Array <Server>] Array of all available Servers
134
+ def all
135
+ DataCenter.all.collect(&:servers).flatten.compact
136
+ end
137
+
63
138
  # Creates a Virtual Server within an existing data center. Parameters can be specified to set up a
64
139
  # boot device and connect the server to an existing LAN or the Internet.
65
140
  #
@@ -80,12 +155,9 @@ module Profitbricks
80
155
  raise ArgumentError.new(":ram has to be at least 256MiB and a multiple of it") if options[:ram].to_i < 256 or (options[:ram].to_i % 256) > 0
81
156
  raise ArgumentError.new(":availability_zone has to be either 'AUTO', 'ZONE_1', or 'ZONE_2'") if options[:availability_zone] and !['AUTO', 'ZONE_1', 'ZONE_2'].include? options[:availability_zone]
82
157
  raise ArgumentError.new(":os_type has to be either 'WINDOWS' or 'OTHER'") if options[:os_type] and !['WINDOWS', 'OTHER'].include? options[:os_type]
83
- xml = "<arg0>"
84
- xml += get_xml_and_update_attributes options,
85
- [:cores, :ram, :name, :boot_from_storage_id, :boot_from_image_id, :os_type, :internet_access, :lan_id, :data_center_id, :availability_zone]
86
- xml += "</arg0>"
87
- response = Profitbricks.request :create_server, xml
88
- self.find(:id => response.to_hash[:create_server_return][:return][:server_id])
158
+ options[:server_name] = options.delete :name if options[:name]
159
+ response = Profitbricks.request :create_server, options
160
+ self.find(:id => response[:server_id])
89
161
  end
90
162
 
91
163
  # Finds a virtual server
@@ -99,9 +171,15 @@ module Profitbricks
99
171
  # options[:id] = dc.id if dc
100
172
  #end
101
173
  raise "Unable to locate the server named '#{options[:name]}'" unless options[:id]
102
- response = Profitbricks.request :get_server, "<serverId>#{options[:id]}</serverId>"
103
- PB::Server.new(response.to_hash[:get_server_response][:return])
174
+ response = Profitbricks.request :get_server, server_id: options[:id]
175
+ PB::Server.new(response)
104
176
  end
105
177
  end
178
+
179
+ private
180
+ def filter_nics_and_return_ips(&block)
181
+ return [] if self.nics.nil?
182
+ self.nics.select { |nic| yield nic }.collect(&:ips).flatten
183
+ end
106
184
  end
107
185
  end