Skip to content

Commit f594af1

Browse files
committed
Added a new class to perform Virtual Server Upgrades. By splitting this out into a separate class we get two benefits:
1 You can upgrade more than one attribute of the server at a time so you don't have to wait on separate transactions for each upgrade 2 It gets information about product ordering out of the Virtual Server class and into its own class.
1 parent 8ccc787 commit f594af1

5 files changed

Lines changed: 277 additions & 100 deletions

File tree

lib/softlayer/VirtualServer.rb

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
# For licensing information see the LICENSE.md file in the project root.
55
#++
66

7-
require 'time'
8-
97
module SoftLayer
108
##
119
# Instance of this class represent servers that are virtual machines in the
@@ -74,49 +72,6 @@ def cancel!
7472
self.service.deleteObject()
7573
end
7674

77-
##
78-
# This routine submits an order to upgrade the cpu count of the virtual server.
79-
# The order may result in additional charges being applied to SoftLayer account
80-
#
81-
# This routine can also "downgrade" servers (set their cpu count lower)
82-
#
83-
# The routine returns true if the order is placed and false if it is not
84-
#
85-
def upgrade_cores!(num_cores)
86-
upgrade_item_price = _item_price_in_category("guest_core", num_cores)
87-
_order_upgrade_item!(upgrade_item_price) if upgrade_item_price
88-
nil != upgrade_item_price
89-
end
90-
91-
##
92-
# This routine submits an order to change the RAM available to the virtual server.
93-
# Pass in the desired amount of RAM for the server in Gigabytes
94-
#
95-
# The order may result in additional charges being applied to SoftLayer account
96-
#
97-
# The routine returns true if the order is placed and false if it is not
98-
#
99-
def upgrade_RAM!(ram_in_GB)
100-
upgrade_item_price = _item_price_in_category("ram", ram_in_GB)
101-
_order_upgrade_item!(upgrade_item_price) if upgrade_item_price
102-
nil != upgrade_item_price
103-
end
104-
105-
##
106-
# This routine submits an order to change the maximum nic speed of the server
107-
# Pass in the desired speed in Megabits per second (typically 10, 100, or 1000)
108-
# (since you may choose a slower speed this routine can also be used for "downgrades")
109-
#
110-
# The order may result in additional charges being applied to SoftLayer account
111-
#
112-
# The routine returns true if the order is placed and false if it is not
113-
#
114-
def upgrade_max_port_speed!(network_speed_in_Mbps)
115-
upgrade_item_price = _item_price_in_category("port_speed", network_speed_in_Mbps)
116-
_order_upgrade_item!(upgrade_item_price) if upgrade_item_price
117-
nil != upgrade_item_price
118-
end
119-
12075
##
12176
# Capture a disk image of this virtual server for use with other servers.
12277
#
@@ -354,32 +309,5 @@ def self.default_object_mask
354309
def service
355310
return softlayer_client["Virtual_Guest"].object_with_id(self.id)
356311
end
357-
358-
private
359-
360-
##
361-
# Searches through the upgrade items pricess known to this server for the one that is in a particular category
362-
# and whose capacity matches the value given. Returns the item_price or nil
363-
#
364-
def _item_price_in_category(which_category, capacity)
365-
item_prices_in_category = self.upgrade_options.select { |item_price| item_price["categories"].find { |category| category["categoryCode"] == which_category } }
366-
item_prices_in_category.find { |ram_item| ram_item["item"]["capacity"].to_i == capacity}
367-
end
368-
369-
##
370-
# Constructs an upgrade order to order the given item price.
371-
# The order is built to execute immediately
372-
#
373-
def _order_upgrade_item!(upgrade_item_price)
374-
# put together an order
375-
upgrade_order = {
376-
'complexType' => 'SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade',
377-
'virtualGuests' => [{'id' => self.id }],
378-
'properties' => [{'name' => 'MAINTENANCE_WINDOW', 'value' => Time.now.iso8601}],
379-
'prices' => [ upgrade_item_price ]
380-
}
381-
382-
self.softlayer_client["Product_Order"].placeOrder(upgrade_order)
383-
end
384312
end #class VirtualServer
385313
end
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#--
2+
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
3+
#
4+
# For licensing information see the LICENSE.md file in the project root.
5+
#++
6+
7+
8+
module SoftLayer
9+
# This class is used to order changes to a virtual server. Although
10+
# the class is named "upgrade" this class can also be used for "downgrades"
11+
# (i.e. changing attributes to a smaller, or slower, value)
12+
#
13+
# The class can also be used to discover what upgrades are available
14+
# for a given virtual server.
15+
#
16+
class VirtualServerUpgradeOrder
17+
# The virtual server that this order is designed to upgrade.
18+
attr_reader :virtual_server
19+
20+
# The number of cores the server should have after the upgrade.
21+
# If this is nil, the the number of cores will not change
22+
attr_accessor :cores
23+
24+
# The amount of RAM (in GB) that the server should have after the upgrade
25+
# If this is nil, the ram will not change
26+
attr_accessor :ram
27+
28+
# The port speed (in Mega bits per second) that the server should have
29+
# after the upgrade. This is typically a value like 100, or 1000
30+
# If this is nil, the port speeds will not change
31+
attr_accessor :max_port_speed
32+
33+
# The date and time when you would like the upgrade to be processed.
34+
# This should simply be a Time object. If nil then the upgrade
35+
# will be performed immediately
36+
attr_accessor :upgrade_at
37+
38+
def initialize(virtual_server)
39+
raise "A virtual server must be provided at the time a virtual server order is created" if !virtual_server || !virtual_server.kind_of?(SoftLayer::VirtualServer)
40+
@virtual_server = virtual_server
41+
end
42+
43+
def verify()
44+
if has_order_items?
45+
order_object = self.order_object
46+
order_object = yield order_object if block_given?
47+
48+
@virtual_server.softlayer_client["Product_Order"].verifyOrder(order_object)
49+
end
50+
end
51+
52+
def place_order!()
53+
if has_order_items?
54+
order_object = self.order_object
55+
order_object = yield order_object if block_given?
56+
57+
@virtual_server.softlayer_client["Product_Order"].placeOrder(order_object)
58+
end
59+
end
60+
61+
##
62+
# Return a list of values that are valid for the :cores attribute
63+
def core_options()
64+
self._item_prices_in_category("guest_core").map { |item_price| item_price["item"]["capacity"].to_i}.sort.uniq
65+
end
66+
67+
##
68+
# Return a list of values that are valid for the :memory attribute
69+
def memory_options()
70+
self._item_prices_in_category("ram").map { |item_price| item_price["item"]["capacity"].to_i}.sort.uniq
71+
end
72+
73+
##
74+
# Returns a list of valid values for max_port_speed
75+
def max_port_speed_options(client = nil)
76+
self._item_prices_in_category("port_speed").map { |item_price| item_price["item"]["capacity"].to_i}.sort.uniq
77+
end
78+
79+
private
80+
81+
def has_order_items?
82+
@cores != nil || @ram != nil || @max_port_speed != nil
83+
end
84+
85+
def _item_prices_in_category(which_category)
86+
@virtual_server.upgrade_options.select { |item_price| item_price["categories"].find { |category| category["categoryCode"] == which_category } }
87+
end
88+
89+
##
90+
# Searches through the upgrade items pricess known to this server for the one that is in a particular category
91+
# and whose capacity matches the value given. Returns the item_price or nil
92+
#
93+
def _item_price_with_capacity(which_category, capacity)
94+
self._item_prices_in_category(which_category).find { |item_price| item_price["item"]["capacity"].to_i == capacity}
95+
end
96+
97+
def order_object
98+
prices = []
99+
100+
cores_price_item = @cores ? _item_price_with_capacity("guest_core", @cores) : nil
101+
ram_price_item = @ram ? _item_price_with_capacity("ram", @ram) : nil
102+
max_port_speed_price_item = @max_port_speed ? _item_price_with_capacity("port_speed", @max_port_speed) : nil
103+
104+
prices << { "id" => cores_price_item["id"] } if cores_price_item
105+
prices << { "id" => ram_price_item["id"] } if ram_price_item
106+
prices << { "id" => max_port_speed_price_item["id"] } if max_port_speed_price_item
107+
108+
# put together an order
109+
upgrade_order = {
110+
'complexType' => 'SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade',
111+
'virtualGuests' => [{'id' => @virtual_server.id }],
112+
'properties' => [{'name' => 'MAINTENANCE_WINDOW', 'value' => @upgrade_at ? @upgrade_at.iso8601 : Time.now.iso8601}],
113+
'prices' => prices
114+
}
115+
end
116+
end # VirtualServerUpgradeOrder
117+
end # SoftLayer Module

