When estimating a new VSI, issue an estimate via API.
It is assumed that you understand the following articles. Learn more about the Bluemix Infrastructure (formerly SoftLayer) API.
ShinobiLayer: SoftLayer API Next Step: Data Type Object (1) --Qiita
I made a script to get the locationId, so please use it. (It is also possible to specify using keyname.)
getDcLocationId.py
import SoftLayer
import json
from prettytable import PrettyTable
# account info
client = SoftLayer.create_client_from_env()
#objectmask
objectmask = """
longName,
name,
regions[keyname],
locationAddress[
locationId,
address1,
address2,
city,
country,
postalCode,
state
]
"""
dcs = client['Location'].getDatacenters(mask=objectmask)
#dcs_jsonstring = json.dumps(dcs,indent=4)
#print(dcs_jsonstring)
table = PrettyTable([
'ID',
'KeyName',
'Name',
'Detail',
'Country',
'State',
'PostalCode',
'City',
'Address1',
'Address2'
])
for key in range(len(dcs)):
if 'locationAddress' in dcs[key]:
if 'regions' in dcs[key]:
table.add_row([
dcs[key]['locationAddress']['locationId'],
dcs[key]['regions'][0]['keyname'],
dcs[key]['name'],
dcs[key]['longName'],
dcs[key]['locationAddress'].get('country',""),
dcs[key]['locationAddress'].get('state',""),
dcs[key]['locationAddress'].get('postalCode',"")[:11],
dcs[key]['locationAddress'].get('city',""),
dcs[key]['locationAddress'].get('address1',""),
dcs[key]['locationAddress'].get('address2',"")
])
else:
table.add_row([
dcs[key]['locationAddress']['locationId'],
dcs[key].get('regions',""),
dcs[key]['name'],
dcs[key]['longName'],
dcs[key]['locationAddress'].get('country',""),
dcs[key]['locationAddress'].get('state',""),
dcs[key]['locationAddress'].get('postalCode',"")[:11],
dcs[key]['locationAddress'].get('city',""),
dcs[key]['locationAddress'].get('address1',""),
dcs[key]['locationAddress'].get('address2',"")
])
else:
table.add_row([
dcs[key].get('locationAddress',""),
dcs[key]['regions'][0]['keyname'],
dcs[key]['name'],
dcs[key]['longName'],
dcs[key].get('locationAddress',""),
dcs[key].get('locationAddress',""),
dcs[key].get('locationAddress',""),
dcs[key].get('locationAddress',""),
dcs[key].get('locationAddress',""),
dcs[key].get('locationAddress',"")
])
print len(dcs)
print table.get_string(sortby="Name")
#Execution command
python getDcLocationId.py
#result
32
+---------+---------------+-------+--------------+---------+-------+-------------+----------------+----------------------------------------------------------------------------------+-----------------------+
| ID | KeyName | Name | Detail | Country | State | PostalCode | City | Address1 | Address2 |
+---------+---------------+-------+--------------+---------+-------+-------------+----------------+----------------------------------------------------------------------------------+-----------------------+
| 265592 | AMSTERDAM | ams01 | Amsterdam 1 | NL | | 1096 BK | Amsterdam | Paul van Vlissingenstraat 16 | |
| 814994 | AMSTERDAM03 | ams03 | Amsterdam 3 | NL | | 1329BG | Almere | Flevoland | Rondebeltweg 62, |
| 1004997 | CHENNAI | che01 | Chennai 1 | IN | | 600053 | Chennai | 226, Red Hills Road | Kallikuppam, Ambattur |
| 3 | DALLAS | dal01 | Dallas 1 | US | TX | 75207 | Dallas | 1950 Stemmons Freeway | Suite 3048 |
| | DALLAS02 | dal02 | Dallas 2 | | | | | | |
| 138124 | DALLAS05 | dal05 | Dallas 5 | US | TX | 75244 | Dallas | 4849 Alpha Road | |
| 154820 | DALLAS06 | dal06 | Dallas 6 | US | TX | 75207 | Dallas | 1333 N. Stemmons Freeway | Suite 110 |
| | DALLAS07 | dal07 | Dallas 7 | | | | | | |
| 449494 | DALLAS09 | dal09 | Dallas 9 | US | TX | 75081 | Richardson | 900 Quality Way | |
| 1441195 | DALLAS10 | dal10 | Dallas 10 | US | TX | 75063 | Irving | 6431 Longhorn Drive | |
| 449506 | FRANKFURT | fra02 | Frankfurt 2 | DE | | 65936 | Frankfurt | Leonard - Heisswolf - Str 4. | |
| 352494 | HONGKONG02 | hkg02 | Hong Kong 2 | HK | | | Hong Kong | 33 Chun Choi Street, Tseung Kwan O Industrial Estate, New Territories, Hong Kong | |
| 142775 | HOUSTON02 | hou02 | Houston 2 | US | TX | 77067 | Houston | 855 Greens Parkway | Suite 300 |
| 358694 | LONDON02 | lon02 | London 2 | GB | | KT9 1SJ | Chessington | Fountain Court, Cox Lane | Suites 210 and 230 |
| 449596 | MELBOURNE | mel01 | Melbourne 1 | AU | | VIC 3032 | Melbourne | 72 Radnor Drive, Deer Park | |
| 449600 | MEXICO | mex01 | Mexico 1 | MX | | | Querétaro | Km 2 200, Lateral Carretera Estatal 431 El Marques | |
| 815394 | MILAN | mil01 | Milan 1 | IT | | 20010 | CORNAREDO | VIA MONZORO 103 | |
| 449610 | MONTREAL | mon01 | Montreal 1 | CA | QC | J2C 7W2 | Drummondville | 2525 Rue Canadien | |
| 1541257 | OSLO | osl01 | Oslo 1 | NO | | 1900 | Fetsund | Fet Næringspark | Heiaveien 9 |
| 449500 | PARIS | par01 | Paris 1 | FR | | 92582 | Clichy | Société par Actions Simplifiée Unipersonnelle | 7-9 rue Petit |
| 983497 | SAOPAULO | sao01 | Sao Paulo 1 | BR | | Km 67,7 | Medeiros | Rod Dom Gabriel Paulino Couto, | |
| 18171 | SEATTLE | sea01 | Seattle 1 | US | WA | 98168 | Tukwila | 3355 S. 120th Place, Suite# 331 | |
| 1555995 | SEOUL | seo01 | Seoul 1 | KR | | Gyeonggi-do | Seongnam-si | 46, Pangyo-ro 255beon-gil | Bundang-gu |
| 168642 | SANJOSE | sjc01 | San Jose 1 | US | CA | 95054 | Santa Clara | 3105 Alfred St, Suite 331 | |
| 1004995 | SANJOSE03 | sjc03 | San Jose 3 | US | CA | 95054 | Santa Clara | 1100 Space Park Drive | |
| 224092 | SINGAPORE | sng01 | Singapore 1 | SG | | 139964 | East Jurong | 29A International Business Park | |
| 449612 | SYDNEY | syd01 | Sydney 1 | AU | | Ultimo, NSW | Ultimo | 273 Pymont Street | |
| 2013295 | | syd04 | Sydney 4 | AU | | 2759 | Sydney | 1 13, Templar Road | Erskine Park |
| 449604 | TOKYO | tok02 | Tokyo 2 | JP | | 135-0061 | Koto-ku, Tokyo | 6-2-12 Toyosu | |
| 448994 | TORONTO | tor01 | Toronto 1 | CA | ON | L3R 4B6 | Markham | Suite 130 | 371 Gough |
| 37473 | WASHINGTON_DC | wdc01 | Washington 1 | US | VA | 20151 | Chantilly | 4030 Lafayette Center Drive | Suite 331 |
| 957095 | ASHBURN04 | wdc04 | Washington 4 | US | VA | 20147 | Ashburn | 44060 Digital Loudoun Plaza | |
+---------+---------------+-------+--------------+---------+-------+-------------+----------------+----------------------------------------------------------------------------------+-----------------------+
I made a script to get the PackageId, so please use it.
getActivePackages.py
# import
import SoftLayer
from prettytable import PrettyTable
#define objectmask
objectmask = """
id,
name,
keyName,
subDescription
"""
#define table
table = PrettyTable([
'PackageID',
'Name',
'keyName',
'subDescription'
])
# account info
client = SoftLayer.create_client_from_env()
getActivePackages = client['Account'].getActivePackages(mask=objectmask)
for key in range(len(getActivePackages)):
table.add_row([
getActivePackages[key]['id'],
getActivePackages[key]['name'],
getActivePackages[key]['keyName'],
getActivePackages[key]['subDescription']
])
print len(getActivePackages)
print table.get_string(sortby="PackageID")
#Execution command
python getActivePackages.py
#result
35
+-----------+-------------------------------------+--------------------------------------+-------------------------------------+
| PackageID | Name | keyName | subDescription |
+-----------+-------------------------------------+--------------------------------------+-------------------------------------+
| 46 | Cloud Server | CLOUD_SERVER | Virtual Server Instance |
| 174 | Network Gateway Appliance | NETWORK_GATEWAY_APPLIANCE | Network Gateway Appliance |
| 192 | Application Delivery Appliance | APPLICATION_DELIVERY_APPLIANCE | Application Delivery Appliance |
| 194 | Load Balancers | LOAD_BALANCERS | Load Balancers |
| 198 | Portable Storage | PORTABLE_STORAGE | Portable Storage |
| 200 | Bare Metal Server | BARE_METAL_SERVER | Bare Metal Server |
| 206 | Object Storage | OBJECT_STORAGE | Object Storage |
| 208 | Content Delivery Network | CONTENT_DELIVERY_NETWORK | Content Delivery Network |
| 210 | SSL Certificate | SSL_CERTIFICATE | SSL Certificate |
| 212 | Message Queue | MESSAGE_QUEUE | Message Queue |
| 216 | Network Attached Storage | NETWORK_ATTACHED_STORAGE | Network Attached Storage |
| 218 | iSCSI Storage | ISCSI_STORAGE | iSCSI Storage |
| 222 | Performance | PERFORMANCE_STORAGE_SERVICE | Performance Storage |
| 226 | Authentication Services | AUTHENTICATION_SERVICES | Authentication Services |
| 236 | Network Gateway Appliance (10 Gbps) | 2U_NETWORK_GATEWAY_APPLIANCE_1O_GBPS | Network Gateway Appliance (10 Gbps) |
| 242 | POWER8 Servers | POWER8_SERVERS | POWER8 Servers |
| 244 | Monitoring | MONITORING | Monitoring |
| 248 | Dual E5-2600 v3 Series (36 Drives) | DUAL_E52600_V3_36_DRIVES | Dual E5-2600 v3 Series (36 Drives) |
| 251 | Dual E5-2600 v3 Series (12 Drives) | 2U_DUAL_E52600_V3_12_DRIVES | Dual E5-2600 v3 Series (12 Drives) |
| 253 | Dual E5-2600 v3 Series (4 Drives) | DUAL_E52600_4_DRIVES | Dual E5-2600 v3 Series (4 Drives) |
| 255 | Single E3-1270 (4 Drives) | SINGLE_E31270_4_DRIVES | Single E3-1270 (4 Drives) |
| 257 | Single E3-1270 v3 (4 Drives) | SINGLE_E31270_V3_4_DRIVES | Single E3-1270 (4 Drives) |
| 259 | Single E5-2600 Series (4 Drives) | SINGLE_E52600_4_DRIVES | Single E5-2600 Series (4 Drives) |
| 261 | Single E3-1270 (2 Drives) | SINGLE_E31270_2_DRIVES | Single E3-1270 (2 Drives) |
| 263 | Dual E5-2600 Series (36 Drives) | 4U_DUAL_E52600_36_DRIVES | Dual E5-2600 Series (36 Drives) |
| 265 | Dual E5-2600 Series (12 Drives) | 2U_DUAL_E52600_12_DRIVES | Dual E5-2600 Series (12 Drives) |
| 267 | Quad E5-4600 Series (24 Drives) | 4U_QUAD_E54600_24_DRIVES | Quad E5-4600 Series (24 Drives) |
| 269 | Quad E7-4800 Series (6 Drives) | 2U_QUAD_E74800_6_DRIVES | Quad E7-4800 Series (6 Drives) |
| 271 | Quad E7-4800 v2 Series (24 Drives) | 2U_QUAD_E74800_V2_6_DRIVES | Quad E7-4800 v2 Series (24 Drives) |
| 273 | Dual E5-2600 (4 Drives) | DUAL_E52600_4_DRIVES_2 | Dual E5-2600 (4 Drives) |
| 295 | Certified Servers | SAP_HANA_CERTIFIED_SERVERS | SAP Certified Servers |
| 297 | Certified Servers | SAP_NETWEAVER_CERTIFIED_SERVERS | SAP Certified Servers |
| 551 | Dual E5-2600 v4 Series (4 Drives) | DUAL_E52600_V4_4_DRIVES | Dual E5-2600 v4 Series (4 Drives) |
| 553 | Dual E5-2600 v4 Series (12 Drives) | DUAL_E52600_V4_12_DRIVES | Dual E5-2600 v4 Series (12 Drives) |
| 555 | Dual E5-2600 v4 Series (36 Drives) | DUAL_E52600_V4_36_DRIVES | Dual E5-2600 v4 Series (36 Drives) |
+-----------+-------------------------------------+--------------------------------------+-------------------------------------+
I made a script to get ItemId, so please use it.
getCategoriesAndItemPrices.py
import SoftLayer
import json
from prettytable import PrettyTable
import operator
# Get the SoftLayer API client object
client = SoftLayer.create_client_from_env()
def getItems(pkgId):
# Get a list of the categories that can be specified and the item prices within each category that you can choose from.
# Build a dict of each category id and what its categoryCode is. This is only used to build the item dict below.
categories = client['Product_Package'].getConfiguration(id=pkgId, mask='isRequired, itemCategory.id, itemCategory.name, itemCategory.categoryCode')
cats = {}
for cat in categories:
catid = cat['itemCategory']['id']
cats[catid] = {'code':cat['itemCategory']['categoryCode'], 'name':cat['itemCategory']['name'], 'isRequired':(cat['isRequired'] == 1)}
# Go thru the items for this pkg and put the key/id pair in the correct category
# Note: the keys are only unique within categories, not between categories
mask = 'id, itemId, recurringFee, hourlyRecurringFee, item.description, item.keyName, categories.id'
itemPrices = client['Product_Package'].getItemPrices(id=pkgId, mask=mask)
items = {} # this is a 2 level dict: 1st key is categoryCode, 2nd key is item keyName, value is item price id and other info
for itemP in itemPrices:
if 'categories' not in itemP: continue
itemId = itemP['id']
itemDesc = itemP['item']['description']
itemKeyName = itemP['item']['keyName']
if 'recurringFee' in itemP: itemFee = itemP['recurringFee']
else: itemFee = '0'
if 'hourlyRecurringFee' in itemP: itemHourlyFee = itemP['hourlyRecurringFee']
else: itemHourlyFee = None
# Go thru this item's supported categories
for itemCat in itemP['categories']:
itemCatId = itemCat['id']
# We correlate the categories and items by the category id
if itemCatId in cats:
# This item supports a category in this package, so add it to the structure under this category
categoryCode = cats[itemCatId]['code']
# If we haven't yet added an entry for this categoryCode, create it now
if categoryCode not in items: items[categoryCode] = {'catName':cats[itemCatId]['name'], 'isRequired':cats[itemCatId]['isRequired'], 'items':{}}
entry = {'id':itemId, 'description':itemDesc, 'fee':itemFee}
if itemHourlyFee: entry['hourlyFee'] = itemHourlyFee
if itemKeyName in items[categoryCode]['items']: print 'Warning: items['+categoryCode+"]['items']["+itemKeyName+'] already has a value of '+str(items[categoryCode]['items'][itemKeyName])+' and we are overwriting it with '+str(entry)
# Now add the item to this category
items[categoryCode]['items'][itemKeyName] = entry
return items
pkgId = 46 # specify the package id you want = Virtual Server
#pkgId = 297 # SAP Certified Servers
items = getItems(pkgId)
#jsonstring = json.dumps(items,indent=4)
#print(jsonstring)
# define table
table = PrettyTable([
'keyCategory',
'isRequired',
'catName',
'id',
'fee',
'hourlyFee',
'description'
])
for i in range(len(items)):
eachItem = items.keys()[i]
for j in range(len(items[eachItem]['items'].keys())):
itemContent = items[eachItem].keys()[2]
itemName = items[eachItem][itemContent].keys()[j]
table.add_row([
items.keys()[i],
items[eachItem]['isRequired'],
items[eachItem]['catName'],
items[eachItem][itemContent][itemName].get('id',""),
items[eachItem][itemContent][itemName].get('fee',""),
items[eachItem][itemContent][itemName].get('hourlyFee',""),
items[eachItem][itemContent][itemName].get('description',"")
])
print table.get_string(sort_key=operator.itemgetter(1,7),sortby='keyCategory')
#Execution command
python getCategoriesAndItemPrices.py
#result
+-------------------------+------------+----------------------------------------+--------+---------+-----------+-----------------------------------------------------------------------+
| keyCategory | isRequired | catName | id | fee | hourlyFee | description |
+-------------------------+------------+----------------------------------------+--------+---------+-----------+-----------------------------------------------------------------------+
| av_spyware_protection | False | Anti-Virus & Spyware Protection | 34536 | 0 | 0 | McAfee VirusScan Enterprise |
| bandwidth | True | Public Bandwidth | 24745 | 1500 | | Unlimited Bandwidth (100 Mbps Uplink) |
| bandwidth | True | Public Bandwidth | 34183 | 0 | 0 | 0 GB Bandwidth |
| bandwidth | True | Public Bandwidth | 35963 | 0 | | 0 GB Bandwidth |
| bandwidth | True | Public Bandwidth | 50253 | 494.45 | | 10000 GB Bandwidth |
| bandwidth | True | Public Bandwidth | 50369 | 0 | | 250 GB Bandwidth |
| bandwidth | True | Public Bandwidth | 78465 | 1448.56 | | 20000 GB Bandwidth |
| bandwidth | True | Public Bandwidth | 153549 | 745.74 | | 5000 GB Bandwidth |
| bandwidth | True | Public Bandwidth | 164857 | 90.7 | | 1000 GB Bandwidth |
| bc_insurance | False | Insurance | 24329 | 0 | 0 | Business Continuance Insurance |
| cdp_backup | False | CDP Addon | 32414 | 36.25 | | Idera Disk Agent 10 Pack |
...
Make full use of the locationId, PackageId, and ItemId obtained above to issue a quote.
placeQuoteVsi.py
#import package
import SoftLayer
import json
# account info
client = SoftLayer.create_client_from_env()
order = {
"orderContainers": [{
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest',
'quantity': 1,
'virtualGuests': [{
'hostname': 'test',
'domain': 'example.com',
}],
'primaryDiskPartitionId': 1,
'location': 449604, # Tokyo
'packageId': 46, # VSI
'useHourlyPricing': False,
'prices': [
{'id':26125}, # 1 x 2.0 GHz Core
{'id':32597}, # 1 GB RAM
{'id':23070}, # Reboot / Remote Console
{'id':26737}, # 100 Mbps Public & Private Networks
{'id':50369}, # 250 GB Bandwidth
{'id':34807}, # 1 IP Address
{'id':26466}, # 100 GB (LOCAL) First Disk
{'id':175779}, # Windows Server 2012 R2 Standard Edition (64 bit)
#{'id':171611}, # Ubuntu 16.04 (64 bit)
{'id':27023}, # Host Ping Monitoring
{'id':32500}, # Email and Ticket Notifications
{'id':32627}, # Automated Notification Response
{'id':33483}, # Unlimited SSL VPN Users & 1 PPTP VPN User per account
{'id':35310} # Vulnerability Assessments & Management
],
},
{
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest',
'quantity': 1,
'virtualGuests': [{
'hostname': 'test',
'domain': 'example.com',
}],
"primaryDiskPartitionId": 1,
'location': 449604, # Tokyo
'packageId': 46, # VSI
'useHourlyPricing': False,
'prices': [
{'id':26125}, # 1 x 2.0 GHz Core
{'id':32597}, # 1 GB RAM
{'id':23070}, # Reboot / Remote Console
{'id':26737}, # 100 Mbps Public & Private Networks
{'id':50369}, # 250 GB Bandwidth
{'id':34807}, # 1 IP Address
{'id':26466}, # 100 GB (LOCAL) First Disk
#{'id':175779}, # Windows Server 2012 R2 Standard Edition (64 bit)
{'id':171611}, # Ubuntu 16.04 (64 bit)
{'id':27023}, # Host Ping Monitoring
{'id':32500}, # Email and Ticket Notifications
{'id':32627}, # Automated Notification Response
{'id':33483}, # Unlimited SSL VPN Users & 1 PPTP VPN User per account
{'id':35310} # Vulnerability Assessments & Management
],
}],
'quoteName': "khayamaQuoteTest",
'sendQuoteEmailFlag': True
}
# placeQuote
placeQuote = client['Product_Order'].placeQuote(order)
#placeQuote = client['Product_Order'].verifyOrder(order)
#jsonstring = json.dumps(placeQuote,indent=4)
#print(jsonstring)
#Execution command
python placeQuoteVsi.py
#result
A quote for the name specified in "quoteName" is saved on the portal.
See here. Save Bluemix IaaS (formerly SoftLayer) quotes to PDF via API --Qiita