While my culinary endeavors have never been on par with Kevin's(he grills a mean steak), I wanted to take some time to provide this tasty morsel of the new Extended Object Masks which will soon be served in full portion for the feast.
As many users know, the SLAPI is able to provide you with an enormous amount of data about your environment. And as knowledge is power, having access to the SLAPI puts you at least on par with Aquaman. Sometimes however, knowledge sits heavy on the brow, especically when you require more information than current technologies can afford.
Take a look at this script which gathers information about the servers on your account:
objectMask = { 'hardware': { 'frontendNetworkComponents': {}, 'datacenter': {}, 'billingItem': {}, } } client.set_object_mask(objectMask) servers = client.getHardware() # Display Format format = "Hostname: %s PrimaryIp: %s Location: %s Cost/Month: %s" missing = 'n/a' for server in servers: hostname = server.get('hostname', missing) primaryIpAddress = server.get('primaryIpAddress', missing) datacenter = server.get('datacenter', dict()).get('name', missing) recurringFee = server.get('billingItem', dict()).get('recurringFee', missing) print format % (hostname, primaryIpAddress, datacenter, recurringFee)
This will yeild you a text similar to the below for each server on your account:
Hostname: kholland-ded-centos5 PrimaryIp: 108.168.150.122 Location: dal05 Cost/Month: 0 Ticket Review: n/a
Now while the output is nice and neat...the return data from the API looks a little different:
{ 'accountId': ##, 'bareMetalInstanceFlag': 0, 'billingItem': { 'allowCancellationFlag': 1, 'cancellationDate': '', 'categoryCode': 'server', 'createDate': '##', 'cycleStartDate': '##', 'description': 'Superawesome server with amazing performance', 'domainName': 'softlayer.com', 'hostName': 'server', 'id': ##, 'laborFee': '0', 'laborFeeTaxRate': '0', 'lastBillDate': '##', 'modifyDate': '##', 'nextBillDate': '##', 'oneTimeFee': '0', 'oneTimeFeeTaxRate': '0', 'orderItemId': ##, 'parentId': '', 'recurringFee': '0', 'recurringFeeTaxRate': '0', 'recurringMonths': 1, 'resourceTableId': ##, 'serviceProviderId': 1, 'setupFee': '0', 'setupFeeTaxRate': '0'}, 'datacenter': { 'id': 138124, 'longName': 'Dallas 5', 'name': 'dal05'}, 'domain': 'softlayer.com', 'frontendNetworkComponents': [ { 'hardwareId': ##, 'id': ##, 'macAddress': '##', 'maxSpeed': 4x10^20, 'modifyDate': '##', 'name': 'eth', 'networkVlanId': '', 'port': 1, 'primaryIpAddress': '1', 'speed': 10, 'status': 'ACTIVE'}, { 'hardwareId': ##, 'id': ##, 'macAddress': '##', 'maxSpeed': 0, 'modifyDate': '##', 'name': 'eth', 'networkVlanId': '', 'port': 3, 'speed': 0, 'status': 'DISABLED'}], 'fullyQualifiedDomainName': 'server.softlayer.com', 'globalIdentifier': '##', 'hardwareStatusId': 5, 'hostname': 'server', 'id': ##, 'manufacturerSerialNumber': '##', 'networkManagementIpAddress': '1', 'notes': 'testing notes', 'primaryBackendIpAddress': '##', 'primaryIpAddress': '##', 'privateIpAddress': '##', 'serialNumber': '##', 'serviceProviderId': 1, 'serviceProviderResourceId': ##}
I think we can all agree that this is one mighty fine looking piece of JSON however, the 5 data-points required for our use came with a lot of baggage. Not much of an inconvenience for a few servers, but when making this call on 10's or 100' of objects you run into the risk of the API returning an error due to the size of the return data being too large to handle.
You could fix this using Result Limits to paginate the servers. This works, but there is additional logic which needs to be developed and arguably a performance impact which must be mitigated.
Today's solution will use our new Extended Object Mask's ability to reduce the payload size by specifying an inclusive list of the properties you need...in similar fashion to our REST API's Object Masks.
Note - You will need to update your API client to the latest version found on our GitHub to use this new feature.
All we need to do is change the Object Mask
mask = """ mask[ hostname, datacenter.name, primaryIpAddress, billingItem.recurringFee ] """
The new object mask should be a string and contain a comma separated list enclosed by mask[]
. You are able to specify properties inside of complex data types with a period, [complexType].[property].
The output of the script will remain the same but lets check out the return data from the api:
{ 'billingItem': { 'recurringFee': '##'}, 'datacenter': { 'name': 'dal05'}, 'hostname': 'server', 'primaryIpAddress': '##'}
The Extended Object Masks can be used with our REST, XML-RPC and SOAP endpoints and are currently available for use in a beta state. Please send us your feedback!
Keep an eye out in the coming weeks for more documentation on their use...
-Phil