lib/softlayer_api.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,32 @@
44
# For licensing information see the LICENSE.md file in the project root.
55
#++
66

7+
# requirements from the core libraries
8+
require 'time'
79

10+
# Requirements for the Foundation Layer
811
require 'softlayer/base'
912
require 'softlayer/object_mask_helpers'
1013
require 'softlayer/APIParameterFilter'
1114
require 'softlayer/ObjectFilter'
1215
require 'softlayer/ObjectMaskParser'
1316
require 'softlayer/Config'
14-
1517
require 'softlayer/Client'
1618
require 'softlayer/Service'
1719

18-
# model classes
20+
# Requirements for the Model Layer
1921
require 'softlayer/ModelBase'
2022
require 'softlayer/Datacenter'
2123
require 'softlayer/DynamicAttribute'
2224
require 'softlayer/Account'
23-
require 'softlayer/Ticket'
2425
require 'softlayer/Server'
2526
require 'softlayer/BareMetalServer'
2627
require 'softlayer/BareMetalServerOrder'
2728
require 'softlayer/BareMetalServerOrder_Package'
2829
require 'softlayer/ImageTemplate'
2930
require 'softlayer/ProductPackage'
3031
require 'softlayer/ProductItemCategory'
32+
require 'softlayer/Ticket'
3133
require 'softlayer/VirtualServer'
3234
require 'softlayer/VirtualServerOrder'
35+
require 'softlayer/VirtualServerUpgradeOrder'

0 commit comments

Comments
 (0)