profitbricks 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +23 -0
- data/.gemtest +0 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +53 -0
- data/Manifest.txt +106 -0
- data/README.md +70 -0
- data/Rakefile +31 -0
- data/bin/profitbricks +3 -0
- data/examples/create_datacenter.rb +57 -0
- data/lib/profitbricks/config.rb +16 -0
- data/lib/profitbricks/data_center.rb +100 -0
- data/lib/profitbricks/extensions.rb +9 -0
- data/lib/profitbricks/image.rb +47 -0
- data/lib/profitbricks/ip_block.rb +49 -0
- data/lib/profitbricks/model.rb +102 -0
- data/lib/profitbricks/nic.rb +103 -0
- data/lib/profitbricks/profitbricks.rb +86 -0
- data/lib/profitbricks/server.rb +83 -0
- data/lib/profitbricks/storage.rb +84 -0
- data/lib/profitbricks.rb +15 -0
- data/profitbricks.gemspec +34 -0
- data/spec/fixtures/add_public_ip_to_nic/success.json +10 -0
- data/spec/fixtures/add_public_ip_to_nic/success.xml +1 -0
- data/spec/fixtures/clear_data_center/success.json +10 -0
- data/spec/fixtures/clear_data_center/success.xml +1 -0
- data/spec/fixtures/connect_storage_to_server/success.json +10 -0
- data/spec/fixtures/connect_storage_to_server/success.xml +1 -0
- data/spec/fixtures/create_data_center/success.json +10 -0
- data/spec/fixtures/create_data_center/success.xml +1 -0
- data/spec/fixtures/create_nic/success.json +11 -0
- data/spec/fixtures/create_nic/success.xml +1 -0
- data/spec/fixtures/create_server/minimal.json +11 -0
- data/spec/fixtures/create_server/minimal.xml +1 -0
- data/spec/fixtures/create_storage/success.json +11 -0
- data/spec/fixtures/create_storage/success.xml +1 -0
- data/spec/fixtures/delete_data_center/success.json +8 -0
- data/spec/fixtures/delete_data_center/success.xml +1 -0
- data/spec/fixtures/delete_nic/success.json +10 -0
- data/spec/fixtures/delete_nic/success.xml +1 -0
- data/spec/fixtures/delete_server/success.json +10 -0
- data/spec/fixtures/delete_server/success.xml +1 -0
- data/spec/fixtures/delete_storage/failture.json +16 -0
- data/spec/fixtures/delete_storage/failture.xml +1 -0
- data/spec/fixtures/delete_storage/success.json +10 -0
- data/spec/fixtures/delete_storage/success.xml +1 -0
- data/spec/fixtures/disconnect_storage_from_server/failture.json +16 -0
- data/spec/fixtures/disconnect_storage_from_server/failture.xml +1 -0
- data/spec/fixtures/disconnect_storage_from_server/success.json +10 -0
- data/spec/fixtures/disconnect_storage_from_server/success.xml +1 -0
- data/spec/fixtures/get_all_data_centers/empty.json +1 -0
- data/spec/fixtures/get_all_data_centers/empty.xml +1 -0
- data/spec/fixtures/get_all_data_centers/test_datacenter.json +10 -0
- data/spec/fixtures/get_all_data_centers/test_datacenter.xml +1 -0
- data/spec/fixtures/get_all_images/success.json +100 -0
- data/spec/fixtures/get_all_images/success.xml +1 -0
- data/spec/fixtures/get_all_public_ip_blocks/success.json +16 -0
- data/spec/fixtures/get_all_public_ip_blocks/success.xml +1 -0
- data/spec/fixtures/get_data_center/create.json +147 -0
- data/spec/fixtures/get_data_center/create.xml +1 -0
- data/spec/fixtures/get_data_center/two_servers_with_storage.json +147 -0
- data/spec/fixtures/get_data_center/two_servers_with_storage.xml +1 -0
- data/spec/fixtures/get_data_center_state/in_process.json +1 -0
- data/spec/fixtures/get_data_center_state/in_process.xml +1 -0
- data/spec/fixtures/get_data_center_state/success.json +1 -0
- data/spec/fixtures/get_data_center_state/success.xml +1 -0
- data/spec/fixtures/get_image/success.json +15 -0
- data/spec/fixtures/get_image/success.xml +1 -0
- data/spec/fixtures/get_nic/success.json +16 -0
- data/spec/fixtures/get_nic/success.xml +1 -0
- data/spec/fixtures/get_nic/two_ips.json +19 -0
- data/spec/fixtures/get_nic/two_ips.xml +1 -0
- data/spec/fixtures/get_server/after_create.json +17 -0
- data/spec/fixtures/get_server/after_create.xml +1 -0
- data/spec/fixtures/get_server/connected_storage.json +26 -0
- data/spec/fixtures/get_server/connected_storage.xml +1 -0
- data/spec/fixtures/get_storage/success.json +14 -0
- data/spec/fixtures/get_storage/success.xml +1 -0
- data/spec/fixtures/reboot_server/success.json +1 -0
- data/spec/fixtures/reboot_server/success.xml +1 -0
- data/spec/fixtures/release_public_ip_block/success.json +1 -0
- data/spec/fixtures/release_public_ip_block/success.xml +1 -0
- data/spec/fixtures/remove_public_ip_from_nic/success.json +10 -0
- data/spec/fixtures/remove_public_ip_from_nic/success.xml +1 -0
- data/spec/fixtures/reserve_public_ip_block/success.json +13 -0
- data/spec/fixtures/reserve_public_ip_block/success.xml +1 -0
- data/spec/fixtures/set_image_os_type/success.json +1 -0
- data/spec/fixtures/set_image_os_type/success.xml +1 -0
- data/spec/fixtures/set_internet_access/success.json +10 -0
- data/spec/fixtures/set_internet_access/success.xml +1 -0
- data/spec/fixtures/update_data_center/success.json +10 -0
- data/spec/fixtures/update_data_center/success.xml +1 -0
- data/spec/fixtures/update_nic/success.json +10 -0
- data/spec/fixtures/update_nic/success.xml +1 -0
- data/spec/fixtures/update_server/basic.json +10 -0
- data/spec/fixtures/update_server/basic.xml +1 -0
- data/spec/fixtures/update_storage/success.json +10 -0
- data/spec/fixtures/update_storage/success.xml +1 -0
- data/spec/profitbricks/data_center_spec.rb +95 -0
- data/spec/profitbricks/image_spec.rb +23 -0
- data/spec/profitbricks/ip_block_spec.rb +26 -0
- data/spec/profitbricks/model_spec.rb +68 -0
- data/spec/profitbricks/nic_spec.rb +55 -0
- data/spec/profitbricks/server_spec.rb +41 -0
- data/spec/profitbricks/storage_spec.rb +47 -0
- data/spec/spec_helper.rb +45 -0
- metadata +193 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
module Profitbricks
|
2
|
+
class Image < Profitbricks::Model
|
3
|
+
|
4
|
+
# Sets the OS Type of an individual HDD and/or CD-ROM/DVD image that has been uploaded on the ProfitBricks FTP server.
|
5
|
+
#
|
6
|
+
# @param [String] OS Type of the target HDD or CD-ROM/DVD image (WINDOWS, OTHER)
|
7
|
+
# @return [Image] Updated Image Object
|
8
|
+
def set_os_type(type)
|
9
|
+
raise ArgumentError.new(":os_type has to be either 'WINDOWS' or 'OTHER'") if !['WINDOWS', 'OTHER'].include? type
|
10
|
+
response = Profitbricks.request :set_image_os_type, "<imageId>#{self.id}</imageId><osType>#{type}</osType>"
|
11
|
+
@os_type = type
|
12
|
+
self
|
13
|
+
end
|
14
|
+
alias_method :os_type=, :set_os_type
|
15
|
+
|
16
|
+
class << self
|
17
|
+
# Returns information about a HDD or CD-ROM/DVD (ISO) image.
|
18
|
+
#
|
19
|
+
# @param [Hash] options either name or id of the Image
|
20
|
+
# @option options [String] :name The name of the Image
|
21
|
+
# @option options [String] :id The id of the Image
|
22
|
+
# @return [Image] The found Image Object
|
23
|
+
def find(options = {})
|
24
|
+
image = nil
|
25
|
+
if options[:name]
|
26
|
+
image = PB::Image.all().select { |d| d.name == options[:name] }.first
|
27
|
+
options[:id] = image.id if image
|
28
|
+
end
|
29
|
+
raise "Unable to locate the image named '#{options[:name]}'" unless options[:id]
|
30
|
+
image
|
31
|
+
# This does not work for public images
|
32
|
+
#response = Profitbricks.request :get_image, "<imageId>#{options[:id]}</imageId>"
|
33
|
+
#PB::Image.new(response.to_hash[:get_image_response][:return])
|
34
|
+
end
|
35
|
+
|
36
|
+
# Outputs a list of all HDD and/or CD-ROM/DVD images existing on or uploaded to the Profit-Bricks FTP server.
|
37
|
+
#
|
38
|
+
# @return [Array<Image>] List of all available Images
|
39
|
+
def all
|
40
|
+
resp = Profitbricks.request :get_all_images
|
41
|
+
resp.to_hash[:get_all_images_response][:return].collect do |dc|
|
42
|
+
PB::Image.new(dc)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Profitbricks
|
2
|
+
class IpBlock < Profitbricks::Model
|
3
|
+
attr_reader :ips
|
4
|
+
|
5
|
+
def initialize(hash)
|
6
|
+
if hash[:public_ips]
|
7
|
+
@ips = [hash.delete(:public_ips)].flatten.compact.collect { |ip| ip[:ip] }
|
8
|
+
end
|
9
|
+
super(hash)
|
10
|
+
@ips = [@ips] if @ips.class != Array
|
11
|
+
end
|
12
|
+
|
13
|
+
def id
|
14
|
+
@block_id
|
15
|
+
end
|
16
|
+
|
17
|
+
# Releases an existing block of reserved public IPs.
|
18
|
+
#
|
19
|
+
# @return [Boolean] true on success, false otherwise
|
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]
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
# Returns a list of all public IP blocks reserved by the user, including the reserved IPs and connected NICs.
|
27
|
+
#
|
28
|
+
# @return [Array<IpBlock>] List of all IpBlocks
|
29
|
+
def all
|
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|
|
33
|
+
PB::IpBlock.new(block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Reserves a specific amount of public IPs which can be manually assigned to a NIC by the user.
|
38
|
+
#
|
39
|
+
# @param [Fixnum] Block size / amount of IPs to reserve
|
40
|
+
# @return [IpBlock] The reserved IpBlock
|
41
|
+
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])
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Profitbricks
|
2
|
+
class Model
|
3
|
+
@@associations = {}
|
4
|
+
|
5
|
+
def initialize(hash = {})
|
6
|
+
klass = self.class.to_s.underscore
|
7
|
+
hash.keys.each do |k|
|
8
|
+
attribute = k.to_s.sub("#{klass}_", '').to_sym
|
9
|
+
if @@associations[attribute]
|
10
|
+
initialize_association(attribute, @@associations[attribute], hash[k])
|
11
|
+
else
|
12
|
+
initialize_getter(attribute, type_cast(hash[k]))
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def reload
|
19
|
+
updated = self.class.find(:id => self.id)
|
20
|
+
update_attributes(updated)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.has_many(model)
|
24
|
+
klass = Profitbricks.get_class model[0..-2].camelcase
|
25
|
+
@@associations[model] = {:type => :collection, :class => klass}
|
26
|
+
define_method(model) { instance_variable_get("@#{model}") }
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.belongs_to(model)
|
30
|
+
klass = Profitbricks.get_class model.to_s.camelcase
|
31
|
+
@@associations[model] = {:type => :belongs_to, :class => klass}
|
32
|
+
define_method(model) { instance_variable_get("@#{model}") }
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_xml_and_update_attributes(hash, attributes=nil)
|
36
|
+
attributes = hash.keys if attributes.nil?
|
37
|
+
attributes.each do |a|
|
38
|
+
initialize_getter(a, hash[a]) if hash[a]
|
39
|
+
end
|
40
|
+
hash, attributes = self.class.expand_attributes(hash, attributes, self.class)
|
41
|
+
xml = self.class.build_xml(hash, attributes)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.get_xml_and_update_attributes(hash, attributes=[])
|
45
|
+
hash, attributes = expand_attributes(hash, attributes, name())
|
46
|
+
self.build_xml(hash, attributes)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def update_attributes(updated)
|
51
|
+
self.instance_variables.each do |var|
|
52
|
+
self.instance_variable_set(var, updated.instance_variable_get(var))
|
53
|
+
end
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
def type_cast(value)
|
58
|
+
return value.to_i if value =~ /^\d+$/
|
59
|
+
value
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.build_xml(hash ,attributes)
|
63
|
+
attributes.collect do |a|
|
64
|
+
"<#{a.to_s.lower_camelcase}>#{hash[a]}</#{a.to_s.lower_camelcase}>" if hash[a]
|
65
|
+
end.join('')
|
66
|
+
end
|
67
|
+
|
68
|
+
def initialize_getter name, value=nil
|
69
|
+
self.class.send :define_method, name do
|
70
|
+
instance_variable_get("@#{name}")
|
71
|
+
end
|
72
|
+
self.instance_variable_set("@#{name}", value) if value
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize_association name, association, value
|
76
|
+
if association[:type] == :collection
|
77
|
+
initialize_collection_association name, association, value
|
78
|
+
elsif association[:type] == :belongs_to
|
79
|
+
initialize_belongs_to_association name, association, value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def initialize_collection_association name, association, value
|
84
|
+
self.instance_variable_set("@#{name}", [])
|
85
|
+
[value].flatten.compact.each do |object|
|
86
|
+
instance_variable_get("@#{name}").send(:push, association[:class].send(:new, object))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def initialize_belongs_to_association name, association, value
|
91
|
+
self.instance_variable_set("@#{name}", association[:class].send(:new, value))
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.expand_attributes(hash, attributes, klass=nil)
|
95
|
+
name = hash.delete(:name)
|
96
|
+
hash["#{klass.to_s.underscore}_name"] = name
|
97
|
+
attributes.delete(:name)
|
98
|
+
attributes.push "#{klass.to_s.underscore}_name"
|
99
|
+
return hash, attributes
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Profitbricks
|
2
|
+
class Ip < Profitbricks::Model; end;
|
3
|
+
|
4
|
+
class Nic < Profitbricks::Model
|
5
|
+
|
6
|
+
def initialize(hash)
|
7
|
+
super(hash)
|
8
|
+
@ips = [@ips] if @ips.class != Array
|
9
|
+
end
|
10
|
+
|
11
|
+
# Connects or disconnects an existing NIC to a public LAN to get internet access.
|
12
|
+
#
|
13
|
+
# @param [Boolean] Internet access (trUe/false)
|
14
|
+
# @return [Boolean] true on success, false otherwise
|
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]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Changes the settings of an existing NIC.
|
22
|
+
#
|
23
|
+
# @param [Hash] options parameters to update
|
24
|
+
# @option options [Fixnum] :server_id Identifier of the target virtual server (required)
|
25
|
+
# @option options [Fixnum] :lan_id Identifier of the target LAN > 0 that is to be connected to the specified virtual server. If no LAN exists for such ID, a new LAN with the given ID will be created.
|
26
|
+
# @option options [String] :ip Public/private IP address.
|
27
|
+
# @option options [String] :name Names the NIC
|
28
|
+
# @return [Boolean] true on success, false otherwise
|
29
|
+
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]
|
36
|
+
end
|
37
|
+
|
38
|
+
# 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
|
+
#
|
40
|
+
# @param [String] Reserved IP
|
41
|
+
def add_ip(ip)
|
42
|
+
response = Profitbricks.request :add_public_ip_to_nic, "<nicId>#{self.id}</nicId><ip>#{ip}</ip>"
|
43
|
+
@ips.push ip
|
44
|
+
return true if response.to_hash[:add_public_ip_to_nic_response][:return]
|
45
|
+
end
|
46
|
+
|
47
|
+
# 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
|
+
#
|
49
|
+
# @param [String] Reserved IP
|
50
|
+
def remove_ip(ip)
|
51
|
+
response = Profitbricks.request :remove_public_ip_from_nic, "<nicId>#{self.id}</nicId><ip>#{ip}</ip>"
|
52
|
+
@ips.delete ip
|
53
|
+
return true if response.to_hash[:remove_public_ip_from_nic_response][:return]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Deletes an existing NIC.
|
57
|
+
#
|
58
|
+
# @return [Boolean] true on success, false otherwise
|
59
|
+
def delete
|
60
|
+
response = Profitbricks.request :delete_nic, "<nicId>#{self.id}</nicId>"
|
61
|
+
return true if response.to_hash[:delete_nic_response][:return]
|
62
|
+
end
|
63
|
+
|
64
|
+
def ip
|
65
|
+
if @ips.length <= 1
|
66
|
+
@ips.first
|
67
|
+
else
|
68
|
+
raise ArgumentError.new("This Nic has more then one IP assigned")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class << self
|
73
|
+
# Creates a NIC on an existing virtual server.
|
74
|
+
#
|
75
|
+
# The user can specify and assign local IPs manually to a NIC, which is connected to a Private LAN. Valid IP addresses for Private LANs are 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16.
|
76
|
+
# In a Public LAN, a random DHCP IP address is assigned to each connected NIC by default. This IP Address is automatically generated and will change eventually, e.g. during a server reboot or while disconnecting and reconnecting a LAN to the internet.
|
77
|
+
#
|
78
|
+
# @param [Hash] options parameters for the new NIC
|
79
|
+
# @option options [Fixnum] :server_id Identifier of the target virtual server (required)
|
80
|
+
# @option options [Fixnum] :lan_id Identifier of the target LAN > 0 that is to be connected to the specified virtual server. If no LAN exists for such ID, a new LAN with the given ID will be created. (required)
|
81
|
+
# @option options [String] :ip Public/private IP address.
|
82
|
+
# @option options [String] :name Names the NIC
|
83
|
+
# @return [Nic] The created NIC
|
84
|
+
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])
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns information about the state and configuration of an existing NIC.
|
93
|
+
#
|
94
|
+
# @param [Hash] options currently just :id is supported
|
95
|
+
# @option options [String] :id The id of the NIC to locate
|
96
|
+
def find(options = {})
|
97
|
+
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])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Profitbricks
|
2
|
+
# Configure the Profitbricks API client
|
3
|
+
#
|
4
|
+
# @see Profitbricks::Config
|
5
|
+
def self.configure(&block)
|
6
|
+
Profitbricks::Config.save_responses = false
|
7
|
+
Profitbricks::Config.log = false
|
8
|
+
Profitbricks::Config.global_classes = true
|
9
|
+
yield Profitbricks::Config
|
10
|
+
|
11
|
+
Savon.configure do |config|
|
12
|
+
config.raise_errors = false
|
13
|
+
config.log = Profitbricks::Config.log
|
14
|
+
end
|
15
|
+
HTTPI.log = false
|
16
|
+
|
17
|
+
@client = Savon::Client.new do |wsdl, http|
|
18
|
+
wsdl.endpoint = "https://api.profitbricks.com/1.1"
|
19
|
+
wsdl.document = "https://api.profitbricks.com/1.1/wsdl"
|
20
|
+
http.auth.basic Profitbricks::Config.username, Profitbricks::Config.password
|
21
|
+
end
|
22
|
+
|
23
|
+
Profitbricks.client = @client
|
24
|
+
if Profitbricks::Config.global_classes
|
25
|
+
Profitbricks.constants.select {|c| Class === Profitbricks.const_get(c)}.each do |klass|
|
26
|
+
next if klass == :Config
|
27
|
+
unless Kernel.const_defined?(klass)
|
28
|
+
Kernel.const_set(klass, Profitbricks.const_get(klass))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def self.request(method, body=nil)
|
36
|
+
resp = Profitbricks.client.request method do
|
37
|
+
soap.body = body if body
|
38
|
+
end
|
39
|
+
self.store(method, body, resp.to_xml, resp.to_hash) if Profitbricks::Config.save_responses
|
40
|
+
if resp.soap_fault?
|
41
|
+
puts "Error during request '#{method}': #{resp.soap_fault.message}"
|
42
|
+
puts "------------------------------ Request XML -------------------------------"
|
43
|
+
puts body
|
44
|
+
puts "--------------------------------------------------------------------------"
|
45
|
+
puts "------------------------------ Response XML ------------------------------"
|
46
|
+
puts resp.to_xml
|
47
|
+
puts "--------------------------------------------------------------------------"
|
48
|
+
raise RuntimeError.new("Error during request '#{method}': #{resp.soap_fault.message}")
|
49
|
+
end
|
50
|
+
resp
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.client=(client)
|
54
|
+
@client = client
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.client
|
58
|
+
@client
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.store(method, body, xml, json)
|
62
|
+
require 'digest/sha1'
|
63
|
+
hash = Digest::SHA1.hexdigest xml
|
64
|
+
|
65
|
+
unless Dir.exists?(File.expand_path("../../../spec/fixtures/#{method}", __FILE__))
|
66
|
+
Dir.mkdir(File.expand_path("../../../spec/fixtures/#{method}", __FILE__))
|
67
|
+
end
|
68
|
+
File.open(File.expand_path("../../../spec/fixtures/#{method}/#{hash}.xml", __FILE__), 'w').write(xml)
|
69
|
+
File.open(File.expand_path("../../../spec/fixtures/#{method}/#{hash}.json", __FILE__), 'w').write(JSON.dump(json))
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.get_class name
|
73
|
+
klass = name
|
74
|
+
if Profitbricks.const_defined?(klass)
|
75
|
+
klass = Profitbricks.const_get(klass)
|
76
|
+
else
|
77
|
+
begin
|
78
|
+
require "profitbricks/#{name.downcase}"
|
79
|
+
klass = Profitbricks.const_get(klass)
|
80
|
+
rescue LoadError
|
81
|
+
raise LoadError.new("Invalid association, could not locate the class '#{name}'")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
klass
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Profitbricks
|
2
|
+
class Server < Profitbricks::Model
|
3
|
+
has_many :nics
|
4
|
+
|
5
|
+
# Deletes the virtual Server.
|
6
|
+
# @return [Boolean] true on success, false otherwise
|
7
|
+
def delete
|
8
|
+
response = Profitbricks.request :delete_server, "<serverId>#{self.id}</serverId>"
|
9
|
+
return true if response.to_hash[:delete_server_response][:return]
|
10
|
+
end
|
11
|
+
|
12
|
+
# Reboots the virtual Server (POWER CYCLE).
|
13
|
+
# @return [Boolean] true on success, false otherwise
|
14
|
+
def reboot
|
15
|
+
response = Profitbricks.request :reboot_server, "<serverId>#{self.id}</serverId>"
|
16
|
+
return true if response.to_hash[:reboot_server_response][:return]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Updates parameters of an existing virtual Server device.
|
20
|
+
# @param [Hash] options parameters for the new server
|
21
|
+
# @option options [Fixnum] :cores Number of cores to be assigned to the specified server (required)
|
22
|
+
# @option options [Fixnum] :ram Number of RAM memory (in MiB) to be assigned to the server. Must be at least 256 and a multiple of it. (required)
|
23
|
+
# @option options [String] :name Name of the server to be created
|
24
|
+
# @option options [String] :boot_from_image_id Defines an existing CD-ROM/DVD image ID to be set as boot device of the server. A virtual CD-ROM/DVD drive with the mounted image will be connected to the server.
|
25
|
+
# @option options [String] :boot_from_storage_id Defines an existing storage device ID to be set as boot device of the server. The storage will be connected to the server implicitly.
|
26
|
+
# @option options [String] :os_type Sets the OS type of the server. (WINDOWS, OTHER) If left empty, the server will inherit the OS Type of its selected boot image / storage.
|
27
|
+
# @return [Boolean] true on success, false otherwise
|
28
|
+
def update(options = {})
|
29
|
+
return false if options.empty?
|
30
|
+
raise ArgumentError.new(":ram and :cores are mandatory options.") unless options[:ram] or options[:core]
|
31
|
+
raise ArgumentError.new(":ram has to be at least 256MiB and a multiple of it") if options[:ram] < 256 or (options[:ram] % 256) > 0
|
32
|
+
raise ArgumentError.new(":os_type has to be either 'WINDOWS' or 'OTHER'") if options[:os_type] and !['WINDOWS', 'OTHER'].include? options[:os_type]
|
33
|
+
xml = "<arg0><serverId>#{self.id}</serverId>"
|
34
|
+
xml += get_xml_and_update_attributes options, [:cores, :ram, :name, :boot_from_storage_id, :boot_from_image_id, :os_type]
|
35
|
+
xml += "</arg0>"
|
36
|
+
response = Profitbricks.request :update_server, xml
|
37
|
+
return true if response.to_hash[:update_server_response][:return]
|
38
|
+
end
|
39
|
+
|
40
|
+
class << self
|
41
|
+
# Creates a Virtual Server within an existing data center. Parameters can be specified to set up a
|
42
|
+
# boot device and connect the server to an existing LAN or the Internet.
|
43
|
+
#
|
44
|
+
# @param [Hash] options parameters for the new server
|
45
|
+
# @option options [Fixnum] :cores Number of cores to be assigned to the specified server (required)
|
46
|
+
# @option options [Fixnum] :ram Number of RAM memory (in MiB) to be assigned to the server. Must be at least 256 and a multiple of it. (required)
|
47
|
+
# @option options [String] :name Name of the server to be created
|
48
|
+
# @option options [String] :data_center_id Defines the data center wherein the server is to be created. If left empty, the server will be created in a new data center.
|
49
|
+
# @option options [String] :boot_from_image_id Defines an existing CD-ROM/DVD image ID to be set as boot device of the server. A virtual CD-ROM/DVD drive with the mounted image will be connected to the server.
|
50
|
+
# @option options [String] :boot_from_storage_id Defines an existing storage device ID to be set as boot device of the server. The storage will be connected to the server implicitly.
|
51
|
+
# @option options [Fixnum] :lan_id Connects the server to the specified LAN ID > 0. If the respective LAN does not exist, it is going to be created.
|
52
|
+
# @option options [Boolean] :internet_access Set to true to connect the server to the internet via the specified LAN ID. If the LAN is not specified, it is going to be created in the next available LAN ID, starting with LAN ID 1
|
53
|
+
# @option options [String] :os_type Sets the OS type of the server. (WINDOWS, OTHER) If left empty, the server will inherit the OS Type of its selected boot image / storage.
|
54
|
+
# @return [Server] The created virtual server
|
55
|
+
def create(options = {})
|
56
|
+
raise ArgumentError.new("You must provide :cores and :ram") if options[:ram].nil? and options[:cores].nil?
|
57
|
+
raise ArgumentError.new(":ram has to be at least 256MiB and a multiple of it") if options[:ram] < 256 or (options[:ram] % 256) > 0
|
58
|
+
raise ArgumentError.new(":os_type has to be either 'WINDOWS' or 'OTHER'") if options[:os_type] and !['WINDOWS', 'OTHER'].include? options[:os_type]
|
59
|
+
xml = "<arg0>"
|
60
|
+
xml += get_xml_and_update_attributes options,
|
61
|
+
[:cores, :ram, :name, :boot_from_storage_id, :boot_from_image_id, :os_type, :internet_access, :lan_id]
|
62
|
+
xml += "</arg0>"
|
63
|
+
response = Profitbricks.request :create_server, xml
|
64
|
+
self.find(:id => response.to_hash[:create_server_return][:return][:server_id])
|
65
|
+
end
|
66
|
+
|
67
|
+
# Finds a virtual server
|
68
|
+
#
|
69
|
+
# @param [Hash] options currently just :id is supported
|
70
|
+
# @option options [String] :id The id of the server to locate
|
71
|
+
def find(options = {})
|
72
|
+
# FIXME
|
73
|
+
#if options[:name]
|
74
|
+
# dc = PB::Server.all().select { |d| d.name == options[:name] }.first
|
75
|
+
# options[:id] = dc.id if dc
|
76
|
+
#end
|
77
|
+
raise "Unable to locate the server named '#{options[:name]}'" unless options[:id]
|
78
|
+
response = Profitbricks.request :get_server, "<serverId>#{options[:id]}</serverId>"
|
79
|
+
PB::Server.new(response.to_hash[:get_server_response][:return])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|