Skip to content

Commit c1a3696

Browse files
Merge pull request #1308 from caberos/issue1295
vs upgrade disk and add new disk
2 parents c623829 + 68f46e2 commit c1a3696

File tree

4 files changed

+136
-15
lines changed

4 files changed

+136
-15
lines changed

SoftLayer/CLI/virt/upgrade.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,20 @@
2020
help="CPU core will be on a dedicated host server.")
2121
@click.option('--memory', type=virt.MEM_TYPE, help="Memory in megabytes")
2222
@click.option('--network', type=click.INT, help="Network port speed in Mbps")
23+
@click.option('--add-disk', type=click.INT, multiple=True, required=False, help="add Hard disk in GB")
24+
@click.option('--resize-disk', nargs=2, multiple=True, type=(int, int),
25+
help="Update disk number to size in GB. --resize-disk 250 2 ")
2326
@click.option('--flavor', type=click.STRING,
2427
help="Flavor keyName\nDo not use --memory, --cpu or --private, if you are using flavors")
2528
@environment.pass_env
26-
def cli(env, identifier, cpu, private, memory, network, flavor):
29+
def cli(env, identifier, cpu, private, memory, network, flavor, add_disk, resize_disk):
2730
"""Upgrade a virtual server."""
2831

2932
vsi = SoftLayer.VSManager(env.client)
3033

31-
if not any([cpu, memory, network, flavor]):
32-
raise exceptions.ArgumentError("Must provide [--cpu], [--memory], [--network], or [--flavor] to upgrade")
34+
if not any([cpu, memory, network, flavor, resize_disk, add_disk]):
35+
raise exceptions.ArgumentError("Must provide [--cpu],"
36+
" [--memory], [--network], [--flavor], [--resize-disk], or [--add] to upgrade")
3337

3438
if private and not cpu:
3539
raise exceptions.ArgumentError("Must specify [--cpu] when using [--private]")
@@ -38,8 +42,19 @@ def cli(env, identifier, cpu, private, memory, network, flavor):
3842
if not (env.skip_confirmations or formatting.confirm("This action will incur charges on your account. Continue?")):
3943
raise exceptions.CLIAbort('Aborted')
4044

45+
disk_json = list()
4146
if memory:
4247
memory = int(memory / 1024)
43-
44-
if not vsi.upgrade(vs_id, cpus=cpu, memory=memory, nic_speed=network, public=not private, preset=flavor):
48+
if resize_disk:
49+
for guest_disk in resize_disk:
50+
disks = {'capacity': guest_disk[0], 'number': guest_disk[1]}
51+
disk_json.append(disks)
52+
53+
elif add_disk:
54+
for guest_disk in add_disk:
55+
disks = {'capacity': guest_disk, 'number': -1}
56+
disk_json.append(disks)
57+
58+
if not vsi.upgrade(vs_id, cpus=cpu, memory=memory, nic_speed=network, public=not private, preset=flavor,
59+
disk=disk_json):
4560
raise exceptions.CLIAbort('VS Upgrade Failed')

SoftLayer/fixtures/SoftLayer_Virtual_Guest.py

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88
'id': 6327,
99
'nextInvoiceTotalRecurringAmount': 1.54,
1010
'children': [
11-
{'nextInvoiceTotalRecurringAmount': 1},
12-
{'nextInvoiceTotalRecurringAmount': 1},
13-
{'nextInvoiceTotalRecurringAmount': 1},
14-
{'nextInvoiceTotalRecurringAmount': 1},
15-
{'nextInvoiceTotalRecurringAmount': 1},
11+
{'categoryCode': 'port_speed',
12+
'nextInvoiceTotalRecurringAmount': 1},
13+
{'categoryCode': 'guest_core',
14+
'nextInvoiceTotalRecurringAmount': 1},
15+
{'categoryCode': 'ram',
16+
'nextInvoiceTotalRecurringAmount': 1},
17+
{'categoryCode': 'guest_core',
18+
'nextInvoiceTotalRecurringAmount': 1},
19+
{'categoryCode': 'guest_disk1',
20+
'nextInvoiceTotalRecurringAmount': 1},
1621
],
1722
'package': {
1823
"id": 835,
@@ -622,7 +627,35 @@
622627
'capacity': '2',
623628
'description': 'RAM',
624629
}
625-
},
630+
}, {
631+
"id": 2255,
632+
"categories": [
633+
{
634+
"categoryCode": "guest_disk1",
635+
"id": 82,
636+
"name": "Second Disk"
637+
},
638+
{
639+
"categoryCode": "guest_disk2",
640+
"id": 92,
641+
"name": "Third Disk"
642+
},
643+
{
644+
"categoryCode": "guest_disk3",
645+
"id": 93,
646+
"name": "Fourth Disk"
647+
},
648+
{
649+
"categoryCode": "guest_disk4",
650+
"id": 116,
651+
"name": "Fifth Disk"
652+
}
653+
],
654+
"item": {
655+
"capacity": "10",
656+
"description": "10 GB (SAN)"
657+
}
658+
}
626659
]
627660

