[Python-modules-commits] [python-softlayer] 02/05: Imported Upstream version 5.4.0

Scott Kitterman kitterman at moszumanska.debian.org
Thu Jan 18 23:43:20 UTC 2018


This is an automated email from the git hooks/post-receive script.

kitterman pushed a commit to branch debian/master
in repository python-softlayer.

commit 3514be20e13cb5af36e03b73e4b3a91b52f39b6f
Author: Scott Kitterman <scott at kitterman.com>
Date:   Thu Jan 18 18:31:20 2018 -0500

    Imported Upstream version 5.4.0
---
 CHANGELOG.md                                    |  30 ++-
 CONTRIBUTORS                                    |   1 +
 README.rst                                      |  20 +-
 SoftLayer/CLI/__init__.py                       |   5 +
 SoftLayer/CLI/block/detail.py                   |   4 +-
 SoftLayer/CLI/file/detail.py                    |   4 +-
 SoftLayer/CLI/{virt => hardware}/ready.py       |  14 +-
 SoftLayer/CLI/order/__init__.py                 |   0
 SoftLayer/CLI/order/category_list.py            |  54 ++++
 SoftLayer/CLI/order/item_list.py                |  77 ++++++
 SoftLayer/CLI/order/package_list.py             |  50 ++++
 SoftLayer/CLI/order/package_locations.py        |  32 +++
 SoftLayer/CLI/order/place.py                    | 112 +++++++++
 SoftLayer/CLI/order/preset_list.py              |  54 ++++
 SoftLayer/CLI/routes.py                         |   9 +
 SoftLayer/CLI/virt/ready.py                     |   6 +-
 SoftLayer/consts.py                             |   2 +-
 SoftLayer/decoration.py                         |  11 +-
 SoftLayer/exceptions.py                         |  12 +-
 SoftLayer/fixtures/SoftLayer_Account.py         |   3 +-
 SoftLayer/fixtures/SoftLayer_Product_Package.py |  18 ++
 SoftLayer/managers/block.py                     |  11 +-
 SoftLayer/managers/dedicated_host.py            |  47 +---
 SoftLayer/managers/file.py                      |  39 +--
 SoftLayer/managers/hardware.py                  |  79 +++---
 SoftLayer/managers/ordering.py                  | 312 +++++++++++++++++++++---
 SoftLayer/managers/vs.py                        |  69 ++----
 SoftLayer/transports.py                         |  79 ++++--
 SoftLayer/utils.py                              |  24 ++
 docs/api/managers/block.rst                     |   5 +
 docs/api/managers/dedicated_host.rst            |   5 +
 docs/api/managers/file.rst                      |   5 +
 docs/api/managers/ordering.rst                  |   5 +
 docs/cli.rst                                    |   1 +
 docs/cli/ordering.rst                           | 108 ++++++++
 docs/conf.py                                    |   4 +-
 setup.py                                        |   5 +-
 tests/CLI/core_tests.py                         |   3 +-
 tests/CLI/modules/order_tests.py                | 192 +++++++++++++++
 tests/CLI/modules/server_tests.py               |  47 ++++
 tests/CLI/modules/vs_tests.py                   |  47 ++++
 tests/basic_tests.py                            |  20 ++
 tests/decoration_tests.py                       |   5 -
 tests/managers/block_tests.py                   |   2 +-
 tests/managers/dedicated_host_tests.py          |  35 +--
 tests/managers/file_tests.py                    |   2 +-
 tests/managers/hardware_tests.py                |   5 +-
 tests/managers/ordering_tests.py                | 257 ++++++++++++++++++-
 tests/managers/vs_tests.py                      | 100 ++++----
 tests/transport_tests.py                        | 121 +++++++--
 tools/requirements.txt                          |   3 +-
 tools/test-requirements.txt                     |   2 +
 52 files changed, 1789 insertions(+), 368 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index faed08f..10a25a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,35 @@
 # Change Log
 
+
+## [5.4.0] - 2018-01-15
+ - Changes: https://github.com/softlayer/softlayer-python/compare/v5.3.2...master
+
+ - Upgraded Requests and Urllib3 library to latest. This allows the library to make use of connection retries, and connection pools. This should prevent the client from crashing if the API gives a connection reset / connection timeout error
+ - reworked wait_for_ready function for virtual, and added to hardware managers. 
+ - fixed block/file iops in the `slcli block|file detail` view
+ - Added sub items to `hw detail --price`, removed reverse PTR entries
+
+### Added to CLI
+- slcli order
+```
+$ ./slcli order
+Usage: slcli order [OPTIONS] COMMAND [ARGS]...
+
+Options:
+  -h, --help  Show this message and exit.
+
+Commands:
+  category-list      List the categories of a package.
+  item-list          List package items used for ordering.
+  package-list       List packages that can be ordered via the...
+  package-locations  List Datacenters a package can be ordered in.
+  place              Place or verify an order.
+  preset-list        List package presets.
+```
+
+
 ## [5.3.2] - 2017-12-18
