Skip to content

Commit 8c87513

Browse files
Merge pull request #1228 from kremlin-/vdr-integration
Support Ordering Dependent Duplicate storage volumes
2 parents b853461 + 7a651b0 commit 8c87513

File tree

10 files changed

+134
-9
lines changed

10 files changed

+134
-9
lines changed

CONTRIBUTORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ chechuironman <chechuironman@gmail.com>
66
Christopher Gallo <chrisagallo@gmail.com>
77
David Ibarra <dtibarra@gmail.com>
88
Hans Kristian Moen <hans@ububeet.(none)>
9+
Ian Sutton <ians@openbsd.org>
910
Jake Williams <jwilliams@softlayer.com>
1011
Jason Johnson <spligak@gmail.com>
1112
Kevin Landreth <klandreth@softlayer.com>

SoftLayer/CLI/block/duplicate.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,16 @@
5454
type=click.Choice(['hourly', 'monthly']),
5555
default='monthly',
5656
help="Optional parameter for Billing rate (default to monthly)")
57+
@click.option('--dependent-duplicate',
58+
type=click.BOOL,
59+
default=False,
60+
show_default=True,
61+
help='Whether or not this duplicate will be a dependent duplicate '
62+
'of the origin volume.')
5763
@environment.pass_env
5864
def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
59-
duplicate_iops, duplicate_tier, duplicate_snapshot_size, billing):
65+
duplicate_iops, duplicate_tier, duplicate_snapshot_size, billing,
66+
dependent_duplicate):
6067
"""Order a duplicate block storage volume."""
6168
block_manager = SoftLayer.BlockStorageManager(env.client)
6269

@@ -75,7 +82,8 @@ def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
7582
duplicate_iops=duplicate_iops,
7683
duplicate_tier_level=duplicate_tier,
7784
duplicate_snapshot_size=duplicate_snapshot_size,
78-
hourly_billing_flag=hourly_billing_flag
85+
hourly_billing_flag=hourly_billing_flag,
86+
dependent_duplicate=dependent_duplicate
7987
)
8088
except ValueError as ex:
8189
raise exceptions.ArgumentError(str(ex))

SoftLayer/CLI/file/duplicate.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,16 @@
5252
type=click.Choice(['hourly', 'monthly']),
5353
default='monthly',
5454
help="Optional parameter for Billing rate (default to monthly)")
55+
@click.option('--dependent-duplicate',
56+
type=click.BOOL,
57+
default=False,
58+
show_default=True,
59+
help='Whether or not this duplicate will be a dependent duplicate'
60+
'of the origin volume.')
5561
@environment.pass_env
5662
def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
57-
duplicate_iops, duplicate_tier, duplicate_snapshot_size, billing):
63+
duplicate_iops, duplicate_tier, duplicate_snapshot_size, billing,
64+
dependent_duplicate):
5865
"""Order a duplicate file storage volume."""
5966
file_manager = SoftLayer.FileStorageManager(env.client)
6067

@@ -73,7 +80,8 @@ def cli(env, origin_volume_id, origin_snapshot_id, duplicate_size,
7380
duplicate_iops=duplicate_iops,
7481
duplicate_tier_level=duplicate_tier,
7582
duplicate_snapshot_size=duplicate_snapshot_size,
76-
hourly_billing_flag=hourly_billing_flag
83+
hourly_billing_flag=hourly_billing_flag,
84+
dependent_duplicate=dependent_duplicate
7785
)
7886
except ValueError as ex:
7987
raise exceptions.ArgumentError(str(ex))

SoftLayer/managers/block.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
310310
duplicate_size=None, duplicate_iops=None,
311311
duplicate_tier_level=None,
312312
duplicate_snapshot_size=None,
313-
hourly_billing_flag=False):
313+
hourly_billing_flag=False,
314+
dependent_duplicate=False):
314315
"""Places an order for a duplicate block volume.
315316
316317
:param origin_volume_id: The ID of the origin volume to be duplicated
@@ -321,6 +322,7 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
321322
:param duplicate_snapshot_size: Snapshot space size for the duplicate
322323
:param hourly_billing_flag: Billing type, monthly (False)
323324
or hourly (True), default to monthly.
325+
:param dependent_duplicate: Duplicate type, normal (False) or dependent duplicate (True)
324326
:return: Returns a SoftLayer_Container_Product_Order_Receipt
325327
"""
326328