628661
DEDICATED_GET_UPGRADE_ITEM_PRICES = [
@@ -641,7 +674,6 @@
641674

642675
getMetricTrackingObjectId = 1000
643676

644-
645677
getBandwidthAllotmentDetail = {
646678
'allocationId': 25465663,
647679
'bandwidthAllotmentId': 138442,

SoftLayer/managers/vs.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
LOGGER = logging.getLogger(__name__)
2020

21+
2122
# pylint: disable=no-self-use,too-many-lines
2223

2324

@@ -818,7 +819,7 @@ def capture(self, instance_id, name, additional_disks=False, notes=None):
818819
return self.guest.createArchiveTransaction(
819820
name, disks_to_capture, notes, id=instance_id)
820821

821-
def upgrade(self, instance_id, cpus=None, memory=None, nic_speed=None, public=True, preset=None):
822+
def upgrade(self, instance_id, cpus=None, memory=None, nic_speed=None, public=True, preset=None, disk=None):
822823
"""Upgrades a VS instance.
823824
824825
Example::
@@ -862,6 +863,40 @@ def upgrade(self, instance_id, cpus=None, memory=None, nic_speed=None, public=Tr
862863
'virtualGuests': [{'id': int(instance_id)}],
863864
}
864865

866+
if disk:
867+
disk_number = 0
868+
vsi_disk = self.get_instance(instance_id)
869+
for item in vsi_disk.get('billingItem').get('children'):
870+
if item.get('categoryCode').__contains__('guest_disk'):
871+
if disk_number < int("".join(filter(str.isdigit, item.get('categoryCode')))):
872+
disk_number = int("".join(filter(str.isdigit, item.get('categoryCode'))))
873+
for disk_guest in disk:
874+
if disk_guest.get('number') > 0:
875+
price_id = self._get_price_id_for_upgrade_option(upgrade_prices, 'disk',
876+
disk_guest.get('capacity'),
877+
public)
878+
disk_number = disk_guest.get('number')
879+
880+
else:
881+
price_id = self._get_price_id_for_upgrade_option(upgrade_prices, 'disk',
882+
disk_guest.get('capacity'),
883+
public)
884+
disk_number = disk_number + 1
885+
886+
if price_id is None:
887+
raise exceptions.SoftLayerAPIError(500,
888+
'Unable to find %s option with value %s' % (
889+
('disk', disk_guest.get('capacity'))))
890+
891+
category = {'categories': [{
892+
'categoryCode': 'guest_disk' + str(disk_number),
893+
'complexType': "SoftLayer_Product_Item_Category"}],
894+
'complexType': 'SoftLayer_Product_Item_Price',
895+
'id': price_id}
896+
897+
prices.append(category)
898+
order['prices'] = prices
899+
865900
for option, value in data.items():
866901
if not value:
867902
continue
@@ -875,8 +910,8 @@ def upgrade(self, instance_id, cpus=None, memory=None, nic_speed=None, public=Tr
875910
"Unable to find %s option with value %s" % (option, value))
876911

877912
prices.append({'id': price_id})
878-
order['prices'] = prices
879913

914+
order['prices'] = prices
880915
if preset is not None:
881916
vs_object = self.get_instance(instance_id)['billingItem']['package']
882917
order['presetId'] = self.ordering_manager.get_preset_by_key(vs_object['keyName'], preset)['id']
@@ -994,9 +1029,11 @@ def _get_price_id_for_upgrade_option(self, upgrade_prices, option, value, public
9941029
option_category = {
9951030
'memory': 'ram',
9961031
'cpus': 'guest_core',
997-
'nic_speed': 'port_speed'
1032+
'nic_speed': 'port_speed',
1033+
'disk': 'guest_disk'
9981034
}
9991035
category_code = option_category.get(option)
1036+
10001037
for price in upgrade_prices:
10011038
if price.get('categories') is None or price.get('item') is None:
10021039
continue
@@ -1006,6 +1043,11 @@ def _get_price_id_for_upgrade_option(self, upgrade_prices, option, value, public
10061043
or product.get('units') == 'DEDICATED_CORE')
10071044

10081045
for category in price.get('categories'):
1046+
if option == 'disk':
1047+
if (category_code == (''.join([i for i in category.get('categoryCode') if not i.isdigit()]))
1048+
and str(product.get('capacity')) == str(value)):
1049+
return price.get('id')
1050+
10091051
if not (category.get('categoryCode') == category_code
10101052
and str(product.get('capacity')) == str(value)):
10111053
continue

tests/CLI/modules/vs/vs_tests.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,27 @@ def test_upgrade(self, confirm_mock):
542542
self.assertIn({'id': 1122}, order_container['prices'])
543543
self.assertEqual(order_container['virtualGuests'], [{'id': 100}])
544544

545+
@mock.patch('SoftLayer.CLI.formatting.confirm')
546+
def test_upgrade_disk(self, confirm_mock):
547+
confirm_mock.return_value = True
548+
result = self.run_command(['vs', 'upgrade', '100', '--flavor=M1_64X512X100',
549+
'--resize-disk=10', '1', '--resize-disk=10', '2'])
550+
self.assert_no_fail(result)
551+
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
552+
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
553+
order_container = call.args[0]
554+
self.assertEqual(799, order_container['presetId'])
555+
self.assertIn({'id': 100}, order_container['virtualGuests'])
556+
self.assertEqual(order_container['virtualGuests'], [{'id': 100}])
557+
558+
@mock.patch('SoftLayer.CLI.formatting.confirm')
559+
def test_upgrade_disk_error(self, confirm_mock):
560+
confirm_mock.return_value = True
561+
result = self.run_command(['vs', 'upgrade', '100', '--flavor=M1_64X512X100',
562+
'--resize-disk=1000', '1', '--resize-disk=10', '2'])
563+
self.assertEqual(result.exit_code, 1)
564+
self.assertIsInstance(result.exception, SoftLayerAPIError)
565+
545566
@mock.patch('SoftLayer.CLI.formatting.confirm')
546567
def test_upgrade_with_flavor(self, confirm_mock):
547568
confirm_mock.return_value = True
@@ -554,6 +575,17 @@ def test_upgrade_with_flavor(self, confirm_mock):
554575
self.assertIn({'id': 100}, order_container['virtualGuests'])
555576
self.assertEqual(order_container['virtualGuests'], [{'id': 100}])
556577

578+
@mock.patch('SoftLayer.CLI.formatting.confirm')
579+
def test_upgrade_with_add_disk(self, confirm_mock):
580+
confirm_mock.return_value = True
581+
result = self.run_command(['vs', 'upgrade', '100', '--add-disk=10', '--add-disk=10'])
582+
self.assert_no_fail(result)
583+
self.assert_called_with('SoftLayer_Product_Order', 'placeOrder')
584+
call = self.calls('SoftLayer_Product_Order', 'placeOrder')[0]
585+
order_container = call.args[0]
586+
self.assertIn({'id': 100}, order_container['virtualGuests'])
587+
self.assertEqual(order_container['virtualGuests'], [{'id': 100}])
588+
557589
@mock.patch('SoftLayer.CLI.formatting.confirm')
558590
def test_upgrade_with_cpu_memory_and_flavor(self, confirm_mock):
559591
confirm_mock.return_value = True

0 commit comments

Comments
 (0)