Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions SoftLayer/CLI/block/detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
83 changes: 83 additions & 0 deletions SoftLayer/CLI/block/duplicate.py
Original file line number Diff line number Diff line change
@@ -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()}


@click.command(context_settings=CONTEXT_SETTINGS)
@click.argument('origin-volume-id')
@click.option('--origin-snapshot-id', '-o',
type=int,
help="ID of an origin volume snapshot to use for duplcation.")
@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)]')
@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.]')
@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']))
@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.')
@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.")
12 changes: 11 additions & 1 deletion SoftLayer/CLI/file/detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
79 changes: 79 additions & 0 deletions SoftLayer/CLI/file/duplicate.py
Original file line number Diff line number Diff line change
@@ -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()}


@click.command(context_settings=CONTEXT_SETTINGS)
@click.argument('origin-volume-id')
@click.option('--origin-snapshot-id', '-o',
type=int,
help="ID of an origin volume snapshot to use for duplcation.")
@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]')
@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.]')
@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']))
@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.')
@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.")
2 changes: 2 additions & 0 deletions SoftLayer/CLI/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
('block:snapshot-restore', 'SoftLayer.CLI.block.snapshot.restore:cli'),
('block:volume-cancel', 'SoftLayer.CLI.block.cancel:cli'),
('block:volume-detail', 'SoftLayer.CLI.block.detail:cli'),
('block:volume-duplicate', 'SoftLayer.CLI.block.duplicate:cli'),
('block:volume-list', 'SoftLayer.CLI.block.list:cli'),
('block:volume-order', 'SoftLayer.CLI.block.order:cli'),

Expand All @@ -98,6 +99,7 @@
('file:snapshot-restore', 'SoftLayer.CLI.file.snapshot.restore:cli'),
('file:volume-cancel', 'SoftLayer.CLI.file.cancel:cli'),
('file:volume-detail', 'SoftLayer.CLI.file.detail:cli'),
('file:volume-duplicate', 'SoftLayer.CLI.file.duplicate:cli'),
('file:volume-list', 'SoftLayer.CLI.file.list:cli'),
('file:volume-order', 'SoftLayer.CLI.file.order:cli'),

Expand Down
37 changes: 36 additions & 1 deletion SoftLayer/fixtures/SoftLayer_Network_Storage.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
DUPLICATABLE_VOLUME = {
'accountId': 1234,
'activeTransactions': None,
'activeTransactionCount': 0,
'billingItem': {
'activeChildren': [{
'categoryCode': 'storage_snapshot_space',
'id': 125,
'cancellationDate': '',
}],
'cancellationDate': '',
'id': 454,
'location': {'id': 449500}
},
'capacityGb': 500,
'id': 102,
'iops': 1000,
'lunId': 2,
'osType': {'keyName': 'LINUX'},
'originalVolumeSize': '500',
'parentVolume': {'snapshotSizeBytes': 1024},
'provisionedIops': '1000',
'replicationPartnerCount': 0,
'serviceResource': {'datacenter': {'id': 449500, 'name': 'dal05'}},
'serviceResourceBackendIpAddress': '10.1.2.3',
'snapshotCapacityGb': '10',
'storageTierLevel': 'READHEAVY_TIER',
'storageType': {'keyName': 'ENDURANCE_BLOCK_STORAGE'},
'username': 'duplicatable_volume_username'
}

getObject = {
'accountId': 1234,
'billingItem': {
Expand All @@ -8,7 +39,8 @@
'categoryCode': 'storage_snapshot_space',
'id': 123,
'cancellationDate': '',
}]
}],
'location': {'id': 449500}
},
'capacityGb': 20,
'createDate': '2015:50:15-04:00',
Expand All @@ -25,6 +57,9 @@
'snapshotCapacityGb': '10',
'parentVolume': {'snapshotSizeBytes': 1024},
'osType': {'keyName': 'LINUX'},
'originalSnapshotName': 'test-origin-snapshot-name',
'originalVolumeName': 'test-origin-volume-name',
'originalVolumeSize': '20',
'schedules': [{
'id': 978,
'type': {'keyname': 'SNAPSHOT_WEEKLY'},
Expand Down
Loading