@@ -348,6 +350,9 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
348350
if origin_snapshot_id is not None:
349351
order['duplicateOriginSnapshotId'] = origin_snapshot_id
350352

353+
if dependent_duplicate:
354+
order['isDependentDuplicateFlag'] = 1
355+
351356
return self.client.call('Product_Order', 'placeOrder', order)
352357

353358
def order_modified_volume(self, volume_id, new_size=None, new_iops=None, new_tier_level=None):

SoftLayer/managers/file.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
259259
duplicate_size=None, duplicate_iops=None,
260260
duplicate_tier_level=None,
261261
duplicate_snapshot_size=None,
262-
hourly_billing_flag=False):
262+
hourly_billing_flag=False,
263+
dependent_duplicate=False):
263264
"""Places an order for a duplicate file volume.
264265
265266
:param origin_volume_id: The ID of the origin volume to be duplicated
@@ -270,6 +271,7 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
270271
:param duplicate_snapshot_size: Snapshot space size for the duplicate
271272
:param hourly_billing_flag: Billing type, monthly (False)
272273
or hourly (True), default to monthly.
274+
:param dependent_duplicate: Duplicate type, normal (False) or dependent duplicate (True)
273275
:return: Returns a SoftLayer_Container_Product_Order_Receipt
274276
"""
275277

@@ -289,6 +291,9 @@ def order_duplicate_volume(self, origin_volume_id, origin_snapshot_id=None,
289291
if origin_snapshot_id is not None:
290292
order['duplicateOriginSnapshotId'] = origin_snapshot_id
291293

294+
if dependent_duplicate:
295+
order['isDependentDuplicateFlag'] = 1
296+
292297
return self.client.call('Product_Order', 'placeOrder', order)
293298

294299
def order_modified_volume(self, volume_id, new_size=None, new_iops=None, new_tier_level=None):

SoftLayer/managers/storage_utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,8 @@ def prepare_replicant_order_object(manager, snapshot_schedule, location,
788788

789789
def prepare_duplicate_order_object(manager, origin_volume, iops, tier,
790790
duplicate_size, duplicate_snapshot_size,
791-
volume_type, hourly_billing_flag=False):
791+
volume_type, hourly_billing_flag=False,
792+
dependent_duplicate=False):
792793
"""Prepare the duplicate order to submit to SoftLayer_Product::placeOrder()
793794
794795
:param manager: The File or Block manager calling this function
@@ -799,6 +800,8 @@ def prepare_duplicate_order_object(manager, origin_volume, iops, tier,
799800
:param duplicate_snapshot_size: The size for the duplicate snapshot space
800801
:param volume_type: The type of the origin volume ('file' or 'block')
801802
:param hourly_billing_flag: Billing type, monthly (False) or hourly (True)
803+
:param dependent_duplicate: Duplicate type, normal (False) or dependent
804+
duplicate (True)
802805
:return: Returns the order object to be passed to the
803806
placeOrder() method of the Product_Order service
804807
"""
@@ -903,6 +906,9 @@ def prepare_duplicate_order_object(manager, origin_volume, iops, tier,
903906
if volume_is_performance:
904907
duplicate_order['iops'] = iops
905908

909+
if dependent_duplicate:
910+
duplicate_order['isDependentDuplicateFlag'] = 1
911+
906912
return duplicate_order
907913

908914

tests/CLI/modules/block_tests.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,8 @@ def test_duplicate_order_hourly_billing(self, order_mock):
642642
duplicate_size=250, duplicate_iops=None,
643643
duplicate_tier_level=2,
644644
duplicate_snapshot_size=20,
645-
hourly_billing_flag=True)
645+
hourly_billing_flag=True,
646+
dependent_duplicate=False)
646647
self.assert_no_fail(result)
647648
self.assertEqual(result.output,
648649
'Order #24602 placed successfully!\n'

tests/CLI/modules/file_tests.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,8 @@ def test_duplicate_order_hourly_billing(self, order_mock):
629629
duplicate_size=250, duplicate_iops=None,
630630
duplicate_tier_level=2,
631631
duplicate_snapshot_size=20,
632-
hourly_billing_flag=True)
632+
hourly_billing_flag=True,
633+
dependent_duplicate=False)
633634
self.assert_no_fail(result)
634635
self.assertEqual(result.output,
635636
'Order #24602 placed successfully!\n'

tests/managers/block_tests.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,52 @@ def test_order_block_duplicate_performance(self):
846846
'useHourlyPricing': False
847847
},))
848848