- - Changes: https://github.com/softlayer/softlayer-python/compare/v5.3.1...master
+ - Changes: https://github.com/softlayer/softlayer-python/compare/v5.3.1...v5.3.2
 
  - Expanded `@retry` useage to a few areas in the hardware manager
  - Added INTERVAL options to block and file replication
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index c097127..4de814b 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -29,3 +29,4 @@ Swapnil Khanapurkar <swapnil_khanapurkar at persistent.co.in>
 The SoftLayer Developer Network <sldn at softlayer.com>
 Tim Ariyeh <tim.ariyeh at gmail.com>
 Wissam Elriachy <wissam.elriachy at gmail.com>
+Anthony Monthe (ZuluPro) <anthony.monthe at gmail.com>
diff --git a/README.rst b/README.rst
index b2c7617..9d53e9f 100644
--- a/README.rst
+++ b/README.rst
@@ -19,7 +19,6 @@ XML-RPC API <http://developer.softlayer.com/reference/softlayerapi>`_.
 A command-line interface is also included and can be used to manage various
 SoftLayer products and services.
 
-Development on this library is done as a best-effort delivery, and some features of the SoftLayer API may not be available through the client.
 
 Documentation
 -------------
@@ -32,6 +31,8 @@ Additional API documentation can be found on the SoftLayer Development Network:
   <http://developer.softlayer.com/reference/softlayerapi>`_
 * `Object mask information and examples
   <http://developer.softlayer.com/article/Object-Masks>`_
+* `Code Examples
+  <https://softlayer.github.io/python/>`_
 
 Installation
 ------------
@@ -56,6 +57,12 @@ InsecurePlatformWarning Notice
 ------------------------------
 This library relies on the `requests <http://docs.python-requests.org/>`_ library to make HTTP requests. On Python versions below Python 2.7.9, requests has started emitting a security warning (InsecurePlatformWarning) due to insecurities with creating SSL connections. To resolve this, upgrade to Python 2.7.9+ or follow the instructions here: http://stackoverflow.com/a/29099439.
 
+Getting Help
+------------
+Bugs and feature requests about this library should have a `GitHub issue <https://github.com/softlayer/softlayer-python/issues>`_ opened about them. 
+
+Issues with the Softlayer API itself should be addressed by opening a ticket.
+
 System Requirements
 -------------------
 * Python 2.7, 3.3, 3.4, 3.5 or 3.6.
@@ -63,9 +70,18 @@ System Requirements
 * A connection to SoftLayer's private network is required to use
   our private network API endpoints.
 
+Python Packages
+---------------
+* six >= 1.7.0
+* prettytable >= 0.7.0
+* click >= 5
+* requests >= 2.18.4
+* prompt_toolkit >= 0.53
+* pygments >= 2.0.0
+* urllib3 >= 1.22
 
 Copyright
 ---------
-This software is Copyright (c) 2016 SoftLayer Technologies, Inc.
+This software is Copyright (c) 2016-2018 SoftLayer Technologies, Inc.
 
 See the bundled LICENSE file for more information.
