1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
"""List package items."""
# :license: MIT, see LICENSE for more details.
import click
from SoftLayer.CLI.command import SLCommand as SLCommand
from SoftLayer.CLI import environment
from SoftLayer.CLI import formatting
from SoftLayer.managers import ordering
from SoftLayer.utils import lookup
COLUMNS = ['Category', 'KeyName', 'Description', 'Price Id']
COLUMNS_ITEM_PRICES = ['KeyName', 'Price Id', 'Hourly', 'Monthly', 'Restriction']
COLUMNS_ITEM_PRICES_LOCATION = ['KeyName', 'Price Id', 'Hourly', 'Monthly', 'Restriction']
@click.command(cls=SLCommand)
@click.argument('package_keyname')
@click.option('--keyword', '-k', help="A word (or string) used to filter item names.")
@click.option('--category', '-c', help="Category code to filter items by")
@click.option('--prices', '-p', is_flag=True,
help='Use --prices to list the server item prices, and to list the '
'Item Prices by location, add it to the --prices option using '
'location KeyName, e.g. --prices AMSTERDAM02')
@click.argument('location', required=False)
@environment.pass_env
def cli(env, package_keyname, keyword, category, prices, location=None):
"""List package items used for ordering.
The item keyNames listed can be used with `slcli order place` to specify
the items that are being ordered in the package.
.. Note::
Items with a numbered category, like disk0 or gpu0, can be included
multiple times in an order to match how many of the item you want to order.
::
# List all items in the VSI package
slcli order item-list CLOUD_SERVER
# List Ubuntu OSes from the os category of the Bare Metal package
slcli order item-list BARE_METAL_SERVER --category os --keyword ubuntu
"""
manager = ordering.OrderingManager(env.client)
tables = []
_filter = {'items': {}}
if keyword:
_filter['items']['description'] = {'operation': '*= %s' % keyword}
if category:
_filter['items']['categories'] = {'categoryCode': {'operation': '_= %s' % category}}
items = manager.list_items(package_keyname, filter=_filter)
sorted_items = sort_items(items)
categories = sorted_items.keys()
if prices:
_item_list_prices(categories, sorted_items, tables)
if location:
location_prices = manager.get_item_prices_by_location(location, package_keyname)
_location_item_prices(location_prices, location, tables)
else:
table_items_detail = formatting.Table(COLUMNS)
for category_name in sorted(categories):
for item in sorted_items[category_name]:
table_items_detail.add_row([category_name, item['keyName'], item['description'], get_price(item)])
tables.append(table_items_detail)
env.fout(tables)
def sort_items(items):
"""sorts the items into a dictionary of categories, with a list of items"""
sorted_items = {}
for item in items:
category = lookup(item, 'itemCategory', 'categoryCode')
if sorted_items.get(category) is None:
sorted_items[category] = []
sorted_items[category].append(item)
return sorted_items
def get_price(item):
"""Given an SoftLayer_Product_Item, returns its default price id"""
for price in item.get('prices', []):
if not price.get('locationGroupId'):
return price.get('id')
return 0
def _item_list_prices(categories, sorted_items, tables):
"""Add the item prices cost and capacity restriction to the table"""
table_prices = formatting.Table(COLUMNS_ITEM_PRICES)
for category in sorted(categories):
for item in sorted_items[category]:
for price in item['prices']:
if not price.get('locationGroupId'):
cr_max = get_item_price_data(price, 'capacityRestrictionMaximum')
cr_min = get_item_price_data(price, 'capacityRestrictionMinimum')
cr_type = get_item_price_data(price, 'capacityRestrictionType')
table_prices.add_row([item['keyName'], price['id'],
get_item_price_data(price, 'hourlyRecurringFee'),
get_item_price_data(price, 'recurringFee'),
"%s - %s %s" % (cr_min, cr_max, cr_type)])
tables.append(table_prices)
def get_item_price_data(price, item_attribute):
"""Given an SoftLayer_Product_Item_Price, returns its default price data"""
result = '-'
if item_attribute in price:
result = price[item_attribute]
return result
def _location_item_prices(location_prices, location, tables):
"""Add a location prices table to tables.
:param list location_prices : Location prices.
:param string location : Location.
:param list tables: Table list to add location prices table.
"""
location_prices_table = formatting.Table(COLUMNS_ITEM_PRICES_LOCATION, title="Item Prices for %s" % location)
location_prices_table.sortby = 'KeyName'
location_prices_table.align = 'l'
for price in location_prices:
cr_max = get_item_price_data(price, 'capacityRestrictionMaximum')
cr_min = get_item_price_data(price, 'capacityRestrictionMinimum')
cr_type = get_item_price_data(price, 'capacityRestrictionType')
location_prices_table.add_row(
[price['item']['keyName'], price['id'],
get_item_price_data(price, 'hourlyRecurringFee'),
get_item_price_data(price, 'recurringFee'),
"%s - %s %s" % (cr_min, cr_max, cr_type)])
tables.append(location_prices_table)
|