File: item_list.py

package info (click to toggle)
python-softlayer 6.1.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 5,100 kB
  • sloc: python: 53,771; makefile: 289; sh: 57
file content (139 lines) | stat: -rw-r--r-- 5,686 bytes parent folder | download | duplicates (2)
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)