diff --git a/SoftLayer/CLI/__init__.py b/SoftLayer/CLI/__init__.py
index 3d5d6bf..31d8f4b 100644
--- a/SoftLayer/CLI/__init__.py
+++ b/SoftLayer/CLI/__init__.py
@@ -6,5 +6,10 @@
     :license: MIT, see LICENSE for more details.
 """
 # pylint: disable=w0401, invalid-name
+import logging
 
 from SoftLayer.CLI.helpers import *  # NOQA
+
+logger = logging.getLogger()
+logger.addHandler(logging.StreamHandler())
+logger.setLevel(logging.INFO)
diff --git a/SoftLayer/CLI/block/detail.py b/SoftLayer/CLI/block/detail.py
index ecfd5c4..87c53a8 100644
--- a/SoftLayer/CLI/block/detail.py
+++ b/SoftLayer/CLI/block/detail.py
@@ -28,8 +28,8 @@ def cli(env, volume_id):
     table.add_row(['Capacity (GB)', "%iGB" % block_volume['capacityGb']])
     table.add_row(['LUN Id', "%s" % block_volume['lunId']])
 
-    if block_volume.get('iops'):
-        table.add_row(['IOPs', block_volume['iops']])
+    if block_volume.get('provisionedIops'):
+        table.add_row(['IOPs', int(block_volume['provisionedIops'])])
 
     if block_volume.get('storageTierLevel'):
         table.add_row([
diff --git a/SoftLayer/CLI/file/detail.py b/SoftLayer/CLI/file/detail.py
index cb712dc..e34c1d4 100644
--- a/SoftLayer/CLI/file/detail.py
+++ b/SoftLayer/CLI/file/detail.py
@@ -38,8 +38,8 @@ def cli(env, volume_id):
     else:
         table.add_row(['Used Space', "%dGB" % (used_space / (1 << 30))])
 
-    if file_volume.get('iops'):
-        table.add_row(['IOPs', file_volume['iops']])
+    if file_volume.get('provisionedIops'):
+        table.add_row(['IOPs', int(file_volume['provisionedIops'])])
 
     if file_volume.get('storageTierLevel'):
         table.add_row([
diff --git a/SoftLayer/CLI/virt/ready.py b/SoftLayer/CLI/hardware/ready.py
similarity index 53%
copy from SoftLayer/CLI/virt/ready.py
copy to SoftLayer/CLI/hardware/ready.py
index 1be2e1b..ec2cf99 100644
--- a/SoftLayer/CLI/virt/ready.py
+++ b/SoftLayer/CLI/hardware/ready.py
@@ -11,19 +11,15 @@ from SoftLayer.CLI import helpers
 
 @click.command()
 @click.argument('identifier')
- at click.option('--wait',
-              default=0,
-              show_default=True,
-              type=click.INT,
-              help="Name of the image")
+ at click.option('--wait', default=0, show_default=True, type=click.INT, help="Seconds to wait")
 @environment.pass_env
 def cli(env, identifier, wait):
     """Check if a virtual server is ready."""
 
-    vsi = SoftLayer.VSManager(env.client)
-    vs_id = helpers.resolve_id(vsi.resolve_ids, identifier, 'VS')
-    ready = vsi.wait_for_ready(vs_id, wait)
+    compute = SoftLayer.HardwareManager(env.client)
+    compute_id = helpers.resolve_id(compute.resolve_ids, identifier, 'hardware')
+    ready = compute.wait_for_ready(compute_id, wait)
     if ready:
         env.fout("READY")
     else:
-        raise exceptions.CLIAbort("Instance %s not ready" % vs_id)
+        raise exceptions.CLIAbort("Instance %s not ready" % compute_id)
diff --git a/SoftLayer/CLI/order/__init__.py b/SoftLayer/CLI/order/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/SoftLayer/CLI/order/category_list.py b/SoftLayer/CLI/order/category_list.py
new file mode 100644
index 0000000..91671b8
--- /dev/null
+++ b/SoftLayer/CLI/order/category_list.py
@@ -0,0 +1,54 @@
+"""List package categories."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+from SoftLayer.managers import ordering
+
+COLUMNS = ['name', 'categoryCode', 'isRequired']
+
+
+ at click.command()
+ at click.argument('package_keyname')
+ at click.option('--required',
+              is_flag=True,
+              help="List only the required categories for the package")
+ at environment.pass_env
+def cli(env, package_keyname, required):
+    """List the categories of a package.
+
+    Package keynames can be retrieved from `slcli order package-list`
+
+    \b
+    Example:
+        # List the categories of Bare Metal servers
+        slcli order category-list BARE_METAL_SERVER
+
+    When using the --required flag, it will list out only the categories
+    that are required for ordering that package (see `slcli order item-list`)
+
+    \b
+    Example:
+        # List the required categories for Bare Metal servers
+        slcli order category-list BARE_METAL_SERVER --required
+
+    """
+    client = env.client
+    manager = ordering.OrderingManager(client)
+    table = formatting.Table(COLUMNS)
+
+    categories = manager.list_categories(package_keyname)
+
+    if required:
+        categories = [cat for cat in categories if cat['isRequired']]
+
+    for cat in categories:
+        table.add_row([
+            cat['itemCategory']['name'],
+            cat['itemCategory']['categoryCode'],
+            'Y' if cat['isRequired'] else 'N'
+        ])
+
+    env.fout(table)
diff --git a/SoftLayer/CLI/order/item_list.py b/SoftLayer/CLI/order/item_list.py
new file mode 100644
index 0000000..74f8fd4
--- /dev/null
+++ b/SoftLayer/CLI/order/item_list.py
@@ -0,0 +1,77 @@
+"""List package items."""
+# :license: MIT, see LICENSE for more details.
+import click
+
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+from SoftLayer.managers import ordering
+from SoftLayer.utils import lookup
+
+COLUMNS = ['category', 'keyName', 'description']
+
+
+ at click.command()
+ at click.argument('package_keyname')
+ at click.option('--keyword', help="A word (or string) used to filter item names.")
+ at click.option('--category', help="Category code to filter items by")
+ at environment.pass_env
+def cli(env, package_keyname, keyword, category):
+    """List package items used for ordering.
+
+    The items listed can be used with `slcli order place` to specify
+    the items that are being ordered in the package.
+
+    Package keynames can be retrieved using `slcli order package-list`
+
+    \b
+    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.
+
+    \b
+    Example:
+        # List all items in the VSI package
+        slcli order item-list CLOUD_SERVER
+
+    The --keyword option is used to filter items by name.
+
+    The --category option is used to filter items by category.
+
+    Both --keyword and --category can be used together.
+
+    \b
+    Example:
+        # List Ubuntu OSes from the os category of the Bare Metal package
+        slcli order item-list BARE_METAL_SERVER --category os --keyword ubuntu
+
+    """
+    table = formatting.Table(COLUMNS)
+    manager = ordering.OrderingManager(env.client)
+
+    _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()
+    for catname in sorted(categories):
+        for item in sorted_items[catname]:
+            table.add_row([catname, item['keyName'], item['description']])
+    env.fout(table)
+
+
+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
diff --git a/SoftLayer/CLI/order/package_list.py b/SoftLayer/CLI/order/package_list.py
new file mode 100644
index 0000000..9a6b97e
--- /dev/null
+++ b/SoftLayer/CLI/order/package_list.py
@@ -0,0 +1,50 @@
+"""List packages."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+from SoftLayer.managers import ordering
+
+COLUMNS = ['name',
+           'keyName', ]
+
+
+ at click.command()
+ at click.option('--keyword',
+              help="A word (or string) used to filter package names.")
+ at environment.pass_env
+def cli(env, keyword):
+    """List packages that can be ordered via the placeOrder API.
+
+    \b
+    Example:
+        # List out all packages for ordering
+        slcli order package-list
+
+
+    Keywords can also be used for some simple filtering functionality
+    to help find a package easier.
+
+    \b
+    Example:
+        # List out all packages with "server" in the name
+        slcli order package-list --keyword server
+
+    """
+    manager = ordering.OrderingManager(env.client)
+    table = formatting.Table(COLUMNS)
+
+    _filter = {}
+    if keyword:
+        _filter = {'name': {'operation': '*= %s' % keyword}}
+
+    packages = manager.list_packages(filter=_filter)
+
+    for package in packages:
+        table.add_row([
+            package['name'],
+            package['keyName'],
+        ])
+    env.fout(table)
diff --git a/SoftLayer/CLI/order/package_locations.py b/SoftLayer/CLI/order/package_locations.py
new file mode 100644
index 0000000..9f8ffb6
--- /dev/null
+++ b/SoftLayer/CLI/order/package_locations.py
@@ -0,0 +1,32 @@
+"""List packages."""
+# :license: MIT, see LICENSE for more details.
+import click
+
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+from SoftLayer.managers import ordering
+
+COLUMNS = ['id', 'dc', 'description', 'keyName']
+
+
+ at click.command()
+ at click.argument('package_keyname')
+ at environment.pass_env
+def cli(env, package_keyname):
+    """List Datacenters a package can be ordered in.
+
+    Use the location Key Name to place orders
+    """
+    manager = ordering.OrderingManager(env.client)
+    table = formatting.Table(COLUMNS)
+
+    locations = manager.package_locations(package_keyname)
+    for region in locations:
+        for datacenter in region['locations']:
+            table.add_row([
+                datacenter['location']['id'],
+                datacenter['location']['name'],
+                region['description'],
+                region['keyname']
+            ])
+    env.fout(table)
diff --git a/SoftLayer/CLI/order/place.py b/SoftLayer/CLI/order/place.py
new file mode 100644
index 0000000..f042e25
--- /dev/null
+++ b/SoftLayer/CLI/order/place.py
@@ -0,0 +1,112 @@
+"""Verify or place an order."""
+# :license: MIT, see LICENSE for more details.
+
+import json
+
+import click
+
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import exceptions
+from SoftLayer.CLI import formatting
+from SoftLayer.managers import ordering
+
+COLUMNS = ['keyName',
+           'description',
+           'cost', ]
+
+
+ at click.command()
+ at click.argument('package_keyname')
+ at click.argument('location')
+ at click.option('--preset',
+              help="The order preset (if required by the package)")
+ at click.option('--verify',
+              is_flag=True,
+              help="Flag denoting whether or not to only verify the order, not place it")
+ at click.option('--billing',
+              type=click.Choice(['hourly', 'monthly']),
+              default='hourly',
+              show_default=True,
+              help="Billing rate")
+ at click.option('--complex-type', help=("The complex type of the order. This typically begins"
+                                      " with 'SoftLayer_Container_Product_Order_'."))
+ at click.option('--extras',
+              help="JSON string denoting extra data that needs to be sent with the order")
+ at click.argument('order_items', nargs=-1)
+ at environment.pass_env
+def cli(env, package_keyname, location, preset, verify, billing, complex_type,
+        extras, order_items):
+    """Place or verify an order.
+
+    This CLI command is used for placing/verifying an order of the specified package in
+    the given location (denoted by a datacenter's long name). Orders made via the CLI
+    can then be converted to be made programmatically by calling
+    SoftLayer.OrderingManager.place_order() with the same keynames.
+
+    Packages for ordering can be retrived from `slcli order package-list`
+    Presets for ordering can be retrieved from `slcli order preset-list` (not all packages
+    have presets)
+
+    Items can be retrieved from `slcli order item-list`. In order to find required
+    items for the order, use `slcli order category-list`, and then provide the
+    --category option for each category code in `slcli order item-list`.
+
+    \b
+    Example:
+        # Order an hourly VSI with 4 CPU, 16 GB RAM, 100 GB SAN disk,
+        # Ubuntu 16.04, and 1 Gbps public & private uplink in dal13
+        slcli order place --billing hourly CLOUD_SERVER DALLAS13 \\
+            GUEST_CORES_4 \\
+            RAM_16_GB \\
+            REBOOT_REMOTE_CONSOLE \\
+            1_GBPS_PUBLIC_PRIVATE_NETWORK_UPLINKS \\
+            BANDWIDTH_0_GB_2 \\
+            1_IP_ADDRESS \\
+            GUEST_DISK_100_GB_SAN \\
+            OS_UBUNTU_16_04_LTS_XENIAL_XERUS_MINIMAL_64_BIT_FOR_VSI \\
+            MONITORING_HOST_PING \\
+            NOTIFICATION_EMAIL_AND_TICKET \\
+            AUTOMATED_NOTIFICATION \\
+            UNLIMITED_SSL_VPN_USERS_1_PPTP_VPN_USER_PER_ACCOUNT \\
+            NESSUS_VULNERABILITY_ASSESSMENT_REPORTING \\
+            --extras '{"virtualGuests": [{"hostname": "test", "domain": "softlayer.com"}]}' \\
+            --complex-type SoftLayer_Container_Product_Order_Virtual_Guest
+
+    """
+    manager = ordering.OrderingManager(env.client)
+
+    if extras:
+        extras = json.loads(extras)
+
+    args = (package_keyname, location, order_items)
+    kwargs = {'preset_keyname': preset,
+              'extras': extras,
+              'quantity': 1,
+              'complex_type': complex_type,
+              'hourly': True if billing == 'hourly' else False}
+
+    if verify:
+        table = formatting.Table(COLUMNS)
+        order_to_place = manager.verify_order(*args, **kwargs)
+        for price in order_to_place['prices']:
+            cost_key = 'hourlyRecurringFee' if billing == 'hourly' else 'recurringFee'
+            table.add_row([
+                price['item']['keyName'],
+                price['item']['description'],
+                price[cost_key] if cost_key in price else formatting.blank()
+            ])
+
+    else:
+        if not (env.skip_confirmations or formatting.confirm(
+                "This action will incur charges on your account. Continue?")):
+            raise exceptions.CLIAbort("Aborting order.")
+
+        order = manager.place_order(*args, **kwargs)
+
+        table = formatting.KeyValueTable(['name', 'value'])
+        table.align['name'] = 'r'
+        table.align['value'] = 'l'
+        table.add_row(['id', order['orderId']])
+        table.add_row(['created', order['orderDate']])
+        table.add_row(['status', order['placedOrder']['status']])
+    env.fout(table)
diff --git a/SoftLayer/CLI/order/preset_list.py b/SoftLayer/CLI/order/preset_list.py
new file mode 100644
index 0000000..a619caf
--- /dev/null
+++ b/SoftLayer/CLI/order/preset_list.py
@@ -0,0 +1,54 @@
+"""List package presets."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+from SoftLayer.managers import ordering
+
+COLUMNS = ['name',
+           'keyName',
+           'description', ]
+
+
+ at click.command()
+ at click.argument('package_keyname')
+ at click.option('--keyword',
+              help="A word (or string) used to filter preset names.")
+ at environment.pass_env
+def cli(env, package_keyname, keyword):
+    """List package presets.
+
+    Package keynames can be retrieved from `slcli order package-list`.
+    Some packages do not have presets.
+
+    \b
+    Example:
+        # List the presets for Bare Metal servers
+        slcli order preset-list BARE_METAL_SERVER
+
+    The --keyword option can also be used for additional filtering on
+    the returned presets.
+
+    \b
+    Example:
+        # List the Bare Metal server presets that include a GPU
+        slcli order preset-list BARE_METAL_SERVER --keyword gpu
+
+    """
+    table = formatting.Table(COLUMNS)
+    manager = ordering.OrderingManager(env.client)
+
+    _filter = {}
+    if keyword:
+        _filter = {'activePresets': {'name': {'operation': '*= %s' % keyword}}}
+    presets = manager.list_presets(package_keyname, filter=_filter)
+
+    for preset in presets:
+        table.add_row([
+            preset['name'],
+            preset['keyName'],
+            preset['description']
+        ])
+    env.fout(table)
diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py
index 3fa1158..9a91c80 100644
--- a/SoftLayer/CLI/routes.py
+++ b/SoftLayer/CLI/routes.py
@@ -203,6 +203,14 @@ ALL_ROUTES = [
     ('object-storage:endpoints',
      'SoftLayer.CLI.object_storage.list_endpoints:cli'),
 
+    ('order', 'SoftLayer.CLI.order'),
+    ('order:category-list', 'SoftLayer.CLI.order.category_list:cli'),
+    ('order:item-list', 'SoftLayer.CLI.order.item_list:cli'),
+    ('order:package-list', 'SoftLayer.CLI.order.package_list:cli'),
+    ('order:place', 'SoftLayer.CLI.order.place:cli'),
+    ('order:preset-list', 'SoftLayer.CLI.order.preset_list:cli'),
+    ('order:package-locations', 'SoftLayer.CLI.order.package_locations:cli'),
+
     ('rwhois', 'SoftLayer.CLI.rwhois'),
     ('rwhois:edit', 'SoftLayer.CLI.rwhois.edit:cli'),
     ('rwhois:show', 'SoftLayer.CLI.rwhois.show:cli'),
@@ -223,6 +231,7 @@ ALL_ROUTES = [
     ('hardware:credentials', 'SoftLayer.CLI.hardware.credentials:cli'),
     ('hardware:update-firmware', 'SoftLayer.CLI.hardware.update_firmware:cli'),
     ('hardware:rescue', 'SoftLayer.CLI.hardware.power:rescue'),
+    ('hardware:ready', 'SoftLayer.CLI.hardware.ready:cli'),
 
     ('securitygroup', 'SoftLayer.CLI.securitygroup'),
     ('securitygroup:list', 'SoftLayer.CLI.securitygroup.list:cli'),
diff --git a/SoftLayer/CLI/virt/ready.py b/SoftLayer/CLI/virt/ready.py
index 1be2e1b..c416804 100644
--- a/SoftLayer/CLI/virt/ready.py
+++ b/SoftLayer/CLI/virt/ready.py
@@ -11,11 +11,7 @@ from SoftLayer.CLI import helpers
 
 @click.command()
 @click.argument('identifier')
- at click.option('--wait',
-              default=0,
-              show_default=True,
-              type=click.INT,
-              help="Name of the image")
+ at click.option('--wait', default=0, show_default=True, type=click.INT, help="Seconds to wait")
 @environment.pass_env
 def cli(env, identifier, wait):
     """Check if a virtual server is ready."""
diff --git a/SoftLayer/consts.py b/SoftLayer/consts.py
index 5e69fe2..ee47683 100644
--- a/SoftLayer/consts.py
+++ b/SoftLayer/consts.py
@@ -5,7 +5,7 @@
 
     :license: MIT, see LICENSE for more details.
 """
-VERSION = 'v5.3.2'
+VERSION = 'v5.4.0'
 API_PUBLIC_ENDPOINT = 'https://api.softlayer.com/xmlrpc/v3.1/'
 API_PRIVATE_ENDPOINT = 'https://api.service.softlayer.com/xmlrpc/v3.1/'
 API_PUBLIC_ENDPOINT_REST = 'https://api.softlayer.com/rest/v3.1/'
diff --git a/SoftLayer/decoration.py b/SoftLayer/decoration.py
index 8fb7598..66ce62c 100644
--- a/SoftLayer/decoration.py
+++ b/SoftLayer/decoration.py
@@ -9,8 +9,17 @@ from functools import wraps
 from random import randint
 from time import sleep
 
+from SoftLayer import exceptions
 
-def retry(ex, tries=4, delay=5, backoff=2, logger=None):
+RETRIABLE = (
+    exceptions.ServerError,
+    exceptions.ApplicationError,
+    exceptions.RemoteSystemError,
+    exceptions.TransportError
+)
+
+
+def retry(ex=RETRIABLE, tries=4, delay=5, backoff=2, logger=None):
     """Retry calling the decorated function using an exponential backoff.
 
     http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
diff --git a/SoftLayer/exceptions.py b/SoftLayer/exceptions.py
index 13da847..450dc23 100644
--- a/SoftLayer/exceptions.py
+++ b/SoftLayer/exceptions.py
@@ -27,14 +27,10 @@ class SoftLayerAPIError(SoftLayerError):
         self.reason = self.faultString = fault_string
 
     def __repr__(self):
-        return '<%s(%s): %s>' % (self.__class__.__name__,
-                                 self.faultCode,
-                                 self.faultString)
+        return '<%s(%s): %s>' % (self.__class__.__name__, self.faultCode, self.faultString)
 
     def __str__(self):
-        return '%s(%s): %s' % (self.__class__.__name__,
-                               self.faultCode,
-                               self.faultString)
+        return '%s(%s): %s' % (self.__class__.__name__, self.faultCode, self.faultString)
 
 
 class ParseError(SoftLayerAPIError):
@@ -78,12 +74,12 @@ class SpecViolation(ServerError):
     pass
 
 
-class MethodNotFound(ServerError):
+class MethodNotFound(SoftLayerAPIError):
     """Method name not found."""
     pass
 
 
-class InvalidMethodParameters(ServerError):
+class InvalidMethodParameters(SoftLayerAPIError):
     """Invalid method paramters."""
     pass
 
diff --git a/SoftLayer/fixtures/SoftLayer_Account.py b/SoftLayer/fixtures/SoftLayer_Account.py
index 0f3a0a6..4a59000 100644
--- a/SoftLayer/fixtures/SoftLayer_Account.py
+++ b/SoftLayer/fixtures/SoftLayer_Account.py
@@ -266,7 +266,8 @@ getObject = {
             "statusId": 4,
             "accountId": 1234
         }
-    ]
+    ],
+    'accountId': 1234
 }
 
 getRwhoisData = {
diff --git a/SoftLayer/fixtures/SoftLayer_Product_Package.py b/SoftLayer/fixtures/SoftLayer_Product_Package.py
index f46176a..4b01ef4 100644
--- a/SoftLayer/fixtures/SoftLayer_Product_Package.py
+++ b/SoftLayer/fixtures/SoftLayer_Product_Package.py
@@ -1121,3 +1121,21 @@ getAllObjectsDH = [{
     "isActive": 1,
     "description": "Dedicated Host"
 }]
+
+getRegions = [{
+    "description": "WDC07 - Washington, DC",
+    "keyname": "WASHINGTON07",
+    "locations": [{
+        "location": {
+            "euCompliantFlag": False,
+            "id": 2017603,
+            "longName": "Washington 7",
+            "name": "wdc07",
+            "statusId": 2},
+        "locationPackageDetails": [{
+            "isAvailable": 1,
+            "locationId": 2017603,
+            "packageId": 46
+        }]
+    }]
+}]
diff --git a/SoftLayer/managers/block.py b/SoftLayer/managers/block.py
index 2b68ba1..74b5fb4 100644
--- a/SoftLayer/managers/block.py
+++ b/SoftLayer/managers/block.py
@@ -90,7 +90,7 @@ class BlockStorageManager(utils.IdentifierMixin, object):
                 'serviceResource.datacenter[name]',
                 'serviceResourceBackendIpAddress',
                 'storageTierLevel',
-                'iops',
+                'provisionedIops',
                 'lunId',
                 'originalVolumeName',
                 'originalSnapshotName',
@@ -105,8 +105,7 @@ class BlockStorageManager(utils.IdentifierMixin, object):
                 'replicationSchedule[type[keyname]]]',
             ]
             kwargs['mask'] = ','.join(items)
