profitbricks 0.9.9 → 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.
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