[Python-modules-commits] [python-softlayer] 01/01: Imported Upstream version 5.2.7
Scott Kitterman
kitterman at moszumanska.debian.org
Mon Jun 26 13:33:02 UTC 2017
This is an automated email from the git hooks/post-receive script.
kitterman pushed a commit to branch upstream
in repository python-softlayer.
commit d767b0bec86480329ddb51902630d0fa0be9f7ed
Author: Scott Kitterman <scott at kitterman.com>
Date: Mon Jun 26 09:17:34 2017 -0400
Imported Upstream version 5.2.7
---
.travis.yml | 2 +
CHANGELOG.md | 60 +-
README.rst | 4 +-
RELEASE.md | 12 +
SoftLayer/CLI/block/detail.py | 11 +-
SoftLayer/CLI/block/duplicate.py | 83 +
SoftLayer/CLI/block/order.py | 15 +-
SoftLayer/CLI/block/replication/locations.py | 49 +
SoftLayer/CLI/block/replication/order.py | 2 +-
SoftLayer/CLI/block/replication/partners.py | 57 +
SoftLayer/CLI/core.py | 2 +-
SoftLayer/CLI/custom_types.py | 32 +
SoftLayer/CLI/dns/record_list.py | 14 +-
SoftLayer/CLI/file/detail.py | 14 +-
SoftLayer/CLI/file/duplicate.py | 79 +
SoftLayer/CLI/file/order.py | 23 +-
SoftLayer/CLI/file/replication/locations.py | 49 +
SoftLayer/CLI/file/replication/order.py | 2 +-
SoftLayer/CLI/file/replication/partners.py | 60 +
SoftLayer/CLI/formatting.py | 4 +-
SoftLayer/CLI/iscsi/__init__.py | 1 -
SoftLayer/CLI/iscsi/cancel.py | 30 -
SoftLayer/CLI/iscsi/create.py | 23 -
SoftLayer/CLI/iscsi/detail.py | 54 -
SoftLayer/CLI/iscsi/list.py | 43 -
SoftLayer/CLI/loadbal/detail.py | 97 +-
SoftLayer/CLI/routes.py | 31 +-
SoftLayer/CLI/snapshot/__init__.py | 1 -
SoftLayer/CLI/snapshot/cancel.py | 21 -
SoftLayer/CLI/snapshot/create.py | 20 -
SoftLayer/CLI/snapshot/create_space.py | 22 -
SoftLayer/CLI/snapshot/list.py | 37 -
SoftLayer/CLI/snapshot/restore_volume.py | 22 -
SoftLayer/CLI/template.py | 2 +
SoftLayer/CLI/vpn/__init__.py | 1 +
SoftLayer/CLI/vpn/ipsec/__init__.py | 1 +
SoftLayer/CLI/vpn/ipsec/configure.py | 31 +
SoftLayer/CLI/vpn/ipsec/detail.py | 196 +++
SoftLayer/CLI/vpn/ipsec/list.py | 31 +
SoftLayer/CLI/vpn/ipsec/subnet/__init__.py | 1 +
SoftLayer/CLI/vpn/ipsec/subnet/add.py | 81 +
SoftLayer/CLI/vpn/ipsec/subnet/remove.py | 51 +
SoftLayer/CLI/vpn/ipsec/translation/__init__.py | 1 +
SoftLayer/CLI/vpn/ipsec/translation/add.py | 44 +
SoftLayer/CLI/vpn/ipsec/translation/remove.py | 33 +
SoftLayer/CLI/vpn/ipsec/translation/update.py | 48 +
SoftLayer/CLI/vpn/ipsec/update.py | 102 ++
SoftLayer/consts.py | 2 +-
.../fixtures/SoftLayer_Metric_Tracking_Object.py | 1 -
SoftLayer/fixtures/SoftLayer_Network_Storage.py | 78 +-
.../fixtures/SoftLayer_Network_Storage_Iscsi.py | 68 -
SoftLayer/fixtures/SoftLayer_Product_Package.py | 133 ++
SoftLayer/fixtures/SoftLayer_User_Customer.py | 1 -
SoftLayer/managers/__init__.py | 4 +-
SoftLayer/managers/block.py | 66 +-
SoftLayer/managers/file.py | 91 +-
SoftLayer/managers/hardware.py | 10 +-
SoftLayer/managers/ipsec.py | 290 ++++
SoftLayer/managers/iscsi.py | 174 --
SoftLayer/managers/object_storage.py | 21 +-
SoftLayer/managers/ordering.py | 22 +
SoftLayer/managers/storage_utils.py | 445 ++++-
SoftLayer/managers/vs.py | 11 +-
SoftLayer/testing/xmlrpc.py | 2 +-
docs/api/managers/ipsec.rst | 5 +
docs/api/managers/iscsi.rst | 5 -
docs/cli.rst | 99 +-
docs/cli/ipsec.rst | 220 +++
docs/conf.py | 6 +-
setup.py | 3 +-
tests/CLI/custom_types_tests.py | 31 +
tests/CLI/modules/block_tests.py | 125 +-
tests/CLI/modules/file_tests.py | 146 +-
tests/CLI/modules/ipsec_tests.py | 513 ++++++
tests/managers/block_tests.py | 395 ++++-
tests/managers/file_tests.py | 339 +++-
tests/managers/ipsec_tests.py | 302 ++++
tests/managers/iscsi_tests.py | 122 --
tests/managers/object_storage_tests.py | 9 +
tests/managers/ordering_tests.py | 14 +
tests/managers/storage_utils_tests.py | 1715 ++++++++++++++++++++
tox.ini | 9 +-
82 files changed, 6198 insertions(+), 878 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 6a26a77..fdb7114 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,8 @@ matrix:
env: TOX_ENV=py34
- python: "3.5"
env: TOX_ENV=py35
+ - python: "3.6"
+ env: TOX_ENV=py36
- python: "pypy"
env: TOX_ENV=pypy
- python: "2.7"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a899f1..e3433e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,67 @@
# Change Log
-## [Unreleased]
- - Changes: https://github.com/softlayer/softlayer-python/compare/v5.2.1...HEAD
+## [5.2.7] - 2017-06-22
+ - Changes: https://github.com/softlayer/softlayer-python/compare/v5.2.6...v5.2.7
+
+Adds support for duplicating block and file storage volumes. Only works on Storage as a Service volumes (Volumes that support encryption at rest).
+
+#### Added to CLI
+ * [block|file] volume-duplicate
+
+## [5.2.6] - 2017-05-22
+ - Changes: https://github.com/softlayer/softlayer-python/compare/v5.2.5...v5.2.6
+
+#### Added To CLI
+* ipsec list
+* ipsec detail
+* ipsec configure
+* ipsec update
+* ipsec subnet-add
+* ipsec subnet-remove
+* ipsec translation-add
+* ipsec translation-remove
+* ipsec translation-update
+
+
+## [5.2.5] - 2017-05-05
+ - Changes: https://github.com/softlayer/softlayer-python/compare/v5.2.1...v5.2.5
+
+The SoftLayer_Network_Storage::storageTierLevel relational property changed in https://softlayer.github.io/release_notes/20170503/ , this version fixes problems caused by that.
+
+### Changed
+ - https://github.com/softlayer/softlayer-python/issues/818
+ - https://github.com/softlayer/softlayer-python/pull/817
+
+## [5.2.4] - 2017-04-06
+ - Changes: https://github.com/softlayer/softlayer-python/compare/v5.2.3...v5.2.4
+
+### Changed
+Removed some debug code that was accidently added in the pypi release
+
+## [5.2.3] - 2017-04-05
+ - Changes: https://github.com/softlayer/softlayer-python/compare/v5.2.2...v5.2.3
+
+### Added
+ - Adds Python 3.6 support
+
+### Changed
+ - CLI+API: Removes the iSCSI manager and commands
+ - API: Fixes hardware order failing to find a single bare metal fast provision package to use
+
+## [5.2.2] - 2017-02-24
+ - Changes: https://github.com/softlayer/softlayer-python/compare/v5.2.1...v5.2.2
### Added
+ - Adds release process documentation
+ - CLI: Displays NFS mount point for volumes in volume list and detail commands
+ - CLI+API: Enables `slcli file` and `block` storage commands to order tier 10 endurance storage and replica
### Changed
+ - Updates docs to replace `sl` command with `slcli`
+ - CLI: Removes requirement to have `--os-type` provided for file storage ordering
+ - API: Fixes block storage ordering to handle size provided properly
+ - CLI: Fixes load balancer detail output so that JSON output is sane
+ - API: Includes check if object storage endpoints were provided by the API before trying to add them to the endpoints returned by `list_endpoints`
## [5.2.1] - 2016-10-4
- Changes: https://github.com/softlayer/softlayer-python/compare/v5.2.0...v5.2.1
diff --git a/README.rst b/README.rst
index 8d46772..dba9d7f 100644
--- a/README.rst
+++ b/README.rst
@@ -9,8 +9,8 @@ SoftLayer API Python Client
.. image:: https://badge.fury.io/py/SoftLayer.svg
:target: http://badge.fury.io/py/SoftLayer
-.. image:: https://coveralls.io/repos/softlayer/softlayer-python/badge.svg
- :target: https://coveralls.io/r/softlayer/softlayer-python
+.. image:: https://coveralls.io/repos/github/softlayer/softlayer-python/badge.svg?branch=master
+ :target: https://coveralls.io/github/softlayer/softlayer-python?branch=master
This library provides a simple Python client to interact with `SoftLayer's
diff --git a/RELEASE.md b/RELEASE.md
new file mode 100644
index 0000000..d0a7712
--- /dev/null
+++ b/RELEASE.md
@@ -0,0 +1,12 @@
+# Release steps
+
+* Update version constants (find them by running `git grep [VERSION_NUMBER]`)
+* Create changelog entry (edit CHANGELOG.md with a one-liner for each closed issue going in the release)
+* Commit and push changes to master with the message: "Version Bump to v[VERSION_NUMBER]"
+* Push tag and PyPi `fab release:[VERSION_NUMBER]`. Before you do this, make sure you have fabric installed (`pip install fabric`) and also make sure that you have pip set up with your PyPi user credentials. The easiest way to do that is to create a file at `~/.pypirc` with the following contents:
+
+ ```
+[server-login]
+username:YOUR_USERNAME
+password:YOUR_PASSWORD
+ ```
diff --git a/SoftLayer/CLI/block/detail.py b/SoftLayer/CLI/block/detail.py
index 51a1fbd..b8ba8be 100644
--- a/SoftLayer/CLI/block/detail.py
+++ b/SoftLayer/CLI/block/detail.py
@@ -34,7 +34,7 @@ def cli(env, volume_id):
if block_volume.get('storageTierLevel'):
table.add_row([
'Endurance Tier',
- block_volume['storageTierLevel']['description'],
+ block_volume['storageTierLevel'],
])
table.add_row([
@@ -99,4 +99,13 @@ def cli(env, volume_id):
replicant_list.append(replicant_table)
table.add_row(['Replicant Volumes', replicant_list])
+ if block_volume.get('originalVolumeSize'):
+ duplicate_info = formatting.Table(['Original Volume Name',
+ block_volume['originalVolumeName']])
+ duplicate_info.add_row(['Original Volume Size',
+ block_volume['originalVolumeSize']])
+ duplicate_info.add_row(['Original Snapshot Name',
+ block_volume['originalSnapshotName']])
+ table.add_row(['Duplicate Volume Properties', duplicate_info])
+
env.fout(table)
diff --git a/SoftLayer/CLI/block/duplicate.py b/SoftLayer/CLI/block/duplicate.py
new file mode 100644
index 0000000..98ef1b7
--- /dev/null
+++ b/SoftLayer/CLI/block/duplicate.py
@@ -0,0 +1,83 @@
+"""Order a duplicate block storage volume."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+import SoftLayer
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import exceptions
+
+
+CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
+
+
+ at click.command(context_settings=CONTEXT_SETTINGS)
+ at click.argument('origin-volume-id')
+ at click.option('--origin-snapshot-id', '-o',
+ type=int,
+ help="ID of an origin volume snapshot to use for duplcation.")
+ at click.option('--duplicate-size', '-c',
+ type=int,
+ help='Size of duplicate block volume in GB. '
+ '***If no size is specified, the size of '
+ 'the origin volume will be used.***\n'
+ 'Potential Sizes: [20, 40, 80, 100, 250, '
+ '500, 1000, 2000, 4000, 8000, 12000] '
+ 'Minimum: [the size of the origin volume] '
+ 'Maximum: [the minimum of 12000 GB or '
+ '10*(origin volume size)]')
+ at click.option('--duplicate-iops', '-i',
+ type=int,
+ help='Performance Storage IOPS, between 100 and 6000 in '
+ 'multiples of 100 [only used for performance volumes] '
+ '***If no IOPS value is specified, the IOPS value of the '
+ 'origin volume will be used.***\n'
+ 'Requirements: [If IOPS/GB for the origin volume is less '
+ 'than 0.3, IOPS/GB for the duplicate must also be less '
+ 'than 0.3. If IOPS/GB for the origin volume is greater '
+ 'than or equal to 0.3, IOPS/GB for the duplicate must '
+ 'also be greater than or equal to 0.3.]')
+ at click.option('--duplicate-tier', '-t',
+ help='Endurance Storage Tier (IOPS per GB) [only used for '
+ 'endurance volumes] ***If no tier is specified, the tier '
+ 'of the origin volume will be used.***\n'
+ 'Requirements: [If IOPS/GB for the origin volume is 0.25, '
+ 'IOPS/GB for the duplicate must also be 0.25. If IOPS/GB '
+ 'for the origin volume is greater than 0.25, IOPS/GB '
+ 'for the duplicate must also be greater than 0.25.]',
+ type=click.Choice(['0.25', '2', '4', '10']))
+ at click.option('--duplicate-snapshot-size', '-s',
+ type=int,
+ help='The size of snapshot space to order for the duplicate. '
+ '***If no snapshot space size is specified, the snapshot '
+ 'space size of the origin volume will be used.***\n'
+ 'Input "0" for this parameter to order a duplicate volume '
+ 'with no snapshot space.')
+ at environment.pass_env
+def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
+ duplicate_iops, duplicate_tier, duplicate_snapshot_size):
+ """Order a duplicate block storage volume."""
+ block_manager = SoftLayer.BlockStorageManager(env.client)
+
+ if duplicate_tier is not None:
+ duplicate_tier = float(duplicate_tier)
+
+ try:
+ order = block_manager.order_duplicate_volume(
+ origin_volume_id,
+ origin_snapshot_id=origin_snapshot_id,
+ duplicate_size=duplicate_size,
+ duplicate_iops=duplicate_iops,
+ duplicate_tier_level=duplicate_tier,
+ duplicate_snapshot_size=duplicate_snapshot_size
+ )
+ except ValueError as ex:
+ raise exceptions.ArgumentError(str(ex))
+
+ if 'placedOrder' in order.keys():
+ click.echo("Order #{0} placed successfully!".format(
+ order['placedOrder']['id']))
+ for item in order['placedOrder']['items']:
+ click.echo(" > %s" % item['description'])
+ else:
+ click.echo("Order could not be placed! Please verify your options " +
+ "and try again.")
diff --git a/SoftLayer/CLI/block/order.py b/SoftLayer/CLI/block/order.py
index 22430e4..a5af2a6 100644
--- a/SoftLayer/CLI/block/order.py
+++ b/SoftLayer/CLI/block/order.py
@@ -17,7 +17,8 @@ CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
required=True)
@click.option('--size',
type=int,
- help='Size of block storage volume in GB',
+ help='Size of block storage volume in GB. Permitted Sizes:\n'
+ '20, 40, 80, 100, 250, 500, 1000, 2000, 4000, 8000, 12000',
required=True)
@click.option('--iops',
type=int,
@@ -27,7 +28,7 @@ CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
@click.option('--tier',
help='Endurance Storage Tier (IOP per GB)'
' [required for storage-type endurance]',
- type=click.Choice(['0.25', '2', '4']))
+ type=click.Choice(['0.25', '2', '4', '10']))
@click.option('--os-type',
help='Operating System',
type=click.Choice([
@@ -71,14 +72,14 @@ def cli(env, storage_type, size, iops, tier, os_type,
if snapshot_size is not None:
raise exceptions.CLIAbort(
'Option --snapshot-size not allowed for performance volumes.'
- ' Snapshots are only available for endurance storage.'
+ 'Snapshots are only available for endurance storage.'
)
try:
order = block_manager.order_block_volume(
storage_type='performance_storage_iscsi',
location=location,
- size=size,
+ size=int(size),
iops=iops,
os_type=os_type
)
@@ -88,13 +89,15 @@ def cli(env, storage_type, size, iops, tier, os_type,
if storage_type == 'endurance':
if tier is None:
raise exceptions.CLIAbort(
- 'Option --tier required with Endurance in IOPS/GB [0.25,2,4]')
+ 'Option --tier required with Endurance in IOPS/GB '
+ '[0.25,2,4,10]'
+ )
try:
order = block_manager.order_block_volume(
storage_type='storage_service_enterprise',
location=location,
- size=size,
+ size=int(size),
tier_level=float(tier),
os_type=os_type,
snapshot_size=snapshot_size
diff --git a/SoftLayer/CLI/block/replication/locations.py b/SoftLayer/CLI/block/replication/locations.py
new file mode 100644
index 0000000..80ba5d9
--- /dev/null
+++ b/SoftLayer/CLI/block/replication/locations.py
@@ -0,0 +1,49 @@
+"""List suitable replication datacenters for the given volume."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+import SoftLayer
+from SoftLayer.CLI import columns as column_helper
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+
+COLUMNS = [
+ column_helper.Column('ID', ('id',), mask="id"),
+ column_helper.Column('Long Name', ('longName',), mask="longName"),
+ column_helper.Column('Short Name', ('name',), mask="name"),
+]
+
+DEFAULT_COLUMNS = [
+ 'ID',
+ 'Long Name',
+ 'Short Name',
+]
+
+
+ at click.command()
+ at click.argument('volume-id')
+ at click.option('--sortby', help='Column to sort by', default='Long Name')
+ at click.option('--columns',
+ callback=column_helper.get_formatter(COLUMNS),
+ help='Columns to display. Options: {0}'.format(
+ ', '.join(column.name for column in COLUMNS)),
+ default=','.join(DEFAULT_COLUMNS))
+ at environment.pass_env
+def cli(env, columns, sortby, volume_id):
+ """List suitable replication datacenters for the given volume."""
+ block_storage_manager = SoftLayer.BlockStorageManager(env.client)
+
+ legal_centers = block_storage_manager.get_replication_locations(
+ volume_id
+ )
+
+ if not legal_centers:
+ click.echo("No data centers compatible for replication.")
+ else:
+ table = formatting.KeyValueTable(columns.columns)
+ table.sortby = sortby
+ for legal_center in legal_centers:
+ table.add_row([value or formatting.blank()
+ for value in columns.row(legal_center)])
+
+ env.fout(table)
diff --git a/SoftLayer/CLI/block/replication/order.py b/SoftLayer/CLI/block/replication/order.py
index c25a8be..5aebea1 100644
--- a/SoftLayer/CLI/block/replication/order.py
+++ b/SoftLayer/CLI/block/replication/order.py
@@ -24,7 +24,7 @@ CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
@click.option('--tier',
help='Endurance Storage Tier (IOPS per GB) of the primary'
' volume for which a replicant is ordered [optional]',
- type=click.Choice(['0.25', '2', '4']))
+ type=click.Choice(['0.25', '2', '4', '10']))
@click.option('--os-type',
help='Operating System Type (e.g.: LINUX) of the primary'
' volume for which a replica is ordered [optional]',
diff --git a/SoftLayer/CLI/block/replication/partners.py b/SoftLayer/CLI/block/replication/partners.py
new file mode 100644
index 0000000..f19be0a
--- /dev/null
+++ b/SoftLayer/CLI/block/replication/partners.py
@@ -0,0 +1,57 @@
+"""List existing replicant volumes for a block volume."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+import SoftLayer
+from SoftLayer.CLI import columns as column_helper
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+
+COLUMNS = [
+ column_helper.Column('ID', ('id',)),
+ column_helper.Column('Username', ('username',), mask="username"),
+ column_helper.Column('Account ID', ('accountId',), mask="accountId"),
+ column_helper.Column('Capacity (GB)', ('capacityGb',), mask="capacityGb"),
+ column_helper.Column('Hardware ID', ('hardwareId',), mask="hardwareId"),
+ column_helper.Column('Guest ID', ('guestId',), mask="guestId"),
+ column_helper.Column('Host ID', ('hostId',), mask="hostId"),
+]
+
+DEFAULT_COLUMNS = [
+ 'ID',
+ 'Username',
+ 'Account ID',
+ 'Capacity (GB)',
+ 'Hardware ID',
+ 'Guest ID',
+ 'Host ID'
+]
+
+
+ at click.command()
+ at click.argument('volume-id')
+ at click.option('--sortby', help='Column to sort by', default='Username')
+ at click.option('--columns',
+ callback=column_helper.get_formatter(COLUMNS),
+ help='Columns to display. Options: {0}'.format(
+ ', '.join(column.name for column in COLUMNS)),
+ default=','.join(DEFAULT_COLUMNS))
+ at environment.pass_env
+def cli(env, columns, sortby, volume_id):
+ """List existing replicant volumes for a block volume."""
+ block_storage_manager = SoftLayer.BlockStorageManager(env.client)
+
+ legal_volumes = block_storage_manager.get_replication_partners(
+ volume_id
+ )
+
+ if not legal_volumes:
+ click.echo("There are no replication partners for the given volume.")
+ else:
+ table = formatting.Table(columns.columns)
+ table.sortby = sortby
+ for legal_volume in legal_volumes:
+ table.add_row([value or formatting.blank()
+ for value in columns.row(legal_volume)])
+
+ env.fout(table)
diff --git a/SoftLayer/CLI/core.py b/SoftLayer/CLI/core.py
index 02ef1e0..860cdff 100644
--- a/SoftLayer/CLI/core.py
+++ b/SoftLayer/CLI/core.py
@@ -21,7 +21,7 @@ from SoftLayer.CLI import formatting
from SoftLayer import consts
# pylint: disable=too-many-public-methods, broad-except, unused-argument
-# pylint: disable=redefined-builtin, super-init-not-called
+# pylint: disable=redefined-builtin, super-init-not-called, arguments-differ
START_TIME = time.time()
DEBUG_LOGGING_MAP = {
diff --git a/SoftLayer/CLI/custom_types.py b/SoftLayer/CLI/custom_types.py
new file mode 100644
index 0000000..66167b6
--- /dev/null
+++ b/SoftLayer/CLI/custom_types.py
@@ -0,0 +1,32 @@
+"""
+ SoftLayer.CLI.custom_types
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ Custom type declarations extending click.ParamType
+
+ :license: MIT, see LICENSE for more details.
+"""
+
+import click
+
+
+class NetworkParamType(click.ParamType):
+ """Validates a network parameter type and converts to a tuple.
+
+ todo: Implement to ipaddress.ip_network once the ipaddress backport
+ module can be added as a dependency or is available on all
+ supported python versions.
+ """
+ name = 'network'
+
+ def convert(self, value, param, ctx):
+ try:
+ # Inlined from python standard ipaddress module
+ # https://docs.python.org/3/library/ipaddress.html
+ address = str(value).split('/')
+ if len(address) != 2:
+ raise ValueError("Only one '/' permitted in %r" % value)
+
+ ip_address, cidr = address
+ return (ip_address, int(cidr))
+ except ValueError:
+ self.fail('{} is not a valid network'.format(value), param, ctx)
diff --git a/SoftLayer/CLI/dns/record_list.py b/SoftLayer/CLI/dns/record_list.py
index bea7098..4e46cb8 100644
--- a/SoftLayer/CLI/dns/record_list.py
+++ b/SoftLayer/CLI/dns/record_list.py
@@ -7,7 +7,7 @@ import SoftLayer
from SoftLayer.CLI import environment
from SoftLayer.CLI import formatting
from SoftLayer.CLI import helpers
-# pylint: disable=redefined-builtin
+# pylint: disable=redefined-builtin, redefined-argument-from-local
@click.command()
@@ -37,13 +37,13 @@ def cli(env, zone, data, record, ttl, type):
ttl=ttl,
data=data)
- for record in records:
+ for the_record in records:
table.add_row([
- record['id'],
- record['host'],
- record['type'].upper(),
- record['ttl'],
- record['data']
+ the_record['id'],
+ the_record['host'],
+ the_record['type'].upper(),
+ the_record['ttl'],
+ the_record['data']
])
env.fout(table)
diff --git a/SoftLayer/CLI/file/detail.py b/SoftLayer/CLI/file/detail.py
index 25cdb95..3c9af3f 100644
--- a/SoftLayer/CLI/file/detail.py
+++ b/SoftLayer/CLI/file/detail.py
@@ -16,7 +16,8 @@ def cli(env, volume_id):
file_manager = SoftLayer.FileStorageManager(env.client)
file_volume = file_manager.get_file_volume_details(volume_id)
file_volume = utils.NestedDict(file_volume)
- used_space = int(file_volume['bytesUsed'])
+ used_space = int(file_volume['bytesUsed'])\
+ if file_volume['bytesUsed'] else 0
table = formatting.KeyValueTable(['Name', 'Value'])
table.align['Name'] = 'r'
@@ -43,7 +44,7 @@ def cli(env, volume_id):
if file_volume.get('storageTierLevel'):
table.add_row([
'Endurance Tier',
- file_volume['storageTierLevel']['description'],
+ file_volume['storageTierLevel'],
])
table.add_row([
@@ -114,4 +115,13 @@ def cli(env, volume_id):
replicant_list.append(replicant_table)
table.add_row(['Replicant Volumes', replicant_list])
+ if file_volume.get('originalVolumeSize'):
+ duplicate_info = formatting.Table(['Original Volume Name',
+ file_volume['originalVolumeName']])
+ duplicate_info.add_row(['Original Volume Size',
+ file_volume['originalVolumeSize']])
+ duplicate_info.add_row(['Original Snapshot Name',
+ file_volume['originalSnapshotName']])
+ table.add_row(['Duplicate Volume Properties', duplicate_info])
+
env.fout(table)
diff --git a/SoftLayer/CLI/file/duplicate.py b/SoftLayer/CLI/file/duplicate.py
new file mode 100644
index 0000000..e021697
--- /dev/null
+++ b/SoftLayer/CLI/file/duplicate.py
@@ -0,0 +1,79 @@
+"""Order a duplicate file storage volume."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+import SoftLayer
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import exceptions
+
+
+CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
+
+
+ at click.command(context_settings=CONTEXT_SETTINGS)
+ at click.argument('origin-volume-id')
+ at click.option('--origin-snapshot-id', '-o',
+ type=int,
+ help="ID of an origin volume snapshot to use for duplcation.")
+ at click.option('--duplicate-size', '-c',
+ type=int,
+ help='Size of duplicate file volume in GB. '
+ '***If no size is specified, the size of '
+ 'the origin volume will be used.***\n'
+ 'Minimum: [the size of the origin volume]')
+ at click.option('--duplicate-iops', '-i',
+ type=int,
+ help='Performance Storage IOPS, between 100 and 6000 in '
+ 'multiples of 100 [only used for performance volumes] '
+ '***If no IOPS value is specified, the IOPS value of the '
+ 'origin volume will be used.***\n'
+ 'Requirements: [If IOPS/GB for the origin volume is less '
+ 'than 0.3, IOPS/GB for the duplicate must also be less '
+ 'than 0.3. If IOPS/GB for the origin volume is greater '
+ 'than or equal to 0.3, IOPS/GB for the duplicate must '
+ 'also be greater than or equal to 0.3.]')
+ at click.option('--duplicate-tier', '-t',
+ help='Endurance Storage Tier (IOPS per GB) [only used for '
+ 'endurance volumes] ***If no tier is specified, the tier '
+ 'of the origin volume will be used.***\n'
+ 'Requirements: [If IOPS/GB for the origin volume is 0.25, '
+ 'IOPS/GB for the duplicate must also be 0.25. If IOPS/GB '
+ 'for the origin volume is greater than 0.25, IOPS/GB '
+ 'for the duplicate must also be greater than 0.25.]',
+ type=click.Choice(['0.25', '2', '4', '10']))
+ at click.option('--duplicate-snapshot-size', '-s',
+ type=int,
+ help='The size of snapshot space to order for the duplicate. '
+ '***If no snapshot space size is specified, the snapshot '
+ 'space size of the origin volume will be used.***\n'
+ 'Input "0" for this parameter to order a duplicate volume '
+ 'with no snapshot space.')
+ at environment.pass_env
+def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
+ duplicate_iops, duplicate_tier, duplicate_snapshot_size):
+ """Order a duplicate file storage volume."""
+ file_manager = SoftLayer.FileStorageManager(env.client)
+
+ if duplicate_tier is not None:
+ duplicate_tier = float(duplicate_tier)
+
+ try:
+ order = file_manager.order_duplicate_volume(
+ origin_volume_id,
+ origin_snapshot_id=origin_snapshot_id,
+ duplicate_size=duplicate_size,
+ duplicate_iops=duplicate_iops,
+ duplicate_tier_level=duplicate_tier,
+ duplicate_snapshot_size=duplicate_snapshot_size
+ )
+ except ValueError as ex:
+ raise exceptions.ArgumentError(str(ex))
+
+ if 'placedOrder' in order.keys():
+ click.echo("Order #{0} placed successfully!".format(
+ order['placedOrder']['id']))
+ for item in order['placedOrder']['items']:
+ click.echo(" > %s" % item['description'])
+ else:
+ click.echo("Order could not be placed! Please verify your options " +
+ "and try again.")
diff --git a/SoftLayer/CLI/file/order.py b/SoftLayer/CLI/file/order.py
index 0219efd..d13b952 100644
--- a/SoftLayer/CLI/file/order.py
+++ b/SoftLayer/CLI/file/order.py
@@ -27,18 +27,7 @@ CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
@click.option('--tier',
help='Endurance Storage Tier (IOP per GB)'
' [required for storage-type endurance]',
- type=click.Choice(['0.25', '2', '4']))
- at click.option('--os-type',
- help='Operating System',
- type=click.Choice([
- 'HYPER_V',
- 'LINUX',
- 'VMWARE',
- 'WINDOWS_2008',
- 'WINDOWS_GPT',
- 'WINDOWS',
- 'XEN']),
- required=True)
+ type=click.Choice(['0.25', '2', '4', '10']))
@click.option('--location',
help='Datacenter short name (e.g.: dal09)',
required=True)
@@ -48,7 +37,7 @@ CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
'space along with endurance file storage; specifies '
'the size (in GB) of snapshot space to order')
@environment.pass_env
-def cli(env, storage_type, size, iops, tier, os_type,
+def cli(env, storage_type, size, iops, tier,
location, snapshot_size):
"""Order a file storage volume."""
file_manager = SoftLayer.FileStorageManager(env.client)
@@ -79,8 +68,7 @@ def cli(env, storage_type, size, iops, tier, os_type,
storage_type='performance_storage_nfs',
location=location,
size=size,
- iops=iops,
- os_type=os_type
+ iops=iops
)
except ValueError as ex:
raise exceptions.ArgumentError(str(ex))
@@ -88,7 +76,9 @@ def cli(env, storage_type, size, iops, tier, os_type,
if storage_type == 'endurance':
if tier is None:
raise exceptions.CLIAbort(
- 'Option --tier required with Endurance in IOPS/GB [0.25,2,4]')
+ 'Option --tier required with Endurance in IOPS/GB '
+ '[0.25,2,4,10]'
+ )
try:
order = file_manager.order_file_volume(
@@ -96,7 +86,6 @@ def cli(env, storage_type, size, iops, tier, os_type,
location=location,
size=size,
tier_level=float(tier),
- os_type=os_type,
snapshot_size=snapshot_size
)
except ValueError as ex:
diff --git a/SoftLayer/CLI/file/replication/locations.py b/SoftLayer/CLI/file/replication/locations.py
new file mode 100644
index 0000000..58f979f
--- /dev/null
+++ b/SoftLayer/CLI/file/replication/locations.py
@@ -0,0 +1,49 @@
+"""List suitable replication datacenters for the given volume."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+import SoftLayer
+from SoftLayer.CLI import columns as column_helper
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+
+COLUMNS = [
+ column_helper.Column('ID', ('id',), mask="id"),
+ column_helper.Column('Long Name', ('longName',), mask="longName"),
+ column_helper.Column('Short Name', ('name',), mask="name"),
+]
+
+DEFAULT_COLUMNS = [
+ 'ID',
+ 'Long Name',
+ 'Short Name',
+]
+
+
+ at click.command()
+ at click.argument('volume-id')
+ at click.option('--sortby', help='Column to sort by', default='Long Name')
+ at click.option('--columns',
+ callback=column_helper.get_formatter(COLUMNS),
+ help='Columns to display. Options: {0}'.format(
+ ', '.join(column.name for column in COLUMNS)),
+ default=','.join(DEFAULT_COLUMNS))
+ at environment.pass_env
+def cli(env, columns, sortby, volume_id):
+ """List suitable replication datacenters for the given volume."""
+ file_storage_manager = SoftLayer.FileStorageManager(env.client)
+
+ legal_centers = file_storage_manager.get_replication_locations(
+ volume_id
+ )
+
+ if not legal_centers:
+ click.echo("No data centers compatible for replication.")
+ else:
+ table = formatting.KeyValueTable(columns.columns)
+ table.sortby = sortby
+ for legal_center in legal_centers:
+ table.add_row([value or formatting.blank()
+ for value in columns.row(legal_center)])
+
+ env.fout(table)
diff --git a/SoftLayer/CLI/file/replication/order.py b/SoftLayer/CLI/file/replication/order.py
index 7c4617f..4b3231e 100644
--- a/SoftLayer/CLI/file/replication/order.py
+++ b/SoftLayer/CLI/file/replication/order.py
@@ -24,7 +24,7 @@ CONTEXT_SETTINGS = {'token_normalize_func': lambda x: x.upper()}
@click.option('--tier',
help='Endurance Storage Tier (IOPS per GB) of the primary'
' volume for which a replicant is ordered [optional]',
- type=click.Choice(['0.25', '2', '4']))
+ type=click.Choice(['0.25', '2', '4', '10']))
@environment.pass_env
def cli(env, volume_id, snapshot_schedule, location, tier):
"""Order a file storage replica volume."""
diff --git a/SoftLayer/CLI/file/replication/partners.py b/SoftLayer/CLI/file/replication/partners.py
new file mode 100644
index 0000000..866248f
--- /dev/null
+++ b/SoftLayer/CLI/file/replication/partners.py
@@ -0,0 +1,60 @@
+"""List existing replicant volumes for a file volume."""
+# :license: MIT, see LICENSE for more details.
+
+import click
+import SoftLayer
+from SoftLayer.CLI import columns as column_helper
+from SoftLayer.CLI import environment
+from SoftLayer.CLI import formatting
+
+COLUMNS = [
+ column_helper.Column('ID', ('id',)),
+ column_helper.Column('Username', ('username',), mask="username"),
+ column_helper.Column('Account ID', ('accountId',), mask="accountId"),
+ column_helper.Column('Capacity (GB)', ('capacityGb',), mask="capacityGb"),
+ column_helper.Column('Hardware ID', ('hardwareId',), mask="hardwareId"),
+ column_helper.Column('Guest ID', ('guestId',), mask="guestId"),
+ column_helper.Column('Host ID', ('hostId',), mask="hostId"),
+]
+
+# In-line comment to avoid similarity flag with block version
+
+DEFAULT_COLUMNS = [
+ 'ID',
+ 'Username',
+ 'Account ID',
+ 'Capacity (GB)',
+ 'Hardware ID',
+ 'Guest ID',
+ 'Host ID'
+]
+
+
+ at click.command()
+ at click.argument('volume-id')
+ at click.option('--sortby', help='Column to sort by', default='Username')
+ at click.option('--columns',
+ callback=column_helper.get_formatter(COLUMNS),
+ help='Columns to display. Options: {0}'.format(
+ ', '.join(column.name for column in COLUMNS)),
+ default=','.join(DEFAULT_COLUMNS))
+ at environment.pass_env
+def cli(env, columns, sortby, volume_id):
+ """List existing replicant volumes for a file volume."""
+ file_storage_manager = SoftLayer.FileStorageManager(env.client)
+
+ legal_volumes = file_storage_manager.get_replication_partners(
+ volume_id
+ )
+
+ if not legal_volumes:
+ click.echo("There are no replication partners for the given volume.")
+ else:
+ table = formatting.Table(columns.columns)
+ table.sortby = sortby
+
+ for legal_volume in legal_volumes:
+ table.add_row([value or formatting.blank()
+ for value in columns.row(legal_volume)])
+
+ env.fout(table)
diff --git a/SoftLayer/CLI/formatting.py b/SoftLayer/CLI/formatting.py
index 59917b0..bb3d72d 100644
--- a/SoftLayer/CLI/formatting.py
+++ b/SoftLayer/CLI/formatting.py
@@ -6,7 +6,7 @@
:license: MIT, see LICENSE for more details.
"""
-# pylint: disable=E0202
+# pylint: disable=E0202, consider-merging-isinstance, arguments-differ
import collections
import json
import os
@@ -48,7 +48,7 @@ def format_output(data, fmt='table'): # pylint: disable=R0911,R0912
cls=CLIJSONEncoder)
elif fmt == 'jsonraw':
return json.dumps(format_output(data, fmt='python'),
- CLIJSONEncoder)
+ cls=CLIJSONEncoder)
elif fmt == 'python':
return data.to_python()
diff --git a/SoftLayer/CLI/iscsi/__init__.py b/SoftLayer/CLI/iscsi/__init__.py
deleted file mode 100644
index 2b37904..0000000
--- a/SoftLayer/CLI/iscsi/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""iSCSI storage."""
diff --git a/SoftLayer/CLI/iscsi/cancel.py b/SoftLayer/CLI/iscsi/cancel.py
deleted file mode 100644
index f744cb6..0000000
--- a/SoftLayer/CLI/iscsi/cancel.py
+++ /dev/null
@@ -1,30 +0,0 @@
-"""Cancel an existing iSCSI account."""
-# :license: MIT, see LICENSE for more details.
-
-import click
-
-import SoftLayer
-from SoftLayer.CLI import environment
-from SoftLayer.CLI import exceptions
-from SoftLayer.CLI import formatting
-from SoftLayer.CLI import helpers
-
-
- at click.command()
- at click.argument('identifier')
- at click.option('--reason', help="An optional reason for cancellation")
- at click.option('--immediate',
- is_flag=True,
- help="Cancels the iSCSI immediately instead of on the billing "
- "anniversary")
- at environment.pass_env
-def cli(env, identifier, reason, immediate):
- """Cancel an existing iSCSI account."""
-
- iscsi_mgr = SoftLayer.ISCSIManager(env.client)
- iscsi_id = helpers.resolve_id(iscsi_mgr.resolve_ids, identifier, 'iSCSI')
-
- if not (env.skip_confirmations or formatting.no_going_back(iscsi_id)):
- raise exceptions.CLIAbort('Aborted')
-
- iscsi_mgr.cancel_iscsi(iscsi_id, reason, immediate)
diff --git a/SoftLayer/CLI/iscsi/create.py b/SoftLayer/CLI/iscsi/create.py
deleted file mode 100644
index 95872c7..0000000
--- a/SoftLayer/CLI/iscsi/create.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""Creates an iSCSI target."""
-# :license: MIT, see LICENSE for more details.
-
-import click
-
-import SoftLayer
-from SoftLayer.CLI import environment
-
-
- at click.command()
- at click.option('--size',
- type=click.INT,
... 7412 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