For these examples, the following class structure will be used. Since most of these examples will share a lot of the initialization code, this class will help reduce the noise level.
All these examples will have a function definition that can simply be added to the example
class and run with a call from the if __name__ == "__main__":
block.
import SoftLayer
from SoftLayer.managers.ordering import OrderingManager
from pprint import pprint as pp
class example():
def __init__(self):
"""Sets up the SoftLayer client, and debugger client"""
self.client = SoftLayer.Client()
# Sets up the SoftLayer debugger, allowing for more verbose output.
debugger = SoftLayer.DebugTransport(self.client.transport)
self.client.transport = debugger
def main(self, vsi):
"""Gets the vsi Object"""
vsi = self.client.call('Virtual_Guest', 'getObject', id=vsi)
pp(vsi)
def debug(self):
"""Iteratess through all class made in this session"""
for call in self.client.transport.get_last_calls():
print(self.client.transport.print_reproduceable(call))
if __name__ == "__main__":
main = example()
vsi = 123465
main.main(vsi)
# Add any functions you need to call below.
This example calls SoftLayer_Virtual_Guest::generateOrderTemplate() to ensure the SoftLayer_Virtual_Guest template object you created is valid.
From there you can pass the same template to SoftLayer_Virtual_Guest::createObject() and a new virtual guest will be created. The only limitation here is that some options are not available with SoftLayer_Virtual_Guest::createObject(), namely adding IPv6 addresses.
To get the options avaliable for Virtual Guest creation, see SoftLayer_Virtual_Guest::getCreateObjectOptions
When creating a templateObject, don’t set startCpus
and maxMemory
fields, these are legacy options, use supplementalCreateObjectOptions->flavorKeyName
to select how much RAM/CPU the new VSI will have.
templateObject = {
# The name of the server
"hostname": "host1",
# The domain for the server
"domain": "example.com",
# Specifies the billing type for the server.
"hourlyBillingFlag": True,
# An identifier for the operating system to provision the server with.
"operatingSystemReferenceCode": "UBUNTU_LATEST",
# Specifies which datacenter the server is to be provisioned in.
"datacenter": {"name": "dal10"},
# Sets metadata, optional.
"userData": [{"value": "someValue"}],
"supplementalCreateObjectOptions": {
"flavorKeyName": "B1_1X2X100" # list from createObjectOptions
}
}
def getCreateOptions(self):
"""Prints out the options available for creating virtual guests"""
create_options = self.client.call('SoftLayer_Virtual_Guest', 'getCreateObjectOptions')
pp(create_options)
def verifyObject(self, templateObject):
"""Pass in a templateObject, defined above, to test if it is valid."""
try:
receipt = self.client.call(
'SoftLayer_Virtual_Guest', 'generateOrderTemplate',
templateObject
)
pp(receipt)
except SoftLayer.SoftLayerAPIError as e:
print("Unable to verify VSI. {} {}".format(e.faultCode, e.faultString))
def createObject(self, templateObject):
"""Pass in a templateObject, defined above, to actually create a VSI."""
try:
receipt = self.client.call(
'SoftLayer_Virtual_Guest', 'createObject',
templateObject
)
pp(receipt)
except SoftLayer.SoftLayerAPIError as e:
print("Unable to create VSI. {} {}".format(e.faultCode, e.faultString))
getCreateOptions
has a lot of irrelevant output, and trimming that out takes a bit of code to complete that gets in the way of this example. See SoftLayer/CLI/virt/create_options.py for how the SLCLI handles the output.
SLCLI also has this as a command feature. See slcli vs create
and slcli vs create-options
This example uses Ordering Manager for interacting with the API, it is using the PUBLIC_CLOUD_SERVER package and include sshkeys and a post provision script.
def create_vsi():
vsi_mgr = OrderingManager(client)
package = 'PUBLIC_CLOUD_SERVER'
location = 'DALLAS13'
preset = 'B1_2X8X100'
items = ['BANDWIDTH_0_GB_2',
'MONITORING_HOST_PING',
'NOTIFICATION_EMAIL_AND_TICKET',
'OS_DEBIAN_9_X_STRETCH_LAMP_64_BIT',
'1_IP_ADDRESS',
'1_IPV6_ADDRESS',
'1_GBPS_PUBLIC_PRIVATE_NETWORK_UPLINKS',
'REBOOT_REMOTE_CONSOLE',
'AUTOMATED_NOTIFICATION',
'UNLIMITED_SSL_VPN_USERS_1_PPTP_VPN_USER_PER_ACCOUNT',
]
complex_type = 'SoftLayer_Container_Product_Order_Virtual_Guest'
extras = {"virtualGuests": [{"hostname": "test", "domain": "ibm.com"}],
"provisionScripts": ["https://examples.provisioning.org"],
"sshKeys": [{"sshKeyIds": [1234, 1235]}]
}
billing_hourly = True
# uses vsi_mgr.place_order instead of vsi_mgr.verify_order to create the vsi
vsi = vsi_mgr.verify_order(package, location, items, complex_type=complex_type,
hourly=billing_hourly, preset_keyname=preset, extras=extras, quantity=1)
pp(vsi)
Tags cannot be set at create time, they can only be added after a VSI has been provisioned, or at least gotten an id
.
SoftLayer_Virtual_Guest::setTags() will either return True
, or an Exception
.
def tagGuest(self, vsi_id, tags="default, tags, csv formatted"):
"""Adds tags to vsi_id"""
try:
self.client.call('SoftLayer_Virtual_Guest', 'setTags',
tags, id=vsi_id)
except SoftLayer.SoftLayerAPIError as e:
print("Unable to tag {}, {} {}".format(e.faultCode, e.faultString))
Occasionally you will want to change some of the details of a server, like its hostname, or notes for example. This can be don with SoftLayer_Virtual_Guest::editObject()
# A Virtual_Guest object. Not all fields are changeable.
objectTemplate = {
'hostname': 'myhostnameEdited',
'notes': 'edited from api'
}
def editGuest(self, vsi_id, objectTemplate):
try:
result = self.client.call('SoftLayer_Virtual_Guest', 'editObject',
objectTemplate, vsi_id)
pp(result)
except SoftLayer.SoftLayerAPIError as e:
print("Unable to edit {}, {} {}".format(vsi_id, e.faultCode, e.faultString))
Usually changing the port speed is used to disable or enable an interface. Speed values can only be 0 (Disconnect), 10, 100, or 1000. The new speed must be equal to or less than the max speed of the interface. If you want to increase the speed to a higher limit than was ordered, that will require an upgrade order for the virtual guest.
setPublicNetworkInterfaceSpeed and p(/reference/services/SoftLayer_Virtual_Guest/setPrivateNetworkInterfaceSpeed/) both will return True
on success, or an Exception
on a failure.
def setPortSpeed(self, vsi_id, speed=0, public=False, private=False):
"""Sets vsi public and/or private interfaces to speed"""
if public:
try:
self.client.call(
'SoftLayer_Virtual_Guest', 'setPublicNetworkInterfaceSpeed',
speed, id=vsi_id)
except SoftLayer.SoftLayerAPIError as e:
print("Unable to set public interface on {} to {}, {} {}".format(
vsi_id, speed, e.faultCode, e.faultString))
if private:
try:
self.client.call(
'SoftLayer_Virtual_Guest', 'setPrivateNetworkInterfaceSpeed',
speed, id=vsi_id)
except SoftLayer.SoftLayerAPIError as e:
print("Unable to set private interface on {} to {}, {} {}".format(
vsi_id, speed, e.faultCode, e.faultString))
This example will get a listing of all the Virtual Guests on your account, with an option to filter that result by hostname.
iter=True
in the API call will return a python generator, and automatically paginate through the results. Especially useful for accounts with a long list of guests.
def listGuets(self, hostname='not null'):
"""Gets all virtual guests, with optional hostname filter"""
filterInstance = {'virtualGuests': {'host':{'operation':hostname}}}
objectMask = "mask[location]"
instances = self.client.call('SoftLayer_Account', 'getVirtualGuests', iter=True, filter=filterInstance, mask=objectMask)
pp(instances)
Print out the available upgrades a Virtual Guest can order.
SoftLayer_Virtual_Guest::getUpgradeItemPrices() This method exclude downgrade item prices by default. You can set the “includeDowngradeItemPrices” parameter to true so that it can include downgrade item prices.
def getUpgrades(self, vsi_id):
"""Gets available upgrades and downgrades for vsi_id"""
upgrades = self.client.call('SoftLayer_Virtual_Guest', 'getUpgradeItemPrices', True, id=vsi_id)
pp(upgrades)
The following API calls exist for power management, and they all are called simply by passing in the VSI id you want to deal with. the Soft
commands will send a signal to the OS to reboot safely. Where the Hard
command will forcefully shut down the VSI.
These methods will all either return True
, or an Exception if something prevented a Guest from changing power state. If you get an exception, try with a more forceful command. RebootHard
instead of rebootSoft
, or powerOff
instead of RebootHard
. If that still doesn’t work, a support ticket will need to be created for support to investigate why the Guest is in a stuck state.
def rebootGuest(self, vsi_id, force=False):
try:
if force:
self.client.call('SoftLayer_Virtual_Guest', 'rebootHard')
else:
self.client.call('SoftLayer_Virtual_Guest', 'rebootSoft')
except SoftLayer.SoftLayerAPIError as e:
print("Unable to reboot {}, {} {}".format(
vsi_id, e.faultCode, e.faultString))
def powerGuest(self, vsi_id, powerOff=False):
try:
if powerOff:
self.client.call('SoftLayer_Virtual_Guest', 'powerOff')
else:
self.client.call('SoftLayer_Virtual_Guest', 'powerOn')
except SoftLayer.SoftLayerAPIError as e:
print("Unable to power {}, {} {}".format(
vsi_id, e.faultCode, e.faultString))
If you ever need to get the VSI to a clean, newly provisioned state, issue a OS reload.
def reloadOS(self, vsi_id):
"""Performs a simple OS reload, no changes"""
try:
self.client.call('SoftLayer_Virtual_Guest', 'reloadCurrentOperatingSystemConfiguration', id=vsi_id)
except SoftLayer.SoftLayerAPIError as e:
print("Unable to reload {}, {} {}".format(
vsi_id, e.faultCode, e.faultString))