I could find some APIs to cancel a single item, such as a virtual guest or a storage. However, it is complex to cancel a virtual guest along with all other billing items, I could not find a API that could get all billing items of a virtual guest.
For example, there exists a virtual guest with disk2, disk3, when I cancel this virtual guest, I do not want to reserve the disks anymore. How could I achieve that?
Update:
The virtual guest has three storages (portal->Device details->Storage):
Block Device (Disk)(25GB)(System) --> first
Block Device (Disk)(2GB)(Swap) --> swap
Block Device (Disk)(10GB)(System) --> second
And I tried to upgrade the virtual guest's storage by API, so that when virtual guest is canceled, the storages could be remove along with it automatically.
I upgraded like this:
none_first_disk_list = {
'local':{
25:'GUEST_DISK_25_GB_LOCAL_3',
100:'GUEST_DISK_100_GB_LOCAL_3',
150:'GUEST_DISK_150_GB_LOCAL',
200:'GUEST_DISK_200_GB_LOCAL',
300:'GUEST_DISK_300_GB_LOCAL'
},
'san':{
10:'GUEST_DISK_10_GB_SAN',
20:'GUEST_DISK_20_GB_SAN',
25:'GUEST_DISK_25_GB_SAN_4',
30:'GUEST_DISK_30_GB_SAN',
40:'GUEST_DISK_40_GB_SAN',
50:'GUEST_DISK_50_GB_SAN',
75:'GUEST_DISK_75_GB_SAN',
100:'GUEST_DISK_100_GB_SAN_3',
125:'GUEST_DISK_125_GB_SAN',
150:'GUEST_DISK_150_GB_SAN',
175:'GUEST_DISK_175_GB_SAN',
200:'GUEST_DISK_200_GB_SAN',
250:'GUEST_DISK_250_GB_SAN',
300:'GUEST_DISK_300_GB_SAN',
350:'GUEST_DISK_350_GB_SAN',
400:'GUEST_DISK_400_GB_SAN',
500:'GUEST_DISK_500_GB_SAN',
750:'GUEST_DISK_750_GB_SAN_2',
1000:'GUEST_DISK_1000_GB_SAN_2',
1500:'GUEST_DISK_1500_GB_SAN',
2000:'GUEST_DISK_2000_GB_SAN'
}
}
class Server_Manager(VSManager):
def __init__(self, client):
super(Server_Manager, self).__init__(client)
self.sl_virtual_guest = client['Virtual_Guest']
self.sl_virtual_disk_image = client['Virtual_Disk_Image']
self.sl_software_component = client['Software_Component']
def get_disk_local_flag(self, instance_id):
block_devices = self.sl_virtual_guest.getBlockDevices(id=instance_id)
local_flag = False
for device in block_devices:
if device['device'] == 0:
local_flag = self.sl_virtual_disk_image.getLocalDiskFlag(id=device['diskImageId'])
else:
continue
return local_flag
def disk_upgrade(self, instance_id, disk_upgrade_config):
disk_type = 'LOCAL' if self.get_disk_local_flag(instance_id) else 'SAN'
for volume in disk_upgrade_config:
if volume not in none_first_disk_list[disk_type.lower()]:
raise AttributeError('Invalid disk volume')
mask = [
'id',
'billingItem[id, package[id, items[softwareDescriptionId, id, keyName, itemCategory[name], prices[id]]]]'
]
items_list = self.sl_virtual_guest.getObject(id=instance_id, mask="mask[%s]" % ','.join(mask))['billingItem']['package']['items']
prices = []
for disk_volume in disk_upgrade_config:
disk_keyName = none_first_disk_list[disk_type.lower()][disk_volume]
for item in items_list:
if item['keyName'] == disk_keyName and item['itemCategory']['name'] == 'Second Disk':
prices.append({'id': item['prices'][0]['id']})
maintenance_window = datetime.datetime.now(utils.UTC())
order = {
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest_'
'Upgrade',
'prices': prices,
'properties': [{
'name': 'MAINTENANCE_WINDOW',
'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z")
}],
'virtualGuests': [{'id': int(instance_id)}],
}
if prices:
self.client['Product_Order'].placeOrder(order)
return True
return False
client = SoftLayer.create_client_from_env(username="XXX",api_key="XXXX")
server_mgt = Server_Manager(client)
disk_upgrade_config = [25, 30]
server_mgt.disk_upgrade(17732233, disk_upgrade_config)
It got an exception:
SoftLayerAPIError(SoftLayer_Exception_Public): Unable to add 30 GB (SAN) because a Second Disk price has already been added.
It seem that the error raises as virtual guest has a second already, but how could I upgrade a portable storage?