-        return self.client.call('Network_Storage', 'getObject',
-                                id=volume_id, **kwargs)
+        return self.client.call('Network_Storage', 'getObject', id=volume_id, **kwargs)
 
     def get_block_volume_access_list(self, volume_id, **kwargs):
         """Returns a list of authorized hosts for a specified volume.
@@ -409,8 +408,7 @@ class BlockStorageManager(utils.IdentifierMixin, object):
 
         :param integer volume_id: The volume ID
         :param string reason: The reason for cancellation
-        :param boolean immediate_flag: Cancel immediately or
-        on anniversary date
+        :param boolean immediate_flag: Cancel immediately or on anniversary date
         """
 
         block_volume = self.get_block_volume_details(
@@ -507,8 +505,7 @@ class BlockStorageManager(utils.IdentifierMixin, object):
 
         :param integer volume_id: The volume ID
         :param string reason: The reason for cancellation
-        :param boolean immediate_flag: Cancel immediately or
-        on anniversary date
+        :param boolean immediate_flag: Cancel immediately or on anniversary date
         """
         block_volume = self.get_block_volume_details(
             volume_id,
diff --git a/SoftLayer/managers/dedicated_host.py b/SoftLayer/managers/dedicated_host.py
index 80e0f37..6f6fe59 100644
--- a/SoftLayer/managers/dedicated_host.py
+++ b/SoftLayer/managers/dedicated_host.py
@@ -1,6 +1,6 @@
 """
     SoftLayer.dedicatedhost
-    ~~~~~~~~~~~~
+    ~~~~~~~~~~~~~~~~~~~~~~~
     DH Manager/helpers
 
     :license: MIT, see License for more details.
@@ -23,21 +23,10 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
 
         See product information here https://www.ibm.com/cloud/dedicated
 
-        Example::
-            # Initialize the DedicatedHostManager.
-            # env variables. These can also be specified in ~/.softlayer,
-            # or passed directly to SoftLayer.Client()
-            # SL_USERNAME = YOUR_USERNAME
-            # SL_API_KEY = YOUR_API_KEY
-            import SoftLayer
-            client = SoftLayer.Client()
-            mgr = SoftLayer.DedicatedHostManager(client)
 
     :param SoftLayer.API.BaseClient client: the client instance
-    :param SoftLayer.managers.OrderingManager ordering_manager: an optional
-                                              manager to handle ordering.
-                                              If none is provided, one will be
-                                              auto initialized.
+    :param SoftLayer.managers.OrderingManager ordering_manager: an optional manager to handle ordering.
+                                              If none is provided, one will be auto initialized.
     """
 
     def __init__(self, client, ordering_manager=None):
@@ -52,8 +41,6 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
                        disk=None, datacenter=None, **kwargs):
         """Retrieve a list of all dedicated hosts on the account
 
-        Example::
-
         :param list tags: filter based on list of tags
         :param integer cpus: filter based on number of CPUS
         :param integer memory: filter based on amount of memory
@@ -61,10 +48,7 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
         :param string disk: filter based on disk
         :param string datacenter: filter based on datacenter
         :param dict \\*\\*kwargs: response-level options (mask, limit, etc.)
-        :returns: Returns a list of dictionaries representing the matching
-                  dedicated host.
-
-
+        :returns: Returns a list of dictionaries representing the matching dedicated host.
 
         """
         if 'mask' not in kwargs:
@@ -113,8 +97,7 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
         """Get details about a dedicated host.
 
         :param integer : the host ID
-        :returns: A dictionary containing a large amount of information about
-                  the specified instance.
+        :returns: A dictionary containing host information.
 
         Example::
 
@@ -266,12 +249,8 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
         '''
 
         package_keyname = 'DEDICATED_HOST'
+        package = self.ordering_manager.get_package_by_key(package_keyname, mask=mask)
 
-        package = self.ordering_manager.get_package_by_key(package_keyname,
-                                                           mask=mask)
-
-        if package is None:
-            raise SoftLayer.SoftLayerError("Ordering package not found")
         return package
 
     def _get_location(self, regions, datacenter):
@@ -281,8 +260,7 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
             if region['location']['location']['name'] == datacenter:
                 return region
 
-        raise SoftLayer.SoftLayerError("Could not find valid location for: '%s'"
-                                       % datacenter)
+        raise SoftLayer.SoftLayerError("Could not find valid location for: '%s'" % datacenter)
 
     def get_create_options(self):
         """Returns valid options for ordering a dedicated host."""
@@ -304,10 +282,7 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
                     'key': item['keyName'],
                 })
 
-        return {
-            'locations': locations,
-            'dedicated_host': dedicated_host,
-        }
+        return {'locations': locations, 'dedicated_host': dedicated_host}
 
     def _get_price(self, package):
         """Returns valid price for ordering a dedicated host."""
@@ -316,8 +291,7 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
             if not price.get('locationGroupId'):
                 return price['id']
 
-        raise SoftLayer.SoftLayerError(
-            "Could not find valid price")
+        raise SoftLayer.SoftLayerError("Could not find valid price")
 
     def _get_item(self, package, flavor):
         """Returns the item for ordering a dedicated host."""
@@ -326,8 +300,7 @@ class DedicatedHostManager(utils.IdentifierMixin, object):
             if item['keyName'] == flavor:
                 return item
 
-        raise SoftLayer.SoftLayerError("Could not find valid item for: '%s'"
-                                       % flavor)
+        raise SoftLayer.SoftLayerError("Could not find valid item for: '%s'" % flavor)
 
     def _get_backend_router(self, locations, item):
         """Returns valid router options for ordering a dedicated host."""
diff --git a/SoftLayer/managers/file.py b/SoftLayer/managers/file.py
index 7c271b2..7b3894e 100644
--- a/SoftLayer/managers/file.py
+++ b/SoftLayer/managers/file.py
@@ -87,7 +87,7 @@ class FileStorageManager(utils.IdentifierMixin, object):
                 'serviceResourceBackendIpAddress',
                 'fileNetworkMountAddress',
                 'storageTierLevel',
-                'iops',
+                'provisionedIops',
                 'lunId',
                 'originalVolumeName',
                 'originalSnapshotName',
@@ -357,21 +357,16 @@ class FileStorageManager(utils.IdentifierMixin, object):
         return self.client.call('Network_Storage', 'createSnapshot',
                                 notes, id=volume_id, **kwargs)
 
-    def enable_snapshots(self, volume_id, schedule_type, retention_count,
-                         minute, hour, day_of_week, **kwargs):
... 2428 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-softlayer.git



More information about the Python-modules-commits mailing list