Skip to content

Instantly share code, notes, and snippets.

@bmpotter
Last active October 20, 2016 21:59
Show Gist options
  • Save bmpotter/fa6a45afe098ebd1d37f to your computer and use it in GitHub Desktop.
Save bmpotter/fa6a45afe098ebd1d37f to your computer and use it in GitHub Desktop.
An alternative/better way to order hourly pre-set bare metal svr configurations
import os
import sys
from pprint import pprint as pp
import SoftLayer
# !!!!! To run this you must also get getOrderItemsDict() and supporting functions
# from: https://gist.github.com/bmpotter/db0c5feda536f2d502cd
def getPresetsDict(client, pkgId=200):
'''Get the preset configs for the preset hourly bare metal pkg 200, and then fix the hourly prices,
add in the totalProcessorCapacity, and turn it all into a dict for easy use.'''
# pkgId = 50 # this returns an empty list
mask = 'mask[id,description,keyName,totalMinimumRecurringFee,configuration[price[hourlyRecurringFee,item[description,keyName,totalPhysicalCoreCount,totalPhysicalCoreCapacity,totalProcessorCapacity]]]]'
# http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package/getActivePresets
presets = client['Product_Package'].getActivePresets(id=pkgId, mask=mask)
# The totalMinimumHourlyFee returned is rounded to the nearest dollar (not very helpful). So we need to add up
# all of the fees of the item prices in this configuration. At the same time find the item price with totalProcessorCapacity
# and pull it out to the top.
for p in presets:
hourlyFee = 0
for c in p['configuration']:
hourlyFee += float(c['price']['hourlyRecurringFee'])
if 'totalProcessorCapacity' in c['price']['item']: p['totalProcessorCapacity'] = c['price']['item']['totalProcessorCapacity']
p['totalMinimumHourlyFee'] = hourlyFee
# Now turn the list into a dict for easier use
presetDict = {}
for p in presets:
presetDict[p['keyName']] = p
return presetDict
def orderPresetHw(client, items, presets, presetKeyName='S1270_32GB_2X400GBSSD_NORAID', osKeyName='OS_UBUNTU_14_04_LTS_TRUSTY_TAHR_64_BIT', location='tor01'):
'''Order a bare metal svr using the more involved, but more flexible, product package method.
The items arg must come from getOrderItemsDict() and the presets arg must come from getPresetsDict().'''
pkgId = 200
presetId = presets[presetKeyName]['id']
prices = [
# {'id': getItemPriceId(items, 'os', 'OS_UBUNTU_14_04_LTS_TRUSTY_TAHR_64_BIT')},
# {'id': getItemPriceId(items, 'os', 'OS_WINDOWS_2012_FULL_STD_64_BIT_Max_1')},
{'id': getItemPriceId(items, 'os', osKeyName)},
{'id': getItemPriceId(items, 'port_speed', '100_MBPS_PUBLIC_PRIVATE_NETWORK_UPLINKS')},
# {'id': getItemPriceId(items, 'port_speed', '1_GBPS_PUBLIC_PRIVATE_NETWORK_UPLINKS')},
# {'id': 1800},
{'id': getItemPriceId(items, 'bandwidth', 'BANDWIDTH_0_GB_2')},
{'id': getItemPriceId(items, 'pri_ip_addresses', '1_IP_ADDRESS')},
{'id': getItemPriceId(items, 'remote_management', 'REBOOT_KVM_OVER_IP')},
{'id': getItemPriceId(items, 'vpn_management', 'UNLIMITED_SSL_VPN_USERS_1_PPTP_VPN_USER_PER_ACCOUNT')},
{'id': getItemPriceId(items, 'vulnerability_scanner', 'NESSUS_VULNERABILITY_ASSESSMENT_REPORTING')},
]
# return prices
# create order structure
productOrder = {
# 'orderContainers': [{
# "complexType" : 'Container_Product_Order_Hardware_Server', # a constant that will tell the api what type of thing we're sending it
"quantity" : 1,
"hardware": [{
"hostname": 'foo',
"domain": 'bar.com',
'fixedConfigurationPreset': {'keyName': presetKeyName},
}],
"location": getLocationId(client, location),
# "location": 448994, # tor01
"packageId": pkgId,
'presetId': presetId,
'useHourlyPricing': True,
"prices": prices,
# }]
}
# right now we intentionally want the exceptions to bubble up to the top
# try:
order = client['Product_Order'].verifyOrder(productOrder)
# to really order:
# order = client['Product_Order'].placeOrder(productOrder, False)
return order
# except SoftLayer.exceptions.SoftLayerAPIError as e:
# return 'order exception: '+str(e.faultCode) + ': ' + e.faultString
def testOrderPresetHw(client):
'''Try ordering a specific preset hw config.'''
pkgId = 200
# location = 'tor01'
location = 'mon01'
items = getOrderItemsDict(client, pkgId, location=location)
presets = getPresetsDict(client, pkgId=pkgId)
presetKeyName = 'S1270_8GB_2X1TBSATA_NORAID'
osKeyName = 'OS_UBUNTU_14_04_LTS_TRUSTY_TAHR_64_BIT'
return orderPresetHw(client, items, presets, presetKeyName=presetKeyName, osKeyName=osKeyName, location=location)
def testAllPresetCombos(client):
'''Order a bare metal svr using the more involved, but more flexible, product package method.'''
pkgId = 200
location = 'tor01'
print 'Getting item prices and preset configs...'
items = getOrderItemsDict(client, pkgId, location=location)
presets = getPresetsDict(client, pkgId=pkgId)
results = {}
for presetKeyName in presets:
presetId = presets[presetKeyName]['id']
presetName = presetKeyName
results[presetName] = {}
results[presetName]['good'] = []
results[presetName]['bad-verify'] = []
results[presetName]['bad-order'] = []
for osKeyName in items['os']['items']:
opSys = items['os']['items'][osKeyName]
if 'totalProcessorCapacity' in presets[presetKeyName] and 'capacityRestrictionMaximum' in opSys and presets[presetKeyName]['totalProcessorCapacity'] != int(opSys['capacityRestrictionMaximum']):
print 'Skipping '+str(osKeyName)+' because its capacityRestrictionMaximum ('+opSys['capacityRestrictionMaximum']+') does not match the totalProcessorCapacity ('+str(presets[presetKeyName]['totalProcessorCapacity'])+') of '+str(presetKeyName)
continue
print 'Verifying '+str(presetName)+' with '+str(osKeyName)+'...'
try:
order = orderPresetHw(client, items, presets, presetKeyName=presetKeyName, osKeyName=osKeyName, location=location)
except SoftLayer.exceptions.SoftLayerAPIError as e:
print ' Exception in verify: '+str(e.faultString)
results[presetName]['bad-verify'].append(osKeyName)
continue
if 'postTaxRecurringHourly' not in order:
print ' Error: order structure returned did not contain postTaxRecurringHourly'
results[presetName]['bad-order'].append(osKeyName)
continue
results[presetName]['good'].append(osKeyName)
print '\n\n'+presetName+' good: '+str(results[presetName]['good'])+'\n'
print presetName+' bad-verify: '+str(results[presetName]['bad-verify'])+'\n'
print presetName+' bad-order: '+str(results[presetName]['bad-order'])+'\n\n'
# break
print 'Summary:'
for p in results:
print '\n\n'+p+' good: '+str(results[p]['good'])+'\n'
print p+' bad-verify: '+str(results[p]['bad-verify'])+'\n'
print p+' bad-order: '+str(results[p]['bad-order'])+'\n\n'
return 'Done'
# Main - Order preset hourly bare metal svr using the more involved, but more flexible, product package method.
# Have a .softlayer file or set SL_USERNAME and SL_API_KEY.
# Omit endpoint_url if you are running this on a softlayer svr.
client = SoftLayer.Client(endpoint_url=SoftLayer.API_PUBLIC_ENDPOINT)
# Verify the order of 1 specific hw preset
result = testOrderPresetHw(client)
# Or you could verify all possible preset/OS combos
# result = testAllPresetCombos(client)
pp(result)
@leeunks
Copy link

leeunks commented Oct 20, 2016

Is there a method to pull the most current information from SL when ordering BM. I have a script to order, but what I don't have is the method to get configuration. Would like to pull info from a particular BM and make a template from that configuration. Is that possible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment