Skip to content
Closed
13 changes: 11 additions & 2 deletions SoftLayer/CLI/block/duplicate.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,20 @@
'space size of the origin volume will be used.***\n'
'Input "0" for this parameter to order a duplicate volume '
'with no snapshot space.')
@click.option('--billing',
type=click.Choice(['hourly', 'monthly']),
default='monthly',
help="Optional parameter for Billing rate. Default to monthly")
@environment.pass_env
def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
duplicate_iops, duplicate_tier, duplicate_snapshot_size):
duplicate_iops, duplicate_tier, duplicate_snapshot_size, billing):
"""Order a duplicate block storage volume."""
block_manager = SoftLayer.BlockStorageManager(env.client)

hourly_billing_flag = False
if billing.lower() == "hourly":
hourly_billing_flag = True

if duplicate_tier is not None:
duplicate_tier = float(duplicate_tier)

Expand All @@ -68,7 +76,8 @@ def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
duplicate_size=duplicate_size,
duplicate_iops=duplicate_iops,
duplicate_tier_level=duplicate_tier,
duplicate_snapshot_size=duplicate_snapshot_size
duplicate_snapshot_size=duplicate_snapshot_size,
hourly_billing_flag=hourly_billing_flag
)
except ValueError as ex:
raise exceptions.ArgumentError(str(ex))
Expand Down
22 changes: 19 additions & 3 deletions SoftLayer/CLI/block/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,27 @@
'storage_as_a_service',
'enterprise',
'performance']))
@click.option('--billing',
type=click.Choice(['hourly', 'monthly']),
default='monthly',
help="Optional parameter for Billing rate. Default to monthly")
@environment.pass_env
def cli(env, storage_type, size, iops, tier, os_type,
location, snapshot_size, service_offering):
location, snapshot_size, service_offering, billing):
"""Order a block storage volume."""
block_manager = SoftLayer.BlockStorageManager(env.client)
storage_type = storage_type.lower()

hourly_billing_flag = False
if billing.lower() == "hourly":
hourly_billing_flag = True

if hourly_billing_flag and service_offering != 'storage_as_a_service':
raise exceptions.CLIAbort(
'Hourly billing is only available for the storage_as_a_service '
'service offering'
)

if storage_type == 'performance':
if iops is None:
raise exceptions.CLIAbort(
Expand All @@ -87,7 +101,8 @@ def cli(env, storage_type, size, iops, tier, os_type,
iops=iops,
os_type=os_type,
snapshot_size=snapshot_size,
service_offering=service_offering
service_offering=service_offering,
hourly_billing_flag=hourly_billing_flag
)
except ValueError as ex:
raise exceptions.ArgumentError(str(ex))
Expand All @@ -107,7 +122,8 @@ def cli(env, storage_type, size, iops, tier, os_type,
tier_level=float(tier),
os_type=os_type,
snapshot_size=snapshot_size,
service_offering=service_offering
service_offering=service_offering,
hourly_billing_flag=hourly_billing_flag
)
except ValueError as ex:
raise exceptions.ArgumentError(str(ex))
Expand Down
13 changes: 11 additions & 2 deletions SoftLayer/CLI/file/duplicate.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,20 @@
'space size of the origin volume will be used.***\n'
'Input "0" for this parameter to order a duplicate volume '
'with no snapshot space.')
@click.option('--billing',
type=click.Choice(['hourly', 'monthly']),
default='monthly',
help="Optional parameter for Billing rate. Default to monthly")
@environment.pass_env
def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
duplicate_iops, duplicate_tier, duplicate_snapshot_size):
duplicate_iops, duplicate_tier, duplicate_snapshot_size, billing):
"""Order a duplicate file storage volume."""
file_manager = SoftLayer.FileStorageManager(env.client)

hourly_billing_flag = False
if billing.lower() == "hourly":
hourly_billing_flag = True

if duplicate_tier is not None:
duplicate_tier = float(duplicate_tier)

Expand All @@ -64,7 +72,8 @@ def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
duplicate_size=duplicate_size,
duplicate_iops=duplicate_iops,
duplicate_tier_level=duplicate_tier,
duplicate_snapshot_size=duplicate_snapshot_size
duplicate_snapshot_size=duplicate_snapshot_size,
hourly_billing_flag=hourly_billing_flag
)
except ValueError as ex:
raise exceptions.ArgumentError(str(ex))
Expand Down
22 changes: 19 additions & 3 deletions SoftLayer/CLI/file/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,27 @@
'storage_as_a_service',
'enterprise',
'performance']))
@click.option('--billing',
type=click.Choice(['hourly', 'monthly']),
default='monthly',
help="Optional parameter for Billing rate. Default to monthly")
@environment.pass_env
def cli(env, storage_type, size, iops, tier,
location, snapshot_size, service_offering):
location, snapshot_size, service_offering, billing):
"""Order a file storage volume."""
file_manager = SoftLayer.FileStorageManager(env.client)
storage_type = storage_type.lower()

hourly_billing_flag = False
if billing.lower() == "hourly":
hourly_billing_flag = True

if hourly_billing_flag and service_offering != 'storage_as_a_service':
raise exceptions.CLIAbort(
'Hourly billing is only available for the storage_as_a_service '
'service offering'
)

if storage_type == 'performance':
if iops is None:
raise exceptions.CLIAbort(
Expand All @@ -74,7 +88,8 @@ def cli(env, storage_type, size, iops, tier,
size=size,
iops=iops,
snapshot_size=snapshot_size,
service_offering=service_offering
service_offering=service_offering,
hourly_billing_flag=hourly_billing_flag
)
except ValueError as ex:
raise exceptions.ArgumentError(str(ex))
Expand All @@ -93,7 +108,8 @@ def cli(env, storage_type, size, iops, tier,
size=size,
tier_level=float(tier),
snapshot_size=snapshot_size,
service_offering=service_offering
service_offering=service_offering,
hourly_billing_flag=hourly_billing_flag
)
except ValueError as ex:
raise exceptions.ArgumentError(str(ex))
Expand Down
1 change: 1 addition & 0 deletions SoftLayer/fixtures/SoftLayer_Network_Storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
}],
'cancellationDate': '',
'categoryCode': 'storage_as_a_service',
'hourlyFlag': None,
'id': 454,
'location': {'id': 449500}
},
Expand Down
37 changes: 25 additions & 12 deletions SoftLayer/managers/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,10 @@ def order_replicant_volume(self, volume_id, snapshot_schedule,
:return: Returns a SoftLayer_Container_Product_Order_Receipt
"""

block_mask = 'billingItem[activeChildren],storageTierLevel,osType,'\
'staasVersion,hasEncryptionAtRest,snapshotCapacityGb,'\
'schedules,hourlySchedule,dailySchedule,weeklySchedule,'\
block_mask = 'billingItem[activeChildren,hourlyFlag],'\
'storageTierLevel,osType,staasVersion,'\
'hasEncryptionAtRest,snapshotCapacityGb,schedules,'\
'hourlySchedule,dailySchedule,weeklySchedule,'\
'storageType[keyName],provisionedIops'
block_volume = self.get_block_volume_details(volume_id,
mask=block_mask)
Expand All @@ -261,7 +262,8 @@ def order_replicant_volume(self, volume_id, snapshot_schedule,
def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
duplicate_size=None, duplicate_iops=None,
duplicate_tier_level=None,
duplicate_snapshot_size=None):
duplicate_snapshot_size=None,
hourly_billing_flag=False):
"""Places an order for a duplicate block volume.

:param origin_volume_id: The ID of the origin volume to be duplicated
Expand All @@ -270,10 +272,11 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
:param duplicate_iops: The IOPS per GB for the duplicate volume
:param duplicate_tier_level: Tier level for the duplicate volume
:param duplicate_snapshot_size: Snapshot space size for the duplicate
:param hourly_billing_flag: Billing type, monthly (False)
:return: Returns a SoftLayer_Container_Product_Order_Receipt
"""

block_mask = 'id,billingItem[location],snapshotCapacityGb,'\
block_mask = 'id,billingItem[location,hourlyFlag],snapshotCapacityGb,'\
'storageType[keyName],capacityGb,originalVolumeSize,'\
'provisionedIops,storageTierLevel,osType[keyName],'\
'staasVersion,hasEncryptionAtRest'
Expand All @@ -288,7 +291,7 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,

order = storage_utils.prepare_duplicate_order_object(
self, origin_volume, duplicate_iops, duplicate_tier_level,
duplicate_size, duplicate_snapshot_size, 'block'
duplicate_size, duplicate_snapshot_size, 'block',hourly_billing_flag
)

order['osFormatType'] = {'keyName': os_type}
Expand All @@ -308,7 +311,8 @@ def delete_snapshot(self, snapshot_id):

def order_block_volume(self, storage_type, location, size, os_type,
iops=None, tier_level=None, snapshot_size=None,
service_offering='storage_as_a_service'):
service_offering='storage_as_a_service',
hourly_billing_flag=False):
"""Places an order for a block volume.

:param storage_type: 'performance' or 'endurance'
Expand All @@ -321,10 +325,12 @@ def order_block_volume(self, storage_type, location, size, os_type,
if snapshot space should also be ordered (None if not ordered)
:param service_offering: Requested offering package to use in the order
('storage_as_a_service', 'enterprise', or 'performance')
:param hourly_billing_flag: Billing type, monthly (False)
or hourly (True), default to monthly.
"""
order = storage_utils.prepare_volume_order_object(
self, storage_type, location, size, iops, tier_level,
snapshot_size, service_offering, 'block'
snapshot_size, service_offering, 'block', hourly_billing_flag
)

order['osFormatType'] = {'keyName': os_type}
Expand Down Expand Up @@ -352,8 +358,9 @@ def order_snapshot_space(self, volume_id, capacity, tier,
:param boolean upgrade: Flag to indicate if this order is an upgrade
:return: Returns a SoftLayer_Container_Product_Order_Receipt
"""
block_mask = 'id,billingItem[location],storageType[keyName],'\
'storageTierLevel,provisionedIops,staasVersion,hasEncryptionAtRest'
block_mask = 'id,billingItem[location,hourlyFlag],'\
'storageType[keyName],storageTierLevel,provisionedIops,'\
'staasVersion,hasEncryptionAtRest'
block_volume = self.get_block_volume_details(volume_id,
mask=block_mask,
**kwargs)
Expand All @@ -376,7 +383,7 @@ def cancel_snapshot_space(self, volume_id,

block_volume = self.get_block_volume_details(
volume_id,
mask='mask[id,billingItem[activeChildren]]')
mask='mask[id,billingItem[activeChildren,hourlyFlag]]')

if 'activeChildren' not in block_volume['billingItem']:
raise exceptions.SoftLayerError(
Expand All @@ -394,6 +401,9 @@ def cancel_snapshot_space(self, volume_id,
raise exceptions.SoftLayerError(
'No snapshot space found to cancel')

if utils.lookup(block_volume, 'billingItem', 'hourlyFlag'):
immediate = True

return self.client['Billing_Item'].cancelItem(
immediate,
True,
Expand Down Expand Up @@ -456,9 +466,12 @@ def cancel_block_volume(self, volume_id,
"""
block_volume = self.get_block_volume_details(
volume_id,
mask='mask[id,billingItem[id]]')
mask='mask[id,billingItem[id,hourlyFlag]]')
billing_item_id = block_volume['billingItem']['id']

if utils.lookup(block_volume, 'billingItem', 'hourlyFlag'):
immediate = True

return self.client['Billing_Item'].cancelItem(
immediate,
True,
Expand Down
37 changes: 25 additions & 12 deletions SoftLayer/managers/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,10 @@ def order_replicant_volume(self, volume_id, snapshot_schedule,
:return: Returns a SoftLayer_Container_Product_Order_Receipt
"""

file_mask = 'billingItem[activeChildren],storageTierLevel,'\
'staasVersion,hasEncryptionAtRest,snapshotCapacityGb,'\
'schedules,hourlySchedule,dailySchedule,weeklySchedule,'\
file_mask = 'billingItem[activeChildren,hourlyFlag],'\
'storageTierLevel,staasVersion,'\
'hasEncryptionAtRest,snapshotCapacityGb,schedules,'\
'hourlySchedule,dailySchedule,weeklySchedule,'\
'storageType[keyName],provisionedIops'
file_volume = self.get_file_volume_details(volume_id,
mask=file_mask)
Expand Down Expand Up @@ -249,7 +250,8 @@ def get_replication_locations(self, volume_id):
def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
duplicate_size=None, duplicate_iops=None,
duplicate_tier_level=None,
duplicate_snapshot_size=None):
duplicate_snapshot_size=None,
hourly_billing_flag=False):
"""Places an order for a duplicate file volume.

:param origin_volume_id: The ID of the origin volume to be duplicated
Expand All @@ -258,10 +260,11 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
:param duplicate_iops: The IOPS per GB for the duplicate volume
:param duplicate_tier_level: Tier level for the duplicate volume
:param duplicate_snapshot_size: Snapshot space size for the duplicate
:param hourly_billing_flag: Billing type, monthly (False)
:return: Returns a SoftLayer_Container_Product_Order_Receipt
"""

file_mask = 'id,billingItem[location],snapshotCapacityGb,'\
file_mask = 'id,billingItem[location,hourlyFlag],snapshotCapacityGb,'\
'storageType[keyName],capacityGb,originalVolumeSize,'\
'provisionedIops,storageTierLevel,'\
'staasVersion,hasEncryptionAtRest'
Expand All @@ -270,7 +273,7 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,

order = storage_utils.prepare_duplicate_order_object(
self, origin_volume, duplicate_iops, duplicate_tier_level,
duplicate_size, duplicate_snapshot_size, 'file'
duplicate_size, duplicate_snapshot_size, 'file', hourly_billing_flag
)

if origin_snapshot_id is not None:
Expand All @@ -288,7 +291,8 @@ def delete_snapshot(self, snapshot_id):

def order_file_volume(self, storage_type, location, size,
iops=None, tier_level=None, snapshot_size=None,
service_offering='storage_as_a_service'):
service_offering='storage_as_a_service',
hourly_billing_flag=False):
"""Places an order for a file volume.

:param storage_type: 'performance' or 'endurance'
Expand All @@ -300,10 +304,12 @@ def order_file_volume(self, storage_type, location, size,
if snapshot space should also be ordered (None if not ordered)
:param service_offering: Requested offering package to use in the order
('storage_as_a_service', 'enterprise', or 'performance')
:param hourly_billing_flag: Billing type, monthly (False)
or hourly (True), default to monthly.
"""
order = storage_utils.prepare_volume_order_object(
self, storage_type, location, size, iops, tier_level,
snapshot_size, service_offering, 'file'
snapshot_size, service_offering, 'file', hourly_billing_flag
)

return self.client.call('Product_Order', 'placeOrder', order)
Expand Down Expand Up @@ -367,8 +373,9 @@ def order_snapshot_space(self, volume_id, capacity, tier,
:param boolean upgrade: Flag to indicate if this order is an upgrade
:return: Returns a SoftLayer_Container_Product_Order_Receipt
"""
file_mask = 'id,billingItem[location],storageType[keyName],'\
'storageTierLevel,provisionedIops,staasVersion,hasEncryptionAtRest'
file_mask = 'id,billingItem[location,hourlyFlag],'\
'storageType[keyName],storageTierLevel,provisionedIops,'\
'staasVersion,hasEncryptionAtRest'
file_volume = self.get_file_volume_details(volume_id,
mask=file_mask,
**kwargs)
Expand All @@ -391,7 +398,7 @@ def cancel_snapshot_space(self, volume_id,

file_volume = self.get_file_volume_details(
volume_id,
mask='mask[id,billingItem[activeChildren]]')
mask='mask[id,billingItem[activeChildren,hourlyFlag]]')

if 'activeChildren' not in file_volume['billingItem']:
raise exceptions.SoftLayerError(
Expand All @@ -409,6 +416,9 @@ def cancel_snapshot_space(self, volume_id,
raise exceptions.SoftLayerError(
'No snapshot space found to cancel')

if utils.lookup(file_volume, 'billingItem', 'hourlyFlag'):
immediate = True

return self.client['Billing_Item'].cancelItem(
immediate,
True,
Expand Down Expand Up @@ -438,9 +448,12 @@ def cancel_file_volume(self, volume_id,
"""
file_volume = self.get_file_volume_details(
volume_id,
mask='mask[id,billingItem[id]]')
mask='mask[id,billingItem[id,hourlyFlag]]')
billing_item_id = file_volume['billingItem']['id']

if utils.lookup(file_volume, 'billingItem', 'hourlyFlag'):
immediate = True

return self.client['Billing_Item'].cancelItem(
immediate,
True,
Expand Down
Loading