849+
def test_order_block_duplicate_depdupe(self):
850+
mock = self.set_mock('SoftLayer_Product_Package', 'getAllObjects')
851+
mock.return_value = [fixtures.SoftLayer_Product_Package.SAAS_PACKAGE]
852+
853+
mock_volume = copy.deepcopy(fixtures.SoftLayer_Network_Storage.STAAS_TEST_VOLUME)
854+
mock_volume['storageType']['keyName'] = 'PERFORMANCE_BLOCK_STORAGE'
855+
mock = self.set_mock('SoftLayer_Network_Storage', 'getObject')
856+
mock.return_value = mock_volume
857+
858+
result = self.block.order_duplicate_volume(
859+
102,
860+
origin_snapshot_id=470,
861+
duplicate_size=1000,
862+
duplicate_iops=2000,
863+
duplicate_tier_level=None,
864+
duplicate_snapshot_size=10,
865+
dependent_duplicate=True
866+
)
867+
868+
self.assertEqual(fixtures.SoftLayer_Product_Order.placeOrder, result)
869+
870+
self.assert_called_with(
871+
'SoftLayer_Product_Order',
872+
'placeOrder',
873+
args=({
874+
'complexType': 'SoftLayer_Container_Product_Order_'
875+
'Network_Storage_AsAService',
876+
'packageId': 759,
877+
'prices': [
878+
{'id': 189433},
879+
{'id': 189443},
880+
{'id': 190113},
881+
{'id': 190173},
882+
{'id': 191193}
883+
],
884+
'volumeSize': 1000,
885+
'quantity': 1,
886+
'location': 449500,
887+
'duplicateOriginVolumeId': 102,
888+
'osFormatType': {'keyName': 'LINUX'},
889+
'duplicateOriginSnapshotId': 470,
890+
'iops': 2000,
891+
'useHourlyPricing': False,
892+
'isDependentDuplicateFlag': 1
893+
},))
894+
849895
def test_order_block_duplicate_endurance_no_duplicate_snapshot(self):
850896
mock = self.set_mock('SoftLayer_Product_Package', 'getAllObjects')
851897
mock.return_value = [fixtures.SoftLayer_Product_Package.SAAS_PACKAGE]

tests/managers/file_tests.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,50 @@ def test_order_file_duplicate_endurance_no_duplicate_snapshot(self):
742742
'useHourlyPricing': False
743743
},))
744744

745+
def test_order_file_duplicate_depdupe(self):
746+
mock = self.set_mock('SoftLayer_Product_Package', 'getAllObjects')
747+
mock.return_value = [fixtures.SoftLayer_Product_Package.SAAS_PACKAGE]
748+
749+
mock_volume = copy.deepcopy(fixtures.SoftLayer_Network_Storage.STAAS_TEST_VOLUME)
750+
mock_volume['storageType']['keyName'] = 'ENDURANCE_FILE_STORAGE'
751+
mock = self.set_mock('SoftLayer_Network_Storage', 'getObject')
752+
mock.return_value = mock_volume
753+
754+
result = self.file.order_duplicate_volume(
755+
102,
756+
origin_snapshot_id=470,
757+
duplicate_size=1000,
758+
duplicate_iops=None,
759+
duplicate_tier_level=4,
760+
duplicate_snapshot_size=10,
761+
dependent_duplicate=True
762+
)
763+
764+
self.assertEqual(fixtures.SoftLayer_Product_Order.placeOrder, result)
765+
766+
self.assert_called_with(
767+
'SoftLayer_Product_Order',
768+
'placeOrder',
769+
args=({
770+
'complexType': 'SoftLayer_Container_Product_Order_'
771+
'Network_Storage_AsAService',
772+
'packageId': 759,
773+
'prices': [
774+
{'id': 189433},
775+
{'id': 189453},
776+
{'id': 194763},
777+
{'id': 194703},
778+
{'id': 194943}
779+
],
780+
'volumeSize': 1000,
781+
'quantity': 1,
782+
'location': 449500,
783+
'duplicateOriginVolumeId': 102,
784+
'duplicateOriginSnapshotId': 470,
785+
'useHourlyPricing': False,
786+
'isDependentDuplicateFlag': 1
787+
},))
788+
745789
def test_order_file_duplicate_endurance(self):
746790
mock = self.set_mock('SoftLayer_Product_Package', 'getAllObjects')
747791
mock.return_value = [fixtures.SoftLayer_Product_Package.SAAS_PACKAGE]

0 commit comments

Comments
 (0)